Fonts and Text

Fonts and Text Contents

Fonts and Text Contents.............................................................................................................................. 1

Fonts and Text..................................................................................................................................................... 1

Glyph Definitions.................................................................................................................................................. 2

The EM Square...................................................................................................................................................... 3

Converting TrueType fonts to SWF glyphs......................................................................................................... 3

Kerning and Advance Values................................................................................................................................. 4

DefineFont and DefineText................................................................................................................................... 4

A Text Example..................................................................................................................................................... 4

The DefineFont Tag............................................................................................................................................... 5

The DefineText Tag............................................................................................................................................... 6

Text Records.......................................................................................................................................................... 6

Text Record Type 1 – Text Style Change Record................................................................................................. 6

Text Record Type 0 – Glyph Record.................................................................................................................... 7

Glyph Entry.......................................................................................................................................................... 7

Mapping to Native Fonts...................................................................................................................................... 8

DefineFont2........................................................................................................................................................... 8

Kerning Record...................................................................................................................................................... 9

DefineText2......................................................................................................................................................... 10

SDK Examples....................................................................................................................................................... 10

Edit Text Fields................................................................................................................................................... 10

SDK Examples....................................................................................................................................................... 12

 

Fonts and Text

 

Flash text has been designed to be completely device independent. Text is guaranteed to look exactly the same on every device, regardless of which fonts are installed on the client machine.  The SWF format achieves this by including the exact shape of every letter, number (or other text character) used in the movie.  These character shape definitions are called glyphs.

 

Defining each and every glyph increases the size of a SWF file, particularly if the font is complex.  However, it is a necessary tradeoff.  At design time, Flash knows nothing about the capabilities of the client device, therefore glyphs must always be included in the SWF file, even if the desired font is already on the client machine.

 

To guarantee text is reproduced correctly, SWF also includes the exact position of every character in a text block.  Again, this adds to the file size, but allows sophisticated text layout effects (like kerning and text wrapping) without requiring a complex layout engine built into the Flash player.

 

Glyph Definitions

Glyphs are defined once in a standard coordinate space called the EM square.  The same set of glyphs are used for every point size of a given font.  To render a glyph at different point sizes, the Flash player scales the glyph from EM coordinates to point-size coordinates.

 

Flash fonts do not include any hinting information for improving the quality of small font sizes.  However, antialiasing dramatically improves the legibility of down-scaled text.  Flash text remains legible down to about 12-points (viewed at 100%).  Below that, text may appear fuzzy and blurred.  In any case, it is rare for Flash movies to be used for large bodies of text with small point sizes.

 

 

TrueType fonts can be readily converted to SWF glyphs.  A simple algorithm can replace the Quadratic B-splines (used by TrueType) with Quadratic Bezier curves (used by SWF).

 

 

Example:

To the left is the glyph for the TrueType letter 'b' of Monotype Arial.  It is made up of curved and straight edges.  Squares indicate on-curve points, and crosses indicate off-curve points.  The black circle is the reference point for the glyph.  The blue outline indicates the bounding-box of the glyph.

 


The EM Square

The EM square is an imaginary square that is used to size and align glyphs. The EM square is generally large enough to completely contain all glyphs, including accented glyphs.  It includes the font’s ascent, descent, and some extra spacing to prevent lines of text from colliding.

 

SWF glyphs are always defined on an EM square of 1024 by 1024 units.  Glyphs from other sources (such as TrueType fonts) may be defined on a different EM square.  To use these glyphs in SWF, they should be scaled to fit an EM square of 1024.

 

 

Converting TrueType fonts to SWF glyphs

TrueType glyphs are defined using Quadratic B-Splines, which can be easily converted to the Quadratic Bezier curves used by SWF.

 

A TrueType B-Spline comprises one on-curve point, followed by many off-curve points, followed by another on-curve point. The mid-point between any two off-curve points is guaranteed to be on the curve.  A SWF Bezier curve comprises one on-curve point, followed by one off-curve point, followed by another on-curve point.

 

The conversion from TrueType to SWF curves involves inserting a new on-curve point at the mid-point of two successive off-curve points.

 

Example:

To the left is a four point B-Spline.  P0 and P3 are on-curve points.  P1 and P2 are successive off-curve points.

 

This curve can be represented as two Quadratic Bezier curves by inserting a new point M, at the mid-point of P1,P2.  The result is two Quadratic Bezier curves; P0,P1,M and M,P2,P3.

 

The complete procedure for converting TrueType glyphs to SWF glyphs is as follows:

 

1.       Negate the y-coordinate.  (In TrueType the y-axis points up, in SWF the y-axis points down)

2.       Scale the x and y co-ordinates from the EM square of the TrueType font, to the EM square of the SWF glyph (always 1024)

3.       Insert an on-curve (anchor) point at the mid-point of each pair of off-curve points.

 

For a more complete discussion of this algorithm see: http://www.icce.rug.nl/erikjan/bluefuzz/beziers/beziers/node1.html


Kerning and Advance Values

Kerning defines the horizontal distance between two glyphs.  This distance may be smaller or larger than the width of the left-hand glyph.  Some kerning pairs are more aesthetically pleasing if they are moved closer together.

 

SWF stores kerning information as an advance value.  That is, the horizontal advance from one glyph to another.  SWF stores an advance value for every character in a text block.

 

In the example to the right, the ‘A’ glyph overlaps the ‘V’ glyph. In this case the advance is narrower than the width of the ‘A’ glyph.

 

DefineFont and DefineText

Fonts and text are defined using two tags:

 

1.        The DefineFont tag defines a set of glyphs.

2.        The DefineText tag defines the text-string that is displayed in the font.

 

The DefineFont tag defines all the glyphs used by subsequent DefineText tags.  DefineFont includes an array of SHAPERECORDs, which describe the outlines of the glyphs.  (These shape records are the same records used by DefineShape to define non-text shapes)  To keep file size to a minimum, only the glyphs actually used in the text block are included in the DefineFont tag.  For example, to display the word “hello”, only the glyphs ‘h’, ‘e’, ‘l’, and ‘o’ are defined.

 

The DefineText tag stores the actual text string(s) to be displayed.  It also includes the bounding box of the text object, a transformation matrix, and style attributes such as color, and point size.

 

DefineText contains an array of TEXTRECORDs, of which there are two types:

 

·         Type 0 – Glyph Information.

A Type 0 Record contains an array of indices into the glyph table of the current font.  Characters are not referred to by their ASCII or Unicode values, but by an index into the glyph table.  Type 0 Records also include the advance value for each character in the text string.

 

·         Type 1 – Style Information.

A Type 1 Record selects the current font, color, and point size, as well as the position of next character in the text. These styles apply to all characters that follow, until another Type 1 record changes the styles.  The array of text records always begins with a Type 1 record to set the initial position and style.

 

Note: The DefineFont tag must always come before the DefineText tag that refers to it.

A Text Example

Suppose you want to display the text “bob” in the Arial font, with a point size of 24.

 

First, you must define the glyphs with a DefineFont tag.  The glyph table has two SHAPERECORDs;  At index 0 is the shape of a lower-case ‘b’ (see diagram).  At index 1 is the shape of a lower-case ‘o’.  (The second ‘b’ in bob is a duplicate, and is not required).  DefineFont also includes a unique ID so it can be selected by the DefineText tag.

 

Next you define the text itself with a DefineText tag.  The first text record must be a Type 1 record.  It sets the position of the first character, selects the Arial font (using the unique ID), and sets the point size to 24, so the font is scaled to the correct size.  (Remember that glyphs are defined in EM coordinates – the actual point size is part of the DefineText tag).

 

The second text record is a Type 0 record.  It contains an array of GLYPHENTRYs.  Each glyph entry contains an index into the font’s shape array.  In this example, the first glyph entry has index 0 (which corresponds to the ‘b’ shape), the second entry has index 1 (the ‘o’), and the third entry has index 0 (‘b’ again).  Each GLYPHENTRY also includes an advance value for accurately positioning the glyph.

 

The diagram below illustrates how the DefineText tag interacts with the DefineFont tag:

 

 

 

 

 

 

 

 

 

 

 

 


The DefineFont Tag

The DefineFont tag defines the shape outlines of each glyph used in a particular font.  Only the glyphs that are used by subsequent DefineText tags are actually defined.

 

The FontId uniquely identifies the font.  It can be used by subsequent DefineText tags to select the font.

 

The offset table and shape table are used together.  These tables have the same number of entries, and there is a one-to-one ordering match between the order of the offsets, and the order of the shapes.

The offset table points to locations in the shape table.  Each offset entry stores the difference (in bytes) between the start of the offset table and the location of the corresponding shape:

 

Location of ShapeRecord[n] = StartOfOffsetTable + OffsetTable[n]

 

Because the ShapeTable immediately follows the OffsetTable, the number of entries in both tables can be inferred by dividing the first offset by two:

 

Shape count = OffsetTable[0] / 2

 

 (See class FDTDefineFont in the Flash File Format SDK)

 

DefineFont

Field

Type

Comment

Header

RECORDHEADER

Tag ID = 10

FontId

UI16

ID for this character

OffsetTable

UI16[nGlyphs]

Array of shape offsets

ShapeTable

SHAPE[nGlyphs]

Array of shapes

 

The DefineText Tag

The DefineText tag defines a block of text.  It describes the font, size, color, and exact position of every character in the text object.

(See class FDTDefineText in the Flash File Format SDK)

 

DefineText

Field

Type

Comment

Header

RECORDHEADER

Tag ID = 11

TextId

UI16

ID for this character

TextBounds

RECT

Bounds of the text

TextMatrix

MATRIX

Matrix for the text

TextGlyphBits

NglyphBits = UI8

Bits in each glyph index

TextAdvanceBits

NadvanceBits = UI8

Bits in each advance value

TextRecords

TEXTRECORD[zero or more]

Text records

TextEndOfRecordsFlag

UI8 = 0

Always set to zero

 

The TextBounds field is the rectangle that completely encloses all the characters in this text block.

 

The TextGlyphBits field defines the number of bits used for the TextGlyphIndex field in each GLYPHENTRY record.

 

The TextAdvanceBits field defines the number of bits used for the TextGlyphAdvance field in each GLYPHENTRY record.

 

 

Text Records

Text Records come in two flavors; Type 0 and Type 1.  The first bit of the TEXTRECORD determines the type.

(See class FTextRecord in the Flash File Format SDK)

 

TEXTRECORD

Field

Type

Comment

TextRecordType

UB[1]

0 = glyph record

1 = text style record

Text Record Type 1 – Text Style Change Record

A Type 1 Record sets text styles for subsequent characters.  It can be used to select a font, change the text color, change the point size, or insert a line break. The new text styles apply until another type 1 record changes the styles.

 

The array of text records always begins with a type 1 record to set the initial position and style.

 

(See class FTextChangeRecord in the Flash File Format SDK)

 

TEXTRECORDTYPE1 (Text Style Change Record)

Field

Type

Comment

TextRecordType

UB[1] = 1

1 if text state change record

TextReserved

UB[3]

Reserved – always 0

TextHasFont

HasFont = UB[1]

1 if text font specified

TextHasColor

HasColor = UB[1]

1 if text color specified

TextHasYOffset

HasYOffset = UB[1]

1 if Y offset specified

TextHasXOffset

HasXOffset = UB[1]

1 if X offset specified

TextFontID

If hasFont UI16

Font ID for following text

TextColor

If hasColor RGB

If this record is part of a DefineText2 tag then RGBA

Font color for following text

TextXOffset

If hasXOffset SI16

Font X offset for following text

TextYOffset

If hasYOffset SI16

Font Y offset for following text

TextHeight

If hasFont UI16

Font height for following text



The TextFontID field is used to select a previously defined font.  This ID uniquely identifies a DefineFont tag earlier in the SWF file.

 

The TextHeight field defines the point size of the font in twips. For example, a point size of 50 is equivalent to a TextHeight of 1000. (50 * 20 = 1000).

 

The TextXOffset field defines the offset from the left of the TextBounds rectangle to the reference point of the glyph.  Typically, the reference point is on the baseline, near the left side of the glyph  (see example glyph diagram). The TextXOffset is generally used to create indented text, such as right-justified text. If there is no TextXOffset specified, the offset is assumed to be zero.

 

The TextYOffset field defines the offset from the top of the TextBounds rectangle to the reference point of the glyph.  Typically, the reference point is on the baseline, near the left side of the glyph  (see example glyph diagram). The TextYOffset is generally used to insert line breaks, by moving the text position to start of a new line.

 

Text Record Type 0 – Glyph Record

The Type 0 Text Record defines the actual characters in a text string.  Characters are referred to by an index into the current font’s glyph table, not by an ASCII or Unicode value.  A Type 0 Text Record contains a group of characters that all share the same text style, and are on the same line of text. 

 

(See class FTextGlyphRecord in the Flash File Format SDK)

 

TEXTRECORDTYPE0 (Glyph Record)

Field

Type

Comment

TextRecordType

UB[1] = 0

0 if text glyph record

TextGlyphCount

nGlyphs = UB[7]

Number of glyphs in record

TextGlyphEntries

GLYPHENTRY[nGlyphs]

Glyph entry – see below

 

The TextGlyphCount field defines the number of characters in this string, and the size of the GLYPHENTRY table.

 

Glyph Entry

The GLYPHENTRY structure describes a single character in a line of text.  It is comprised of an index into the current font’s glyph table, and an advance value.  The advance value is the horizontal distance between the reference point of this character, and the following character.

 

(See class FGlyphEntry in the Flash File Format SDK)

 

GLYPHENTRY

Field

Type

Comment

TextGlyphIndex

UB[nGlyphBits]

Glyph index into current font

TextGlyphAdvance

SB[nAdvanceBits]

X advance value for glyph

 

Mapping to Native Fonts

SWF also supports the use of native fonts. Rather than using the glyph outlines in the DefineFont tag, fonts can be rendered using the client machine’s font engine.   Since most native font engines include hinting techniques, they may produce better results at very small point sizes. 

 

The DefineFontInfo tag defines the mapping of a Flash font to a native font.  It includes the font name, font style – bold, italic, or plain, and the encoding scheme used – ANSI, Unicode or ShiftJIS.  It also defines a mapping of glyph indices to character codes.  Thus if ‘a’ were the first character in your DefineFont tag, the DefineFontInfo tag would map index zero to the character code for ‘a’.


(See class FDTDefineFontInfo in the Flash File Format SDK)

 

DefineFontInfo

Field

Type

Comment

Header

RECORDHEADER

Tag ID = 13

FontId

UI16

Font ID this information is for

FontNameLen

NameLen = UI8

Length of font name

FontName

UI8[nameLen]

Name of the font

FontFlagsReserved

UB[2]

Reserved bit fields

FontFlagsUnicode

UB[1]

Unicode character codes

FontFlagsShiftJIS

UB[1]

ShiftJIS character codes

FontFlagsANSI

UB[1]

ANSI character codes

FontFlagsItalic

UB[1]

Font is italic

FontFlagsBold

UB[1]

Font is bold

FontFlagsWideCodes

WideChars = UB[1]

if 1 codeTable is UI16s else UI8s

CodeTable

if wideChars = 1 U16[nGlyphs]
if wideChars = 0 UI8[nGlyphs]

Glyph to code table

 

 

DefineFont2

The DefineFont2 tag extends the functionality of DefineFont.  Enhancements include:

 

·         32-bit entries in the OffsetTable, for fonts with more than 64K glyphs.

·         Mapping to native fonts, by incorporating all the functionality of DefineFontInfo.

·         Ascent, descent and leading information.

·         An advance table that defines the advance for each glyph (in EM square coordinates).

·         A bounds table that defines the bounding-box of each glyph (in EM square coordinates).

·         A table of kerning pairs that defines the distance between pairs of glyphs.

 

(See class FDTDefineFont2 in the Flash File Format SDK)

 

DefineFont2

Field

Type

Comment

Header

RECORDHEADER

Tag ID = 48

FontId

UI16

Font ID for this information

FontFlagsHasLayout

UB[1]

Has font metrics/layout information

FontFlagsShiftJIS

UB[1]

ShiftJIS encoding

FontFlagsUnicode

UB[1]

Unicode encoding

FontFlagsAnsi

UB[1]

ANSI encoding

FontFlagsWideOffsets

UB[1]

If 1, uses 32 bit offsets

FontFlagsWideCodes

UB[1]

If 1, font uses 16-bit codes, otherwise font uses 8 bit codes

FontFlagsItalic

UB[1]

Italic Font

FontFlagsBold

UB[1]

Bold Font

FontFlagsReserved

UB[8]

Reserved Flags

FontNameLen

NameLen = UI8

Length of name

FontName

UI8[NameLen]

Name of Font

FontGlyphCount

UI16

Count of Glyphs in font – nGlyphs

FontOffsetTable

If FontFlagsWideOffsets is 1, UI32[nGlyphs] else UI16[nGlyphs]

 

FontCodeOffset

If FontFlagsWideOffsets is 1, UI32 else UI16

Byte count from start of the FontOffsetTable to start of FontCodeTable

FontShapeTable

SHAPE[nGlyphs]

 

FontCodeTable

If FontFlagsWideCodes is 1, UI16[nGlyphs] else UI8[nGlyphs]

 

FontAscent

If FontFlagsHasLayout is 1,
SI16 – Font ascender height

 

FontDescent

If FontFlagsHasLayout is 1,
SI16 – Font decender height

 

FontLeading

If FontFlagsHasLayout is 1,
SI16 – Font leading height

 

FontAdvanceTable

If FontFlagsHasLayout is 1,
SI16[nGlyphs]

 

FontBoundsTable

If FontFlagsHasLayout = 1,
RECT[nGlyphs]

Not used in Flash 4 Player

FontKerningCount

If FontFlagsHasLayout is 1,
nCount = UI16

Not used in Flash 4 Player

FontKerningTable

If FontFlagsHasLayout is 1,
KERNINGRECORD[nCount]

Not used in Flash 4 Player

Kerning Record

A Kerning Record defines the distance between two glyphs in EM square coordinates.  Certain pairs of glyphs appear more aesthetically pleasing if they are moved closer together, or farther apart. The FontKerningCode1 and FontKerningCode2 fields are the character codes for the left and right characters.  The FontKerningAdjustment field is a signed integer that defines the offset from the advance value of the left-hand character.  The distance between two characters can be calculated like this:

 

Distance = FontAdvanceTable[ord(FontKerningCode1)] + FontKerningAdjustment

 

(See class FKerningRec in the Flash File Format SDK)

 

KERNINGRECORD

Field

Type

Comment

FontKerningCode1

If FontFlagsWideCodes is 1, UI16 else UI8

The character code of the left hand character.

FontKerningCode2

If FontFlagsWideCodes is 1, UI16 else UI8

The character code of the right hand character.

FontKerningAdjustment

SI16

Adjustment relative to advance values.

 

Note: FontBoundsTable, FontKerningCount and FontKerningTable are not used in the player. 

 

DefineText2

The DefineText2 tag is almost identical to the DefineText tag.  The only difference is that Type 1 Text Records contained within a DefineText2 tag use an RGBA value (rather than an RGB value) to define TextColor.  This allows transparent characters.

 

(See class FDTDefineText2 in the Flash File Format SDK)

 

DefineText2

Field

Type

Comment

Header

RECORDHEADER

Tag ID = 33

TextId

UI16

ID for this character

TextBounds

RECT

Bounding box of  the text

TextMatrix

MATRIX

Transform Matrix

TextGlyphBits

NglyphBits = UI8

Bits in each glyph index

TextAdvanceBits

NadvanceBits = UI8

Bits in each advance value

TextRecords

TEXTRECORD[zero or more]

Text records

TextEndOfRecordsFlag

UI8 = 0

Always set to zero

 

SDK Examples

 

The SDK contains C++ examples that demonstrate how to create fonts and text in SWF:

 

·         FExampleFont.cpp uses the low-level manager to create a simple two-glyph font with the letters ‘b’ and ‘o’, and a text object with the string “bob”.

·         HFExampleFont.cpp uses the high-level manager to create a font with the glyphs F, L, A, S, and H.  The glyphs are added to the HFFont object and associated with ASCII/Unicode equivalents.  A text object is created by referencing the glyphs by their ASCII/Unicode values.

 

Edit Text Fields

 

As well as static text, SWF (version 4.0) also supports editable text fields.  A text field is similar to an input field in an HTML form, but it has all the typographic controls of Flash text.  Unlike HTML, a text entry box in a Flash movie can be any color, font, size or style.

 

A text field is associated with a variable name where the contents of the text field are stored.  The Flash movie can perform some action based on the contents of the variable.  For example, a search button could send the contents of a text field to a web server (using a GetURL action) which would display the search results.

 

The DefineEditText tag defines a TextField.

 

(See class FDTDefineEditText in the Flash File Format SDK)

 

DefineEditText

Field

Type

Comment

Header

RECORDHEADER

Tag ID = 37

TextId

UI16

ID for this character

Bounds

RECT

Rectangle that completely encloses the text field. 

HasText

HasText = UB[1]

0 = text field has no default text

1 = text field initially displays the string specified by InitialText

WordWrap

WordWrap = UB[1]

0 = text will not wrap and scroll sideways.

1 = text will wrap automatically when the end of line is reached.

Multiline

Multiline = UB[1]

0 = text field is one line only.

1 = text field is multi-line and will scroll automatically.

Password

Password = UB[1]

0 = characters are displayed as typed.

1 = all characters are displayed as an asterisk.

ReadOnly

ReadOnly = UB[1]

0 = text editing is enabled

1 = text  editing is disabaled.

HasTextColor

HasTextColor = UB[1]

0 = use default color

1 = use specified color (TextColor)

HasMaxLength

HasMaxLength = UB[1]

0 = length of text is unlimited.

1 = maximum length of string is specified by MaxLength.

HasFont

HasFont = UB[1]

0 = use default font.

1 = use specified font (FontID) and height (FontHeight)

Reserved

UB[2]

Reserved for future use

HasLayout

HasLayout = UB[1]

0 = no margins, indents or leading

1 = use specified margins, indents, and leading.

NoSelect

NoSelect = UB[1]

0 = selections enabled

1 = selections disabled 

Border

Border = UB[1]

0 = text field is drawn without border.

1 = text field is drawn with border.

Reserved

UB[2]

Reserved for future use

UseOutlines

UseOutlines = UB[1]

0 =  

FontID

IF HasFont UI16

Font ID for text

FontHeight

IF HasFont UI16

Height of font in twips

TextColor

IF HasTextColor RGBA

Color of text

MaxLength

IF HasMaxLength UI16

Text is restricted to this length

Align

IF HasLayout U8

0 = Left
1 = Right
2 = Center
3 = Justify

LeftMargin

IF HasLayout UI16

Left margin in twips

RightMargin

IF HasLayout UI16

Right margin in twips

Indent

IF HasLayout UI16

Indent in twips

Leading

IF HasLayout UI16

Leading in twips.

VariableName

STRING

Name of the variable where the contents of the text field are stored.

InitialText

IF HasText STRING

Text that is initially displayed in the text field, before it is edited.

 

Note: Fonts used by DefineEditText must be defined using DefineFont2, not DefineFont.

 

 

SDK Examples

 

The SDK contains C++ examples that demonstrate how to create editable text fields in SWF:

 

·         FExampleEditText.cpp uses the low-level manager to create a single-line editable text field, which contains the text “start” initially.  The FDTDefineEditText object does not define any outlines (glyphs), it uses the default font built into the player.