FTE and TLF text in MX components - Functional and Design SpecificationFTE and TLF text in MX components - Functional and Design Specification | Last-minute changes | Glossary | Summary and Background | Usage Scenarios | Detailed Description | API Description | B Features | Examples and Usage | Additional Implementation Details | Prototype Work | Compiler Work | Web Tier Compiler Impact | Flex Feature Dependencies | Backwards Compatibility | Accessibility | Performance | Globalization | Localization | Issues and Recommendations | Documentation | QA
Last-minute changesThe following API changes have been made in the trunk since Beta 2: TLFText.css -> MXFTEText.css Glossary
FTE is the foundation for all future text functionality in the Player. TextField will be maintained for backward compatibility, but it will no longer be enhanced, and bug fixes are unlikely. The documentation for the FTE APIs can be found under the flash.text.engine.* package in the Adobe Flex 4 Beta Language Reference. However, very few developers are likely to need to use FTE APIs.
TLF was formerly known by the code name Vellum. (At one point it was also called TCAL, the Text Component ActionScript Library.). It is provided within the Gumbo SDK as the SWCs textLayout.swc. The documentation for the TLF APIs can be found under the flashx.textLayout.* package in the Adobe Flex 4 Beta Language Reference. Developers are likely to use TLF mainly via its text model, when they write MXML tags like <p> and <span> or import markup with such tags. TLF's text model is a superset of FXG 1.0. Summary and BackgroundText in Flash Player 10 is more complicated than it used to be in Flash Player 9: TextField provides "old style" text while FTE (and the TLF library on top of it) provide "new style" text. The main advantages of FTE and TLF over TextField are
The main disadvantages are
The MX components were developed when only TextField was available. The new Spark components have been developed to use FTE and TLF only. This leaves Flex 4 developers who use a combination of MX and Spark components with two problems related to text:
The goal of this feature is to fix both of these problems by making it possible to use FTE/TLF text in some – but not all – MX components. Usage Scenarios
Ermaline is developing an RIA with Flex 4 that uses an embedded font to get the right corporate look. Because the Spark component set isn't yet a complete replacement for the MX one, she is using a mixture of both component sets. She's chosen to use the Spark Button, ComboBox, TextInput, and TextArea over the MX ones, but she still has to use the MX Accordion and DataGrid because these don't have Spark equivalents. She doesn't want to have to bloat the size of her SWF by embedding her font in the two different formats. She embeds her font only with embedAsCFF="true" and compiles with the TLFText theme mxmlc -theme=TLFText.css MyApp.mxml The TLFTExt theme makes it possible for the MX Accordion and DataGrid to use the CFF-embedded font.
Hamid is developing an Arabic RIA with Flex 4. Like Ermaline, he is using a mixture of MX and Spark components. He notices that the MX ones do a poor job of displaying and editing Arabic. By enabling the TLFText theme (as above), the MX components now do a good job of displaying and editing Arabic. Detailed DescriptionHow can a mere theme make certain MX components use FTE and TLF when they were written to use TextField? And why are only some MX components supported rather than all of them? The answer to the first question is that the theme file will set four styles – textFieldClass, textInputClass, defaultDataGridItemRenderer, and defaultDataGridItemEditor – in various CSS type selectors, and these styles will then make those MX components use FTE and TLF by handing them a TextField or TextInput "workalike" implemented using FTE and TLF. The answer to the second question is that the TextField workalike will be only a partial implementation of the TextField API on top of FTE and TLF. It will not support scrolling, selection, or editing, and consequently cannot be used in MX components such as <mx:TextInput> and <mx:TextArea>. textFieldClassConsider, for example, the MX Button type selector in the theme file: Button
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
This will tell the MX Button class to use a new UITLFTextField class – rather than the normal UITextField class – for displaying its label. UITLFTextField will extend a new TLFTextField class, just like UITextField extends TextField, in order to make it play nicely with the LayoutManager. The lower-level TLFTextField will be a "workalike" for the Player's TextField, at least for the functionality that Button requires. Since the MX Button code is written to expect an IUITextField for displaying its label, it will be happy to create either a UITextField or a UITLFTextField because both of these classes implement IUITextField. All MX components were already written to declare their text fields as IUITextFields, and they were already written to create their IUITextFields by calling a factory method in UIComponent, createInFontContext(UITextField). This factory method will be changed so that, even though an MX components asks for a UITextField, the factory method will create whatever the textFieldClass style specifies. Consequently, changes to each MX component that creates text fields will not be necessary. TLFTextField will use FTE and TLF to implement a subset of the API of classic TextField. The subset will support displaying simple text (via the text property) and rich text (via the htmlText property). However, it will not support scrolling, selection, or editing, due to the complexity of supporting these and the fact that they are already supported in Spark components such as RichEditableText. The support for htmlText will include clickable hyperlinks and loadable images, but it will not include bulleted lists because TLF 1.0 does not support them. textInputClassNow consider the MX ComboBox type selector in the theme file: ComboBox
{
textInputClass: ClassReference("mx.controls.TLFTextInput");
}
This tells the editable ComboBox to create a new TLFTextInput, extending the Spark TextInput, instead of an MX TextInput for its entry field. It would not be possible for it to simply create an MX TextInput that uses a UITLFTextField, because UITLFTextField does not support scrolling, selection, or editing. Instead we leverage the work in the Spark RichEditableText component to provide these capabilities. The components which allowed text entry by creating an MX TextInput will be revised so that they accept any component implementing a new interface, ITextInput. The MX TextInput will be revised to implement this interface, and the new TLFTextInput, which extends the Spark TextInput, will also implement this interface. defaultDataGridItemRendererDataGrid item renderers are a special case because they don't contain TextFields, they actually extend TextField. Consequently, they don't get created via the createInFontContext() factory method. This means that we will need to have a new TLFDataGridItemRenderer class that extends UITLFTextField in the same way that DataGridItemRenderer extends UITextField, to make it usable as an item renderer. defaultDataGridItemEditorDataGrid normally creates an MX TextInput for its item editor, but this style can specify that the new TLFTextInput (which extends the Spark TextInput) be used instead. TLFText.css theme file/*
This style sheet should be used if you would like to use the new
Text Layout Framework (TLF) text in your MX controls. TLF
provides text editing with high-quality international typography
and layout. It supports displaying left-to-right (ltr) text such as
French, right-to-left (rtl) text such as Arabic, and bidirectional text
such as a French phrase inside of an Arabic one.
You use this style sheet by applying it as theme to your application.
Alternatively you may apply this style sheet in your application with
<fx:Style source="path/TLFText.css" />
but you will see compiler warnings for any unused selectors.
*/
@namespace "library://ns.adobe.com/flex/mx";
AlertForm
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
Button
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
CalendarLayout
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
ColorPicker
{
textInputClass: ClassReference("mx.controls.TLFTextInput");
}
ComboBox
{
textInputClass: ClassReference("mx.controls.TLFTextInput");
}
DataGrid
{
defaultDataGridItemEditor: ClassReference("mx.controls.TLFTextInput");
defaultDataGridItemRenderer: ClassReference("mx.controls.dataGridClasses.TLFDataGridItemRenderer");
}
DateChooser
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
DateField
{
textInputClass: ClassReference("mx.controls.TLFTextInput");
}
ListItemRenderer
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
MenuBarItem
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
MenuItemRenderer
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
NumericStepper
{
textInputClass: ClassReference("mx.controls.TLFTextInput");
}
Panel
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
ProgressBar
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
SwatchPanel
{
textInputClass: ClassReference("mx.controls.TLFTextInput");
}
TileListItemRenderer
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
TreeItemRenderer
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
ToolTip
{
textFieldClass: ClassReference("mx.core.UITLFTextField");
}
Supported and unsupported MX componentsThe rules are:
The following table summarizes this unfortunately complicated state of affairs:
As is clear from the table above, porting is only required for a few "purely-text" components, which (except for RichTextEditor) have Spark equivalents. We are leaving the development of a Spark RichTextEditor to developers, because the UI for such a component is difficult to standardize. Caveats1. 3rd-party components must follow our Flex framework best-practice of maniupulating TextFields through the interface IUITextField, and create them by calling createInFontContext(UITextField). 2. Rendering fidelity with TextField will not be exact. As an extreme example, TLFTextField might render text as three lines where TextField rendered as two, if the last word doesn't quite fit on the second line. Therefore, when developers "turn on" TextField in an already-written MX application, layout may well be messed up, scrollbars may sprout, etc. 3. If developers have written 3rd-party components that create interactive TextFields, we don't have a solution for them, because out TLFTextField will be only a partial implementation supporting non-interactive text. 4. If developers have written 3rd-party controls that create internal TextInputs, they should revise their code to use ITextInput and pay attention to textInputClass. API DescriptiontextFieldClass style (new in Flex 4)The following style will be added to TextStyles.as, the style metadata file that gets included by any MX component wanting to expose text formatting styles such as fontFamily, fontSize, etc. This style will tell the component whether to use UITextField or UITLFTextField for its IUITextField. /** * The class implementing IUITextField that is used by this component * to render text. * * <p>It can be set to either the mx.core.UITextField class * (to use the classic TextField class built into Flash Player) * or the mx.core.UITLFTextField class * (to use the Text Layout Framework to get improved text rendering, * including bidirectional layout).</p> * * @default mx.core.UITextField */ [Style(name="textFieldClass", type="Class", inherit="no")] class mx.core.TLFTextField (new in Flex 4)This class will move from the flashx.textLayout.controls package (in textLayout.swc) to the mx.core package (in spark.swc). In addition, it is being optimized for FTE, and support for htmlText is being added. Note that it lives in the mx package, but in spark.swc. package mx.core
{
/**
* TLFTextField is a Sprite which uses the Flash Text Engine (FTE)
* and the Text Layout Framework (TLF) to display text by creating
* TextLines as its children.
*
* <p>This class can be used as a replacement for the Player's
* flash.text.TextField class in many but not all MX components,
* thereby bringing the advantages of FTE-based text -- such as
* improved typography and support for bidirectional text
* and CFF-embedded fonts -- to these older components.</p>
*
* <p>TLFTextField supports displaying both <code>text</code>
* and <code>htmlText</code>, but it does not support scrolling,
* selection, or editing.
* This means, for example, that TLFTextField is suitable for use
* inside an MX Button or as a DataGrid item renderer, but cannot be
* used inside, say, an MX TextArea.</p>
*
* <p>Although this class exposes all of the documented properties
* and methods of flash.text.TextField, many of them are simply
* unimplemented stubs that do nothing or throw runtime exceptions.<p>
*
* <p>TLFTextField has two properties which TextField does not have:
* <code>direction</code> and <code>textLineCreator</code>.</p>
*/
public class TLFTextField extends Sprite
{
... [ all of TextField's documented properties and methods ] ...
/**
* The directionality of the text displayed by TLFTextField.
*
* <p>The allowed values are <code>"ltr"</code> for left-to-right text,
* as in Latin-style scripts,
* and <code>"rtl"</code> for right-to-left text,
* as in Arabic and Hebrew.</p>
*
* <p>Note: This property does not exist in the classic
* flash.text.TextField API.</p>
*
* @default "ltr"
*/
public function get direction():String
public function set direction(value:String):void
/**
* The ITextLineCreator instance that TLFTextField
* uses for creating TextLines.
*
* <p>Set this if you need lines to be created in a different
* SWF context than the one containing the TLF code.</p>
*
* <p>Note: This property does not exist in the classic
* flash.text.TextField API.</p>
*
* @default null
*/
public function get textLineCreator():ITextLineCreator
public function set textLineCreator(value:ITextLineCreator):void
}
}
The following tables show the support available for each TextField API. APIs marked as "Unimplemented" will throw a runtime exception if used. Properties
Methods
Events
Formats
class mx.core.UITLFTextField (new in Flex 4)UITLFTextField will extend TLFTextField in the same way that UITextField extends TextField, to make it play nicely with Flex's LayoutManager. Note that it lives in the mx package, but in spark.swc.
package mx.core
{
public class UITLFTextField extends TLFTextField
implements IAutomationObject, IIMESupport,
IFlexModule,
IInvalidating, ISimpleStyleClient,
IToolTipManagerClient, IUITextField
}
class mx.controls.dataGridClasses.TLFDataGridItemRenderer (new in Flex 4)TLFDataGridItemRenderer will extend UITLFTextField in the same way that DataGridItemRenderer extends UITextField, to make it usable as an item renderer. Note that it lives in the mx package, but in spark.swc. package mx.controls.dataGridClasses
{
public class TLFDataGridItemRenderer extends UITLFTextField
implements IDataRenderer,
IDropInListItemRenderer, ILayoutManagerClient,
IListItemRenderer, IStyleClient
}
textInputClass style (new in Flex 4)The following style will be added to ComboBase, NumericStepper, and SwatchPanel, which are the classes which have internal MX TextInputs. This style will tell the component whether to use mx.controls.TextInput or mx.controls.TLFTextInput for its ITextInput. /** * The class implementing ITextInput that is used by this component * to input text. * * <p>It can be set to either the mx.controls.TextInput class * (to use the classic TextField-based MX TextInput control) * or the mx.controls.TLFTextInput class * (to use the Text Layout Framework to get improved text rendering, * including bidirectional layout).</p> * * @default mx.controls.TextInput */ [Style(name="textInputClass", type="Class", inherit="no")] interface mx.core.ITextInput (new in Flex 4)package mx.core
{
/**
* Documentation is not currently available.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public interface ITextInput
extends IDataRenderer, IDropInListItemRenderer, IFocusManagerComponent,
IFontContextComponent, IIMESupport, IListItemRenderer, IUIComponent,
IInvalidating, IStyleClient
{
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// editable
//----------------------------------
/**
* Documentation is not currently available.
*/
function get editable():Boolean;
function set editable(value:Boolean):void;
//----------------------------------
// horizontalScrollPosition
//----------------------------------
/**
* Documentation is not currently available.
*/
function get horizontalScrollPosition():Number;
function set horizontalScrollPosition(value:Number):void;
//----------------------------------
// maxChars
//----------------------------------
/**
* Documentation is not currently available.
*/
function get maxChars():int;
function set maxChars(value:int):void;
//----------------------------------
// mouseChildren
//----------------------------------
/**
* Documentation is not currently available.
*/
function get mouseChildren():Boolean;
function set mouseChildren(value:Boolean):void;
//----------------------------------
// mouseEnabled
//----------------------------------
/**
* Documentation is not currently available.
*/
function get mouseEnabled():Boolean;
function set mouseEnabled(value:Boolean):void;
//----------------------------------
// parentDrawsFocus
//----------------------------------
/**
* Documentation is not currently available.
*/
function get parentDrawsFocus():Boolean;
function set parentDrawsFocus(value:Boolean):void;
//----------------------------------
// restrict
//----------------------------------
/**
* Documentation is not currently available.
*/
function get restrict():String;
function set restrict(value:String):void;
//----------------------------------
// selectable
//----------------------------------
/**
* Documentation is not currently available.
*/
function get selectable():Boolean;
function set selectable(value:Boolean):void;
//----------------------------------
// text
//----------------------------------
/**
* Documentation is not currently available.
*/
function get text():String;
function set text(value:String):void;
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* For MX, used to determine if the control's border object is visible.
* For Spark, it does nothing.
*/
function showBorder(visible:Boolean):void;
/**
* Selects the text in the range specified by the parameters.
*/
function selectRange(anchorIndex:int, activeIndex:int):void;
}
}
interace mx.managers.IFocusManagerComponent (changes from Flex 3)As part of defining ITextInput, we will add a setter for tabIndex to this interface, which already has the getter: function set tabIndex(value:int):void; class mx.controls.TextInput (changes from Flex 3)Instead of implementing many separate interfaces as it did in Flex 3 public class TextInput extends UIComponent
implements IDataRenderer, IDropInListItemRenderer,
IFocusManagerComponent, IIMESupport, IListItemRenderer,
IFontContextComponent
TextInput will implement the new ITextInput interface which aggregates all of these (plus some other properties and methods): public class TextInput extends UIComponent
implements ITextInput
Also the mx_internal parentDrawFocus property, and the mx_internal getter/setter for the selectable property, will be promoted to public getter/setters because they must be in ITextInput: /** * If true, calls to this control's drawFocus() method are forwarded * to its parent's drawFocus() method. * This is used when a TextInput is part of a composite control * like NumericStepper or ComboBox; * * @default false; */ public function get parentDrawsFocus():Boolean public function set parentDrawsFocus(value:Boolean):void /** * A flag indicating whether the text in the TextInput can be selected. */ public function get selectable():Boolean public function set selectable(value:Boolean):void Finally two new methods in ITextInput must be implemented: /**
* Shows or hides the border.
*/
public function showBorder(visible:Boolean):void
/**
* Selects the text in the range specified by the parameters.
* Unlike in <code>setSelection</code>, this is done immediately.
*
* @see mx.controls.TextInput#setSelection
*/
public function selectRange(anchorIndex:int, activeIndex:int):void
class mx.controls.TLFTextInput (new in Flex 4)package mx.controls
{
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when the <code>data</code> property changes.
*
* <p>When you use a component as an item renderer,
* the <code>data</code> property contains the data to display.
* You can listen for this event and update the component
* when the <code>data</code> property changes.</p>
*
* @eventType mx.events..DATA_CHANGE
*/
[Event(name="dataChange", type="mx.events.")]
/**
* TLFTextInput is a UIComponent which is used to support TLF text
* in MX controls and data grid renderers. It can be used in place
* of a MX TextInput control.
*/
public class TLFTextInput extends spark.components.TextInput
implements ITextInput
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*/
public function TLFTextInput()
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// data
//----------------------------------
private var _data:Object;
[Bindable("dataChange")]
[Inspectable(environment="none")]
/**
* Lets you pass a value to the component
* when you use it in an item renderer or item editor.
* You typically use data binding to bind a field of the <code>data</code>
* property to a property of this component.
*
* <p>When you use the control as a drop-in item renderer or drop-in
* item editor, Flex automatically writes the current value of the item
* to the <code>text</code> property of this control.</p>
*
* <p>You do not set this property in MXML.</p>
*
* @default null
*
* @see mx.core.IDataRenderer
*/
public function get data():Object
public function set data(value:Object):void
//----------------------------------
// fontContext
//----------------------------------
/**
* Documentation is not currently available.
*/
public function get fontContext():IFlexModuleFactory
public function set fontContext(value:IFlexModuleFactory):void
//----------------------------------
// horizontalScrollPosition
//----------------------------------
/**
* Documentation is not currently available.
*/
public function get horizontalScrollPosition():Number
public function set horizontalScrollPosition(value:Number):void
//----------------------------------
// listData
//----------------------------------
[Bindable("dataChange")]
[Inspectable(environment="none")]
/**
* When a component is used as a drop-in item renderer or drop-in
* item editor, Flex initializes the <code>listData</code> property
* of the component with the appropriate data from the list control.
* The component can then use the <code>listData</code> property
* to initialize the <code>data</code> property of the drop-in
* item renderer or drop-in item editor.
*
* <p>You do not set this property in MXML or ActionScript;
* Flex sets it when the component is used as a drop-in item renderer
* or drop-in item editor.</p>
*
* @default null
*
* @see mx.controls.listClasses.IDropInListItemRenderer
*/
public function get listData():BaseListData
public function set listData(value:BaseListData):void
//----------------------------------
// parentDrawsFocus
//----------------------------------
/**
* Documentation is not currently available.
*/
public function get parentDrawsFocus():Boolean
public function set parentDrawsFocus(value:Boolean):void
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* Documentation is not currently available.
*/
public function showBorder(visible:Boolean):void
}
class mx.controls.ComboBase (changes from Flex 3)The textInputClass style will be added. (See above.) A type selector for ComboBase will make it default to mx.controls.TextInput. The type of the protected variable textInput will be generalized from TextInput to ITextInput so that it can be either an mx.controls.TextInput or an mx.controls.TLFTextInput, depending on the textInputClass style. protected var textInput:ITextInput; For the same reason, the type of the mx_internal function getTextInput() will similarly change: mx_internal function getTextInput():ITextInput; class mx.controls.NumericStepper (changes from Flex 3)The textInputClass style will be added. (See above.) A type selector for NumericaStepper will make it default to mx.controls.TextInput. The type of the mx_internal variable textField will be generalized from TextInput to ITextInput so that it can be either an mx.controls.TextInput or an mx.controls.TLFTextInput, depending on the textInputClass style. mx_internal var inputField:ITextInput; class mx.controls.colorPickerColasses.SwatchPanel (change from Flex 3)The textInputClass style will be added. (See above.) A type selector for SwatchPanel will make it default to mx.controls.TextInput. The type of the mx_internal variable textInput will be generalized from TextInput to ITextInput so that it can be either an mx.controls.TextInput or an mx.controls.TLFTextInput, depending on the textInputClass style. mx_internal var textInput:ITextInput; B FeaturesNone. Examples and UsageTo make most MX components use FTE/TLF text, a developer simply uses the -theme compiler option to use the TLFText.css file: mxmlc -theme=TLFText.css MyApp.mxml When using this theme, spark.swc must be in the <library-path>, because classes specified in TLFText.css – such as UITLFTextField, TLFDataGridItemRenderer, and TLFTextInput – are in this SWC. Additional Implementation DetailsNone. Haven't I explained enough already? Prototype WorkMost of what is described here has been prototyped and checked in to the trunk. Compiler WorkNone. Web Tier Compiler ImpactNone. Flex Feature DependenciesThis features is dependent on TLF features such as HTML importing and exporting. Backwards CompatibilitySyntax changesNone. BehaviorWhen a MX component uses UITLFTextField insteadc of UITextField, or TLFTextInput instead of TextInput, it is not guaranteed to lay out its text in exactly the same way and therefore may have a different size. Warnings/DeprecationNone. AccessibilityTBD PerformanceTLFTextField is expected to be within 2x of TextField in performance. It is likely to be slower because FTE does much more work than TextField did, in order to provide improved typography, bidirectional support, font fallback, etc. GlobalizationNone. LocalizationCompiler FeaturesNone. Framework FeaturesTLFTextField has a new "unimplemented" RTE message. But it should not be localized because this is conceptually a Player-level class and should not have a dependency on Flex's ResourceManager. Issues and RecommendationsPlayerThis feature will perform better on players that implement the new recreateTextLine() method in TextBlock. TLFThe HTML importer and exporter need improvements before we can ship. TLF also need a more TextField-like LeadingModel. FlexNone. DocumentationASDoc will be provided by the developer. QAYou bet! |
|
| You must be logged in to comment. |
|---|
