Some test text!

Search
Hamburger Icon

Add or edit PDF annotations in Ruby

More languages

More languages
JavaScript
Java (Android)
C++
C#
C# (.NET Core)
Go
Java
Kotlin
Obj-C
JS (Node.js)
PHP
Python
Ruby
Swift
C# (UWP)
VB
C# (Xamarin)

Sample Ruby code to use PDFTron SDK for adding or editing PDF annotations. The annotation types included in this sample are: hyperlink, intra-document link, stamp, rubber stamp, file attachment, sound, text, free-text, line, circle, square, polygon, polyline, highlight, squiggly, caret, and ink. Learn more about our Ruby PDF Library and PDF Annotation Library.

Get Started Samples Download

To run this sample, get started with a free trial of Apryse SDK.

#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
# Consult LICENSE.txt regarding license information.
#---------------------------------------------------------------------------------------

require '../../../PDFNetC/Lib/PDFNetRuby'
include PDFNetRuby
require '../../LicenseKey/RUBY/LicenseKey'

$stdout.sync = true

$output_path = "../../TestFiles/Output/"
$input_path = "../../TestFiles/"

def FloatToStr(float)
	if float.to_i() == float.to_f()
		return float.to_i().to_s()
	else
		return float.to_f().to_s()
	end
end

def AnnotationHighLevelAPI(doc)
	# The following code snippet traverses all annotations in the document
	puts "Traversing all annotations in the document..."
	page_num = 1
	itr = doc.GetPageIterator()
	
	while itr.HasNext() do
		puts "Page " + page_num.to_s() + ": "
		page_num = page_num + 1
		page = itr.Current()
		num_annots = page.GetNumAnnots()
		i = 0
		while i < num_annots do
			annot = page.GetAnnot(i)
			if !(annot.IsValid())
				i = i + 1
				next
			end
			puts "Annot Type: " + annot.GetSDFObj().Get("Subtype").Value().GetName()
			
			bbox = annot.GetRect()
			puts "  Position: " + FloatToStr(bbox.x1.to_s()) + 
				  ", " + FloatToStr(bbox.y1.to_s()) +
				  ", " + FloatToStr(bbox.x2.to_s()) + 
				  ", " + FloatToStr(bbox.y2.to_s())
			
			type = annot.GetType()			
			case type
			when Annot::E_Link
				link = Link.new(annot)
				action = link.GetAction()
				if !(action.IsValid())
					i = i + 1
					next
				end
				if action.GetType() == Action::E_GoTo
					dest = action.GetDest()
					if !(dest.IsValid())
						puts "  Destination is not valid."
					else
						page_n = dest.GetPage().GetIndex()
						puts "  Links to: page number " + page_n.to_s() + " in this document"
					end
				elsif action.GetType() == Action::E_URI
					uri = action.GetSDFObj().Get("URI").Value().GetAsPDFText()
					puts "  Links to: " + uri.to_s()
				end
			when Annot::E_Widget
			when Annot::E_FileAttachment
			end
			i = i + 1
		end
		itr.Next()
	end

	# Use the high-level API to create new annotations.		
	first_page = doc.GetPage(1)
	
	# Create a hyperlink...
	hyperlink = Link.Create(doc.GetSDFDoc(), Rect.new(85, 570, 503, 524), Action.CreateURI(doc.GetSDFDoc(), "http://www.pdftron.com"))
	first_page.AnnotPushBack(hyperlink)
	
	# Create an intra-document link...
	goto_page_3 = Action.CreateGoto(Destination.CreateFitH(doc.GetPage(3), 0))
	link = Link.Create(doc.GetSDFDoc(), Rect.new(85, 458, 503, 502), goto_page_3)
	link.SetColor(ColorPt.new(0, 0, 1))
	
	# Add the new annotation to the first page
	first_page.AnnotPushBack(link) 
	
	# Create a stamp annotation ...
	stamp = RubberStamp.Create(doc.GetSDFDoc(), Rect.new(30, 30, 300, 200))
	stamp.SetIcon("Draft")
	first_page.AnnotPushBack(stamp)

	# Create a file attachment annotation (embed the 'peppers.jpg').
	file_attach = FileAttachment.Create(doc.GetSDFDoc(), Rect.new(80, 280, 108, 320), $input_path + "peppers.jpg")
	first_page.AnnotPushBack(file_attach)

	ink = Ink.Create(doc.GetSDFDoc(), Rect.new(110, 10, 300, 200))
	pt3 = Point.new(110, 10)
	pt3.x = 110 
	pt3.y = 10
	ink.SetPoint(0, 0, pt3)
	pt3.x = 150 
	pt3.y = 50
	ink.SetPoint(0, 1, pt3)
	pt3.x = 190 
	pt3.y = 60
	ink.SetPoint(0, 2, pt3)
	pt3.x = 180 
	pt3.y = 90
	ink.SetPoint(1, 0, pt3)
	pt3.x = 190 
	pt3.y = 95
	ink.SetPoint(1, 1, pt3)
	pt3.x = 200 
	pt3.y = 100
	ink.SetPoint(1, 2, pt3)
	pt3.x = 166 
	pt3.y = 86
	ink.SetPoint(2, 0, pt3)
	pt3.x = 196 
	pt3.y = 96
	ink.SetPoint(2, 1, pt3)
	pt3.x = 221 
	pt3.y = 121
	ink.SetPoint(2, 2, pt3)
	pt3.x = 288 
	pt3.y = 188
	ink.SetPoint(2, 3, pt3)
	ink.SetColor(ColorPt.new(0, 1, 1), 3)
	first_page.AnnotPushBack(ink)
end

def AnnotationLowLevelAPI(doc)
	itr = doc.GetPageIterator()
	page = itr.Current()
	annots = page.GetAnnots()
	
	if annots.nil?
		# If there are no annotations, create a new annotation 
		# array for the page.
		annots = doc.CreateIndirectArray()
		page.GetSDFObj().Put("Annots", annots)
	end

	# Create a Text annotation
	annot = doc.CreateIndirectDict()
	annot.PutName("Subtype", "Text")
	annot.PutBool("Open", true)
	annot.PutString("Contents", "The quick brown fox ate the lazy mouse.")
	annot.PutRect("Rect", 266, 116, 430, 204)

	# Insert the annotation in the page annotation array
	annots.PushBack(annot)   
	
	# Create a Link annotation
	link1 = doc.CreateIndirectDict()
	link1.PutName("Subtype", "Link")
	dest = Destination.CreateFit(doc.GetPage(2))
	link1.Put("Dest", dest.GetSDFObj())
	link1.PutRect("Rect", 85, 705, 503, 661)
	annots.PushBack(link1)

	# Create another Link annotation
	link2 = doc.CreateIndirectDict()
	link2.PutName("Subtype", "Link")
	dest2 = Destination.CreateFit((doc.GetPage(3)))
	link2.Put("Dest", dest2.GetSDFObj())
	link2.PutRect("Rect", 85, 638, 503, 594)
	annots.PushBack(link2)
	
	# Note that PDFNet API can be used to modify existing annotations. 
	# In the following example we will modify the second link annotation 
	# (link2) so that it points to the 10th page. We also use a different 
	# destination page fit type.
	
	# link2 = annots.GetAt(annots.Size()-1)
	link2.Put("Dest", Destination.CreateXYZ(doc.GetPage(10), 100, 792-70, 10).GetSDFObj())
	
	# Create a third link annotation with a hyperlink action (all other 
	# annotation types can be created in a similar way)
	link3 = doc.CreateIndirectDict()
	link3.PutName("Subtype", "Link")
	link3.PutRect("Rect", 85, 570, 503, 524)
	
	# Create a URI action 
	action = link3.PutDict("A")
	action.PutName("S", "URI")
	action.PutString("URI", "http://www.pdftron.com")
	
	annots.PushBack(link3)
end
	
def CreateTestAnnots(doc)
	ew = ElementWriter.new()
	eb = ElementBuilder.new()
	
	first_page = doc.PageCreate(Rect.new(0, 0, 600, 600))
	doc.PagePushBack(first_page)
	ew.Begin(first_page, ElementWriter::E_overlay, false )   # begin writing to this page
	ew.End()	# save changes to the current page
	
	# Test of a free text annotation.
	txtannot = FreeText.Create( doc.GetSDFDoc(), Rect.new(10, 400, 160, 570)  )
	txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out " +
						  "of the air by freezing it with an angry glare." +
						  "\n\nAha!\n\nAnd there was much rejoicing!"	)
	txtannot.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 1, 10, 20 ), false )
	txtannot.SetQuaddingFormat(0)
	first_page.AnnotPushBack(txtannot)
	txtannot.RefreshAppearance()
	
	txtannot = FreeText.Create( doc.GetSDFDoc(), Rect.new(100, 100, 350, 500)  )
	txtannot.SetContentRect( Rect.new( 200, 200, 350, 500 ) )
	txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air " +
				"by freezing it with an angry glare." +
				"\n\nAha!\n\nAnd there was much rejoicing!")
	txtannot.SetCalloutLinePoints( Point.new(200,300), Point.new(150,290), Point.new(110,110) )
	txtannot.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 1, 10, 20 ), false )
	txtannot.SetEndingStyle( LineAnnot::E_ClosedArrow )
	txtannot.SetColor( ColorPt.new( 0, 1, 0 ) )
	txtannot.SetQuaddingFormat(1)
	first_page.AnnotPushBack(txtannot)
	txtannot.RefreshAppearance()
	
	txtannot = FreeText.Create(doc.GetSDFDoc(), Rect.new(400, 10, 550, 400))	
	txtannot.SetContents( "\n\nSome swift brown fox snatched a gray hare out of the air " +
				"by freezing it with an angry glare." +
				"\n\nAha!\n\nAnd there was much rejoicing!")
	txtannot.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 1, 10, 20 ), false )
	txtannot.SetColor( ColorPt.new( 0, 0, 1 ) )
	txtannot.SetOpacity( 0.2 )
	txtannot.SetQuaddingFormat(2)
	first_page.AnnotPushBack(txtannot)
	txtannot.RefreshAppearance()
	
	page= doc.PageCreate(Rect.new(0, 0, 600, 600))
	doc.PagePushBack(page)
	ew.Begin(page, ElementWriter::E_overlay, false )	# begin writing to this page
	eb.Reset()	# Reset the GState to default
	ew.End()	# save changes to the current page
	
	# Create a Line annotation...
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(250, 250, 400, 400))
	line.SetStartPoint( Point.new(350, 270 ) )
	line.SetEndPoint( Point.new(260,370) )
	line.SetStartStyle(LineAnnot::E_Square)
	line.SetEndStyle(LineAnnot::E_Circle)
	line.SetColor(ColorPt.new(0.3, 0.5, 0), 3)
	line.SetContents( "Dashed Captioned" )
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.SetBorderStyle( BorderStyle.new( BorderStyle::E_dashed, 2, 0, 0, [2.0, 2.0] ) )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(347, 377, 600, 600))
	line.SetStartPoint( Point.new(385, 410 ) )
	line.SetEndPoint( Point.new(540,555) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_OpenArrow)
	line.SetColor(ColorPt.new(1, 0, 0), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetContents( "Inline Caption" )
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Inline )
	line.SetLeaderLineExtensionLength( 4 )
	line.SetLeaderLineLength( -12 )
	line.SetLeaderLineOffset( 2 )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(10, 400, 200, 600))
	line.SetStartPoint( Point.new(25, 426 ) )
	line.SetEndPoint( Point.new(180,555) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_Square)
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(1, 0, 0), 3)
	line.SetContents("Offset Caption")
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.SetTextHOffset( -60 )
	line.SetTextVOffset( 10 )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(200, 10, 400, 70))
	line.SetStartPoint( Point.new(220, 25 ) )
	line.SetEndPoint( Point.new(370,60) )
	line.SetStartStyle(LineAnnot::E_Butt)
	line.SetEndStyle(LineAnnot::E_OpenArrow)
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetContents( "Regular Caption" )
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(200, 70, 400, 130))
	line.SetStartPoint( Point.new(220, 111 ) )
	line.SetEndPoint( Point.new(370,78) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_Diamond)
	line.SetContents( "Circle to Diamond" )
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new(10, 100, 160, 200))
	line.SetStartPoint( Point.new(15, 110 ) )
	line.SetEndPoint( Point.new(150, 190) )
	line.SetStartStyle(LineAnnot::E_Slash)
	line.SetEndStyle(LineAnnot::E_ClosedArrow)
	line.SetContents( "Slash to CArrow" )
	line.SetColor(ColorPt.new(1, 0, 0), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 1), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 270, 270, 570, 433 ))
	line.SetStartPoint( Point.new(300, 400 ) )
	line.SetEndPoint( Point.new(550, 300) )
	line.SetStartStyle(LineAnnot::E_RClosedArrow)
	line.SetEndStyle(LineAnnot::E_ROpenArrow)
	line.SetContents( "ROpen & RClosed arrows" )
	line.SetColor(ColorPt.new(0, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)

	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 195, 395, 205, 505 ))
	line.SetStartPoint( Point.new(200, 400 ) )
	line.SetEndPoint( Point.new(200, 500) )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 55, 299, 150, 301 ))
	line.SetStartPoint( Point.new(55, 300 ) )
	line.SetEndPoint( Point.new(155, 300) )
	line.SetStartStyle(LineAnnot::E_Circle)
	line.SetEndStyle(LineAnnot::E_Circle)
	line.SetContents( "Caption that's longer than its line." )
	line.SetColor(ColorPt.new(1, 0, 1), 3)
	line.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	line.SetShowCaption(true)
	line.SetCaptionPosition( LineAnnot::E_Top )
	line.RefreshAppearance()
	page.AnnotPushBack(line)
	
	line=LineAnnot.Create(doc.GetSDFDoc(), Rect.new( 300, 200, 390, 234 ))
	line.SetStartPoint( Point.new(310, 210 ) )
	line.SetEndPoint( Point.new(380, 220) )
	line.SetColor(ColorPt.new(0, 0, 0), 3)
	line.RefreshAppearance()
	page.AnnotPushBack(line)

	page3 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page3)	# begin writing to the page
	ew.End()	# save changes to the current page
	doc.PagePushBack(page3)

	circle=Circle.Create(doc.GetSDFDoc(), Rect.new( 300, 300, 390, 350 ))
	circle.SetColor(ColorPt.new(0, 0, 0), 3)
	circle.RefreshAppearance()
	page3.AnnotPushBack(circle)
	
	circle=Circle.Create(doc.GetSDFDoc(), Rect.new( 100, 100, 200, 200 ))
	circle.SetColor(ColorPt.new(0, 1, 0), 3)
	circle.SetInteriorColor(ColorPt.new(0, 0, 1), 3)
	circle.SetBorderStyle( BorderStyle.new( BorderStyle::E_dashed, 3, 0, 0, [2, 4] ) )
	circle.SetPadding( 2 )
	circle.RefreshAppearance()
	page3.AnnotPushBack(circle)

	sq = Square.Create( doc.GetSDFDoc(), Rect.new(10,200, 80, 300 ) )
	sq.SetColor(ColorPt.new(0, 0, 0), 3)
	sq.RefreshAppearance()
	page3.AnnotPushBack( sq )

	sq = Square.Create( doc.GetSDFDoc(), Rect.new(500,200, 580, 300 ) )
	sq.SetColor(ColorPt.new(1, 0, 0), 3)
	sq.SetInteriorColor(ColorPt.new(0, 1, 1), 3)
	sq.SetBorderStyle( BorderStyle.new( BorderStyle::E_dashed, 6, 0, 0, [4, 2] ) )
	sq.SetPadding( 4 )
	sq.RefreshAppearance()
	page3.AnnotPushBack( sq )
	
	poly = Polygon.Create(doc.GetSDFDoc(), Rect.new(5, 500, 125, 590))
	poly.SetColor(ColorPt.new(1, 0, 0), 3)
	poly.SetInteriorColor(ColorPt.new(1, 1, 0), 3)
	poly.SetVertex(0, Point.new(12,510) )
	poly.SetVertex(1, Point.new(100,510) )
	poly.SetVertex(2, Point.new(100,555) )
	poly.SetVertex(3, Point.new(35,544) )
	poly.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 4, 0, 0 ) )
	poly.SetPadding( 4 )
	poly.RefreshAppearance()
	page3.AnnotPushBack( poly )
	
	poly = PolyLine.Create(doc.GetSDFDoc(), Rect.new(400, 10, 500, 90))
	poly.SetColor(ColorPt.new(1, 0, 0), 3)
	poly.SetInteriorColor(ColorPt.new(0, 1, 0), 3)
	poly.SetVertex(0, Point.new(405,20) )
	poly.SetVertex(1, Point.new(440,40) )
	poly.SetVertex(2, Point.new(410,60) )
	poly.SetVertex(3, Point.new(470,80) )
	poly.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 2, 0, 0 ) )
	poly.SetPadding( 4 )
	poly.SetStartStyle( LineAnnot::E_RClosedArrow )
	poly.SetEndStyle( LineAnnot::E_ClosedArrow )
	poly.RefreshAppearance()
	page3.AnnotPushBack( poly )

	lk = Link.Create( doc.GetSDFDoc(), Rect.new(5,5,55,24) )
	lk.RefreshAppearance()
	page3.AnnotPushBack( lk )

	page4 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page4)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page4)
	
	ew.Begin( page4 )
	font = Font.Create(doc.GetSDFDoc(), Font::E_helvetica)
	element = eb.CreateTextBegin( font, 16 )
	element.SetPathFill(true)
	ew.WriteElement(element)
	element = eb.CreateTextRun( "Some random text on the page", font, 16 )
	element.SetTextMatrix(1, 0, 0, 1, 100, 500 )
	ew.WriteElement(element)
	ew.WriteElement( eb.CreateTextEnd() )
	ew.End()

	hl = HighlightAnnot.Create( doc.GetSDFDoc(), Rect.new(100,490,150,515) )
	hl.SetColor( ColorPt.new(0,1,0), 3 )
	hl.RefreshAppearance()
	page4.AnnotPushBack( hl )

	sq = Squiggly.Create( doc.GetSDFDoc(), Rect.new(100,450,250,600) )
	sq.SetQuadPoint( 0, QuadPoint.new( Point.new(122,455), Point.new(240, 545), Point.new(230, 595), Point.new(101,500 ) ) )
	sq.RefreshAppearance()
	page4.AnnotPushBack( sq )

	cr = Caret.Create( doc.GetSDFDoc(), Rect.new(100,40,129,69) )
	cr.SetColor( ColorPt.new(0,0,1), 3 )
	cr.SetSymbol( "P" )
	cr.RefreshAppearance()
	page4.AnnotPushBack( cr )
	
	page5 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page5)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page5)
	fs = FileSpec.Create( doc.GetSDFDoc(), ($input_path + "butterfly.png"), false )
	page6 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page6)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page6)
	
		
	txt = Text.Create( doc.GetSDFDoc(), Rect.new( 10, 20, 30, 40 ) )
	txt.SetIcon( "UserIcon" )
	txt.SetContents( "User defined icon, unrecognized by appearance generator" )
	txt.SetColor( ColorPt.new(0,1,0) )
	txt.RefreshAppearance()
	page6.AnnotPushBack( txt )
	
	ink = Ink.Create( doc.GetSDFDoc(), Rect.new( 100, 400, 200, 550 ) )
	ink.SetColor( ColorPt.new(0,0,1) )
	ink.SetPoint( 1, 3, Point.new( 220, 505) )
	ink.SetPoint( 1, 0, Point.new( 100, 490) )
	ink.SetPoint( 0, 1, Point.new( 120, 410) )
	ink.SetPoint( 0, 0, Point.new( 100, 400) )
	ink.SetPoint( 1, 2, Point.new( 180, 490) )
	ink.SetPoint( 1, 1, Point.new( 140, 440) )		
	ink.SetBorderStyle( BorderStyle.new( BorderStyle::E_solid, 3, 0, 0  ) )
	ink.RefreshAppearance()
	page6.AnnotPushBack( ink )
	
	page7 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page7)	# begin writing to the page
	ew.End()  # save changes to the current page
	doc.PagePushBack(page7)
	
	snd = Sound.Create( doc.GetSDFDoc(), Rect.new( 100, 500, 120, 520 ) )
	snd.SetColor(  ColorPt.new(1,1,0) )
	snd.SetIcon( Sound::E_Speaker )
	snd.RefreshAppearance()
	page7.AnnotPushBack( snd )
	
	snd = Sound.Create( doc.GetSDFDoc(), Rect.new( 200, 500, 220, 520 ) )
	snd.SetColor(  ColorPt.new(1,1,0) )
	snd.SetIcon( Sound::E_Mic )
	snd.RefreshAppearance()
	page7.AnnotPushBack( snd )
	
	page8 = doc.PageCreate(Rect.new(0, 0, 600, 600))
	ew.Begin(page8)	# begin writing to the page
	ew.End()	# save changes to the current page
	doc.PagePushBack(page8)
	
	ipage = 0
	while ipage<2 do
		px = 5
		py = 520
		istamp = RubberStamp::E_Approved
		while istamp <= RubberStamp::E_Draft do
			st = RubberStamp.Create(doc.GetSDFDoc(), Rect.new(1,1,100,100))
			st.SetIcon( istamp )
			st.SetContents( st.GetIconName() )
			st.SetRect( Rect.new(px, py, px+100, py+25 ) )
			py -= 100
			if py < 0
				py = 520
				px+=200
			end
			if ipage == 0
				#page7.AnnotPushBack( st )
			else
				page8.AnnotPushBack( st )
				st.RefreshAppearance()
			end
			istamp = istamp + 1
		end
		ipage = ipage + 1
	end
	
	st = RubberStamp.Create( doc.GetSDFDoc(), Rect.new(400,5,550,45) )
	st.SetIcon( "UserStamp" )
	st.SetContents( "User defined stamp" )
	page8.AnnotPushBack( st )
	st.RefreshAppearance()
end

	PDFNet.Initialize(PDFTronLicense.Key)
	
	doc = PDFDoc.new($input_path + "numbered.pdf")
	doc.InitSecurityHandler()
	
	# An example of using SDF/Cos API to add any type of annotations.
	AnnotationLowLevelAPI(doc)
	doc.Save($output_path + "annotation_test1.pdf", SDFDoc::E_remove_unused)
	puts "Done. Results saved in annotation_test1.pdf"
	
	# An example of using the high-level PDFNet API to read existing annotations,
	# to edit existing annotations, and to create new annotation from scratch.
	AnnotationHighLevelAPI(doc)
	doc.Save(($output_path + "annotation_test2.pdf"), SDFDoc::E_linearized)
	doc.Close()
	puts "Done. Results saved in annotation_test2.pdf"
	
	doc1 = PDFDoc.new()
	CreateTestAnnots(doc1)
	outfname = $output_path + "new_annot_test_api.pdf"
	doc1.Save(outfname, SDFDoc::E_linearized)
	doc1.Close()
	PDFNet.Terminate
	puts "Saved new_annot_test_api.pdf"