Setting custom attributes on form fields (e.g. font, point size, stroke color, etc).

Q: I have everything up and running and the new demo is working
fabulously -
compiles wonderfully on XCode where I do my development. I am
exploring
and experimenting, but I have a few follow up questions:

Can Form Field / Annotation objects have have any typeface attributes
set?
(font, point size, stroke color, etc.) I did not see any classes with
the
power to do such things.
------
A: Using annot.SetAppearance() you can define a custom-look and feel
of any annotation (including widgets). If you search the PDFNet KB for
"SetAppearance" you will find several relevant articles.

Please note that after setting a custom appearance you should not call
RefreshAppearances(). Calling pdfdoc.RefreshAppearances() or filed.
RefreshAppearance() will overwrite the custom appearance.

In case that you find creating a custom appearance too complicated,
you can set a different 'default appearance string' for the field
before calling RefreshAppearance(). With this appraoch you have more
limited control of the look an feel of the text widget (you can only
control the color, font face, font size, and other graphics state
properties). For example:

string da_str = "/Helv 0 Tf 0 g ";
my_field.Put("DA", Obj.CreateString(da_str));

// Refresh the appearance...
my_field.EraseAppearance();
my_field.RefreshAppearance();

The number value preceding 'Tf' in da_str indicates the desired font
size. Value 0 means that the font size should be selected
automatically so that text fills out the field.

The following are some default appearances that you may play with
during testing:

"/Helv 14 Tf 0 g "; // font size is fixed to 14pts. Text is black.
"/Helv 12 Tf 1 0 0 rg "; // font size is fixed to 12pts. Text color
is red.

Q: This topic has several articles in the KB, but perhaps not on point
for fields instead of annotations.

1. I'd like the few lines of code here vetted. I couldn't find an
example for fields. Is this the way to do this?
2. I'd suggest a KB entry specifically addressing changing field
attributes.
3. Where are the parameters passed in the string "/Arial 10 Tf 1 0 0
rg " and the string format documented? And the keys ("DA", for
example)?

Experience helps: "Tf" must be text field; the last 3 fields are RGB
values. The answer would answer questions such as: Can I write x'ff'?
Where do the letter values like "rg" come from?

         Dim docPDF as PDFDoc
         Dim sdfObjFld as SDF.Obj
         Dim fldField as Field
         Dim strFieldName as String = "SampleFieldName"
         Dim strFieldValue as String = "Sample Field Value"
         fldField = docPDF.GetField(strFieldName)
         If Not fldField Is Nothing Then
               fldField.SetValue(strFieldValue)
               docPDF.RefreshFieldAppearances()
               sdfObjFld = fldField.GetSDFObj()
               If Not sdfObjFld Is Nothing Then
                   sdfObjFld.PutString("DA", "/Arial 10 Tf 1 0 0 rg ")
                   docPDF.RefreshFieldAppearances()
               End If
        End If
----
A: The format for DA (i.e. Default Appearance) is documented in PDF
Reference Manual (http://www.pdftron.com/downloads/PDFReference16.pdf,
Table 8.71 in Chapter 8.6.2)

The default appearance string contains a sequence of valid page-
content graphics or text state operators that define such properties
as the field’s text size and color. The operators are documented in
Appendix A "Operator Summary" in PDF Reference.

The following are the relevant paragraphs from Chapter 8.6.2.

"The default appearance string (DA) contains any graphics state or
text state operators needed to establish the graphics state
parameters, such as text size and color, for displaying the field’s
variable text. Only operators that are allowed within text objects may
occur in this string (see Figure 4.1 on page 197). At a minimum, the
string must include a Tf (text font) operator along with its two
operands, font and size. The specified font value must match a
resource name in the Font entry of the default resource dictionary
(referenced from the DR entry of the interactive form dictionary; see
Table 8.67). A zero value for size means that the font is to be auto-
sized: its size is computed as a function of the height of the
annotation rectangle. The default appearance string should contain at
most one Tm (text matrix) operator.

If this operator is present, the viewer application should replace the
horizontal
and vertical translation components with positioning values it
determines to be appropriate, based on the field value, the quadding
(Q) attribute, and any layout rules it employs. If the default
appearance string contains no Tm operator, the viewer should insert
one in the appearance stream (with appropriate horizontal and vertical
translation components) after the default appearance string and before
the text-positioning and text-showing operators for the variable
text."

"Operator rg (r g b rg) sets the fill color space to DeviceRGB and set
the color to use for filling operations.
Each operand must be a number between 0.0 (minimum intensity) and 1.0
(maximum intensity)."

"rg" is a shorthand for "Set RGB values for fill color".
"Tf" is a shorthand for "Set font and font size".
"Tm" is a shorthand for "Set text matrix".
"Tc" is a shorthand for "Set text character spacing".
... etc.

The following are examples of DA strings:

// Set font size to 10 pts. Set text color to black (0, 0, 0).
fld.PutString("DA", "/Arial 10 Tf 0 0 0 rg ");

// Auto-size font (font size = 0). Set text color to red (1, 0, 0).
fld.PutString("DA", "/Arial 0 Tf 1 0 0 rg ");

// Set font size to 14 pts. Set text color to green (0, 0, 1).
fld.PutString("DA", "/Arial 0 Tf 0 0 1 rg ");

// Auto-size font (font size = 0). Set character spacing (Tc) to 0.25.
Set text color to gray (0.5, 0.5, 0.5).
fld.PutString("DA", "/Courier 0 Tf 0.25 Tc 0.5 0.5 0.5 rg ");

// Set the explicit text matrix (scale text 0.5 horizontally, 1.5
times vertically, offset by [10,20]).
fld.PutString("DA", "/Courier 12 Tf 0.5 0 0 1.7 10 20 Tm ");

Q: Thanks for the sample code. It works on some 'standard' fonts like
"Helv" but doc.RefreshAppearances() raises an exception "Missing
Resource" if I use anything other than Helv. Could you please clarify
this.
------
A: The problem is that Arial font can't be found in the resource
dictionary for the form fields in your document. To resolve this you
need to create/embed a font as follows:

// Create a custom font that fill be used to fill form fields.
// This function could be invoked only once to setup custom fonts that
will be
// later used in PutString("DA" ...).

Obj dr = doc.GetAcroForm().FindObj("DR"); if (dr == null) dr =
doc.GetAcroForm().PutDict("DR");

Obj font_dict = dr.FindObj("Font");
if (font_dict == null) font_dict = dr.PutDict("Font");

Obj myfont = font_dict.FindObj("MyFont"); if (myfont == null) {
  Font fnt = Font.Create(doc, Font.StandardType1Font.e_times_roman);
  // or Font fnt = Font.CreateTrueTypeFont(doc, "myfont.ttf");
  // ... etc
  myfont = fnt.GetSDFObj();
  font_dict = font_dict.Put("MyFont", myfont); }

...
field.GetSDFObj().PutString("DA", " /MyFont 10 Tf 1 0 0 rg ");
field.EraseAppearance();
field.SetValue("A new value"); ...
doc.RefreshFieldAppearances();
doc.Save("my.pdf", 0);
doc.Close();

The above sample is in C#, but it should be easy to translate in
VB.NET.