Programmatic creation of PDF annotations.

Q: Using PDFNet SDK I created a small program to programmaticaly add
comments and annotations to existing PDF documents. I am creating
custom appearance streams instead of using default appearances. Stuff
works well for path markup (lines, circles, etc) but I am not sure how
to add text
--------------
A: The simplest way to create a free text annotation is using the high-
level API. For example (in C#, other languages are similar):

pdftron.PDF.Annots.FreeText ftxt = pdftron.PDF.Annots.FreeText.Create
(doc, new Rect(100, 100, 150, 150));
ftxt.SetContents("Hello World!");
ftxt.SetOpacity( 0.45 );
ftxt.RefreshAppearance();
first_page.AnnotPushBack(ftxt);

You can also build your own appearance (without having to rely on
PDFNet) using SetAppearance(). For example:

pdftron.PDF.Annots.FreeText ftxt = pdftron.PDF.Annots.FreeText.Create
(doc, new Rect(100, 100, 450, 150));
string txt = "Hello World!"
ftxt.SetContents(txt);
ftxt.SetAppearance(CreateMyAppearance(doc, txt));
first_page.AnnotPushBack(ftxt);

static Obj CreateMyAppearance(PDFDoc doc, string txt) {
  ElementBuilder builder = new ElementBuilder();
  ElementWriter writer = new ElementWriter();
  writer.Begin(doc);

  writer.WriteElement(builder.CreateTextBegin());
  Element text_run = builder.CreateTextRun(txt, Font.Create(doc,
Font.StandardType1Font.e_helvetica), 1);
  Rect bbox = new Rect();
  text_run.GetBBox(bbox);
  text_run.GetGState().SetFillColor(new ColorPt(0, 0, 1));
  text_run.GetGState().SetFillOpacity(0.5);
  writer.WriteElement(text_run);
  writer.WriteElement(builder.CreateTextEnd());
  Obj stm = writer.End();

  writer.Dispose();
  builder.Dispose();

  // Set the bounding box
  stm.PutRect("BBox", bbox.x1, bbox.y1, bbox.x2, bbox.y2);
  stm.PutName("Subtype", "Form");
  return stm;
}