Menu

Font Embedding Reprise

SourceForge Editorial Staff

Font Embedding Reprise

Problem Description

In Flash Player 10, there are two different ways to embed fonts: DefineFont3 and DefineFont4 (also known as CFF). The original Flash TextField can only be used with DefineFont3 fonts. The new Vellum components can only be used with DefineFont4.

Since Halo components use UITextField, a subclass of TextField, they are currently only compatible with DefineFont3. The Gumbo components use Vellum, so they will only be compatible with DefineFont4. Since many Flex 4 projects will use a mix of Halo and Gumbo components, this would lead to two problems:

  1. The same font would need to be embedded twice in each application--once using DefineFont3 and once using DefineFont4. This will lead to bloated SWFs.
  2. Developers would have to carefully craft their CSS to ensure that the DefineFont3 version of a font is applied to Halo components and the DefineFont4 version is applied to Gumbo components. This would require a great deal of manual work, and would be highly error-prone, since mismatches could not be detected at compile time.

Originally, we had planned to make a drop-in replacement for UITextField called UITLFTextField which would be compatible with DefineFont4. In this plan, the Halo components would automatically use UITLFTextField by default, but would switch back to UITextField if the developer set a compiler switch that would set the default font embedding to DefineFont3. (See the original Font Embedding proposal.)

Unfortunately, UITLFTextField won't reach feature parity with UITextField in the Flex 4.0 timeframe; in particular, it won't support editing and selection. As a result, not all Halo components will be compatible with DefineFont4. Therefore, we need to revisit our original decision. (In a near-future version, the problem should become less severe, because we'll either be able to bring UITLFTextField to parity with UITextField, or because we'll have Spark alternatives for all the Halo components that require UITextField.)

Additionally, we seem to have taken a step backwards with the usability of embedded fonts in Flex 4, in that an extra "fontLookup" attribute now needs to be specified on components that want to use DefineFont4 fonts. We should eliminate this if possible.

Decision

To accept the proposal below.

Decision Criteria

  1. Developers creating all-Spark or all-Halo applications and who want to embed a font should not have to do extra work compared to what they had to do in Flex 3.
  2. Developers creating mixed Spark/Halo applications should not have to do an excessive amount of work to embed fonts that will work with the components in their applications, and the work they have to do should be easy to explain and straightforward to implement.
  3. We should avoid bloating SWFs with two embedded versions of the same font wherever possible, and should not double-embed any fonts by default.
  4. Tooling that supports font embedding should not be heavily impacted by the proposal.

Proposed Solution(s):

  1. To fix the "fontLookup" usability issue, we will add a new value, "auto", for fontLookup, and make that the default. When fontLookup is auto, we will automatically figure out the correct value.
  2. By default, "cff" will be set to true, so fonts will be embedded using DefineFont4 by default.
  3. Create a version of UITextField called UITLFTextField that is based on TLF, so it works with DefineFont4 (CFF) fonts, and drop it into the Halo components.
    1. Halo components will support a new style that sets which textfield class to use. The default stylesheet will set UITLFTextField as the default textfield for components that can support it. UPDATE 6/19: we will not set UITLFTextField as the default textfield. Developers who want to take advantage of it will need to manually set it as the textfield for Halo controls that use DefineFont4 embedded fonts.
    2. Due to limited time on the Flex 4 schedule, UITLFTextField will not support all the functionality of UITextField. In particular, it will not support editable text or HTML markup. Therefore, some Halo controls can't be retrofitted to use UITextField.
    3. Developers building mixed Spark/Halo apps who want to embed fonts into Halo controls that require UITextField will need to manually embed them, as described below.
  4. If the Flex 3 compatibility flag is set, make the behavior for embedded fonts be exactly like Flex 3, by doing the following:
    1. Default embedded fonts that don't otherwise specify a value for the "cff" property to "cff: false".
    2. Add an additional global style rule that sets UITextField as the default textfield for all Halo components (overriding the UITLFTextField default from the previous item). UPDATE 6/19: unnecessary due to the change mentioned above.

The ramifications of this proposal are as follows.

  1. For Spark-only projects, the developer embeds and uses fonts exactly the same way s/he did in Flex 3: s/he defines an embedded font using @font-face (without needing to set the "cff" attribute), and can apply the font in the global style to apply it to all components (or apply it to CSS classes or specific components as usual).
  2. For Halo-only projects, if the developer chooses Flex 3 compatibility mode, s/he embeds fonts exactly the same way s/he did in Flex 3.
  3. Most Spark projects that use Halo components will also be able to embed fonts using the normal mechanism, but for some mixed projects, developers will need to manually embed DefineFont3 fonts:
    1. For projects that use Halo components like TextInput that have a Spark equivalent, our recommendation would be to use the Spark version instead.
    2. For Halo components that do not have a Spark equivalent and that need to use embedded fonts, developers will either need to set the textField style to UITLFTextField, or manually embed a DefineFont3 version of the font as described below. Note that some Halo components will not be able to use UITLFTextField (editable ComboBox, ColorPicker color field, DateField, RichTextEditor, editable DataGrid) and so will need to use DefineFont3 fonts.
    3. That leaves a handful of components (editable ComboBox, ColorPicker color field, DateField, RichTextEditor, editable DataGrid) that require UITextField and have no Spark equivalent. In these cases, developers will need to manually embed DefineFont3 fonts for these components, as described below.
    4. Note that if the developer tries to apply a DefineFont4 font to a Halo control that uses UITextField, the control will still work--it will just fall back to the default font.

In order to manually embed a DefineFont3 font, the developer will need to:

  1. Create a @font-face declaration for the font that has "cff: false" set.
  2. If both DefineFont3 (CFF) and DefineFont4 (non-CFF) versions of the same font are needed, give different names to the two embedded versions.
  3. Apply the non-CFF version to the components that require it, either using CSS or attributes on specific component instances.

Here are some examples:

For a Halo TextInput: (normally we would recommend you use the Spark version, but as an example…)

@font-face {
    src: url("assets/ARIAL.TTF");
    fontFamily: ArialDF3Embed; /* named this way so you could use ArialEmbed for the DF4 version, if needed */
        cff: false;
}
mx|TextInput {
    fontFamily: ArialDF3Embed;
}

For a Halo editable ComboBox, it's a bit more work since you also have to set the font on the internal TextInput:

@font-face {
    src: url("assets/ARIAL.TTF");
    fontFamily: ArialDF3Embed; /* named this way so you could use ArialEmbed for the DF4 version, if needed */
        cff: false;
}
mx|ComboBox {
    fontFamily: ArialDF3Embed;
    textInputStyleName: myTextInput;
}
.myTextInput {
    fontFamily: ArialDF3Embed;
}

(Note that without the fontLookup fix described in the proposal, you would need to also set "fontLookup: device" on these components, even though this is an embedded font, not a device font. That kind of confusion is why we want to make it so developers don't need to set fontLookup.)

As above.

Notes

Analysis of which Halo components are likely to be needed in a Spark app (i.e. there's no viable Spark replacement) that will require UITextField (and thus DF3)

[[ quote ]] The following analysis covers all Halo components in the Flex SDK that display text. It doesn't include any DMV stuff, but I don't think the DMV components will change the conclusion. UITLFTextField (completed through Milestone 1) can be the default in the following Halo components, which simply display single-format, non-interactive text: Accordion Alert Button ButtonBar CheckBox DateChooser FileSystemComboBox FileSystemHistoryButton FormHeading FormItem LinkBar LinkButton Menu MenuBar Panel PopUpButton PopUpMenuButton PrintDataGrid ProgressBar RadioButton TabBar TabNavigator TitleWindow ToggleButtonBar ToolTip The remaining components support interactive text (i.e, text that is scrollable, selectable, editable, or has hyperlinks) or rich text. We cannot make UITLFTextField the default for them without doing significant additional work (Milestones 2 and/or 3) in UITLFTextField; they must continue to use TextField or else they will throw RTEs. So the question for Flex 4 is whether they present a problem by having common use cases that require embedded fonts to use DF3. List-based components (List, FileSystemList, HorizontalList, TileList,, DataGrid, FileSystemDataGrid, Tree, FileSystemTree): Some of these (List, HorizontalList, TileList) have Spark replacements. Or, in the common case that developers don't use editability or htmlText-based custom item renderers, they can opt in to use UITLFTextFIeld in order to use DF4. Otherwise, they would need DF3. Label, Text: Developers can use Spark replacements. Or, in the common case that developers don't use htmlText, they can opt in to use UITLFTextField in order to use DF4. Otherwise, they would need DF3. TextInput, TextArea: Developers can use Spark replacements. Otherwise, they would need DF3. RichTextEditor: Developers can build a Spark replacement. (We should blog an example.) Otherwise, they would need DF3. ColorPicker: This has editable text. But it only displays a color value like "#FF0000" so using an embedded font should not be necessary. If it is, they would need DF3. ComboBox: Developers can use a Spark ComboBox. Or, in the common case that it doesn't need to be editable, they can opt in to use UITLFTextField in order to use DF4. Otherwise, they would need DF3. DateField: In the common case that developers don't use editability, they can opt in to use UITLFTextField in order to use DF4. Otherwise, they would need DF3. NumericStepper: In the common case that it doesn't need to be editable, developers can opt in to use UITLFTextField in order to use DF4. Otherwise, they would need DF3. I conclude that the cases requiring DF3 are of the "20% of 20%" types, such as apps that use both embedded fonts and editable item renderers. We can get away with making this small fraction embed both DF3 and DF4 until TLFTextField is complete in Flex 4.1. 
[[ /quote ]]

Related

Wiki: Flex 4
Wiki: Gumbo Font Embedding

MongoDB Logo MongoDB