FTE and TLF text in MX components - Functional and Design Specification



Last-minute changes


The following API changes have been made in the trunk since Beta 2:

TLFText.css -> MXFTEText.css
TLFTextField -> FTETextField
UITLFTextField -> UIFTETextField
TLFDataGridItemRenderer -> FTEDataGridItemRenderer
TLFTextInput -> MXFTETextInput

Glossary



TextField - A legacy class in the Flash Player that does text rendering and editing. In Flex 3, all MX components used this class for text.


FTE - An acronym for Flash Text Engine, a set of new classes in Flash Player 10. They support low-level text functionality such as rendering individual lines of text. This involves mapping Unicode characters to font glyphs, laying out the glyphs using the Unicode bidirectional text algorithm, determining appropriate line breaks, and rendering the glyphs into pixels.

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 - An acronym for Text Layout Framework, a set of classes built on top of FTE. They provide high-level text functionality such as multiple lines and paragraphs; an XHTML-like text model and markup language; and scrolling, selection, and editing.

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 Background


Text 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

  • high-quality typography with kerning, ligatures, etc.;
  • support for a large set of the world's scripts, include right-to-left ones;
  • support for bidirectional text such as French inside of Arabic;
  • automatic fallback to device fonts when a character is not present in an embedded font;
  • support for text rotation;
  • support for complex text layout via the use of individual TextLine objects.

The main disadvantages are

  • FTE and TLF require a different format for embedded fonts: a DefineFont4 tag in the SWF rather than a DefineFont3 tag.
  • In some cases FTE and TLF are slower and require more memory.

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:

  • If they are using embedded fonts, each font must be embedded both as a DefineFont3 tag (embedAsCFF="false") and as a DefineFont4 tag (embedAsCFF="true").
  • There are various languages, such as Arabic, which the TextField-based MX components don't display well.

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


  • "I don't want to embed fonts twice!"

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.

  • "I need language XXX to work better!"

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 Description


How 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>.

textFieldClass

Consider, 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.

textInputClass

Now 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.

defaultDataGridItemRenderer

DataGrid 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.

defaultDataGridItemEditor

DataGrid 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 components

The rules are:

  • MX components which do not do text scrolling, selection, or editing can use FTE and TLF via UITLFTextField.
  • MX components which do text scrolling, selection, or editing by creating an MX TextInput can use FTE and TLF by creating a TLFTextInput instead.
  • MX components which do text scrolling, selection, or editing by creating a UITLFTextField are not supported. Developers must port to the Spark equivalent in order to use FTE and TLF.

The following table summarizes this unfortunately complicated state of affairs:

Accordion Use TLFTextField for display
Alert Use TLFTextField for display
Button Use TLFTextField for display
ButtonBar Use TLFTextField for display
CheckBox Use TLFTextField for display
ColorPicker Use TLFTextInput for input
ComboBox Use TLFTextField for renderers, TLFTextInput for input
DataGrid Use TLFTextField for renderers, TLFTextInput for editors
DateChooser Use TLFTextField for display
DateField Use TLFTextInput for input
FormHeading Use TLFTextField for display
FormItemLabel Use TLFTextField for display
HorizontalList Use TLFTextField for display
HSlider Use TLFTextField for display
Label Use TLFTextField for display or port to Spark RichEditableText if selectability is required
LinkBar Use TLFTextField for display
LinkButton Use TLFTextField for display
List Use TLFTextField for renderers and TLFTextInput for editors
Menu Use TLFTextField for display
MenuBar Use TLFTextField for display
NumericStepper Use TLFTextInput for input
Panel Use TLFTextField for display
PopUpButton Use TLFTextField for display
PopUpMenuButton Use TLFTextField for display
ProgressBar Use TLFTextField for display
RadioButton Use TLFTextField for display
RichTextEditor Use Spark TextArea and roll your own formatting UI
TabBar Use TLFTextField for display
TabNavigator Use TLFTextField for display
Text Use TLFTextField for display or port to Spark RichEditableText if selectability is required
TextArea Port to Spark TextArea
TextInput Port to Spark TextInput
TileList Use TLFTextField for renderers and TLFTextInput for editors
ToggleButtonBar Use TLFTextField for display
ToolTip Use TLFTextField for display
Tree Use TLFTextField for renderers and TLFTextInput for editors
VSlider Use TLFTextField for display

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.

Caveats

1. 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 Description


textFieldClass 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

alwaysShowSelection Unimplemented - no selection
antiAliasType Getter returns null; setter does nothing - doesn't apply in FTE
autoSize Fully implemented
background Fully implemented
backgroundColor Fully implemented
border Fully implemented
borderColor Fully implemented
bottomScrollV Unimplemented - no scrolling
caretIndex Unimplemented - no editing
condenseWhite Fully implemented
defaultTextFormat Mostly implemented - see Formats below
displayAsPassword Unimplemented - no editing
embedFonts Fully implemented
gritFitType Getter returns null; setter does nothing - doesn't apply in FTE
htmlText Mostly implemented, using TLF's HTML importer/exporter
length Fully implemented
maxChars Unimplemented - no editing
maxScrollH Unimplemented - no scrolling
maxScrollV Unimplemented - no scrolling
mouseWheelEnabled Getter returns false; setter does nothing
multiline Can get and set but flag is ignored - no editing
numLines Fully implemented
restrict Unimplemented - no editing
scrollH Unimplemented - no scrolling
scrollV Unimplemented - no scrolling
selectable Getter returns false; setter does nothing - no selection
selectionBeginIndex Unimplemented - no selection
selectionEndIndex Unimplemented - no selection
sharpness Getter returns NaN; setter does nothing - doesn't apply in FTE
styleSheet Mostly implemented
text Fully implemented
textColor Fully implemented
textHeight Fully implemented
textWidth Fully implemented
thickness Getter returns NaN; setter does nothing - doesn't apply in FTE
type Getter returns "dynamic"; setter is unimplemented - no editing
useRichTextClibboard Unimplemented - no selection or editing
wordWrap Fully implemented

Methods

appendText() Unimplemented - unused in MX components
getCharBoundaries() Unimplemented - unused in MX components
getCharIndexAtPoint() Unimplemented - unused in MX components
getFirstCharInParagraph() Unimplemented - used only in RichTextEditor
getImageReference() Unimplemented - unused in MX components
getLineIndexAtPoint() Unimplemented - unused in MX components
getLineIndexOfChar() Unimplemented - used only in RichTextEditor
getLineLength() Unimplemented - unused in MX components
getLineMetrics() Fully implemented
getLineOffset() Unimplemented - unused in MX components
getLineText() Unimplemented - unused in MX components
getParagraphLength() Unimplemented - used only in RichTextEditor
getTextFormat() Implemented to return copy of defaultTextFormat
isFontCompatible() Unimplemented - unused in MX components
replaceSelectedText() Unimplemented - unused in MX components
replaceText() Unimplemented - used only in TextRange
setSelection() Unimplemented - no selection
setTextFormat() Ignored - use htmlText

Events

change Not dispatched - no editing
link Fully implemented
scroll Not dispatched - no scrolling
textInput Not dispatched - no editing

Formats

align Fully implemented - "left" will be treated as "start" and "right" as "end"
blockIndent Fully implemented - applied from starting edge
bold Fully implemented
bullet Ignored - no lists in TLF 1.0
color Fully implemented
font Fully implemented
indent Fully implemented - applied from starting edge
italic Fully implemented
kerning Fully implemented
leading Fully implemented
leftMargin Fully implemented - applied from starting edge
letterSpacing Fully implemented
rightMargin Fully implemented - applied from ending edge
size Fully implemented
tabStops Ignored - use htmlText
target Ignored - use htmlText
underline Fully implemented
url Ignored - use htmlText

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 Features


None.

Examples and Usage


To 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 Details


None. Haven't I explained enough already?

Prototype Work


Most of what is described here has been prototyped and checked in to the trunk.

Compiler Work


None.

Web Tier Compiler Impact


None.

Flex Feature Dependencies


This features is dependent on TLF features such as HTML importing and exporting.

Backwards Compatibility


Syntax changes

None.

Behavior

When 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/Deprecation

None.

Accessibility


TBD

Performance


TLFTextField 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.

Globalization


None.

Localization


Compiler Features

None.

Framework Features

TLFTextField 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 Recommendations


Player

This feature will perform better on players that implement the new recreateTextLine() method in TextBlock.

TLF

The HTML importer and exporter need improvements before we can ship.

TLF also need a more TextField-like LeadingModel.

Flex

None.

Documentation


ASDoc will be provided by the developer.

QA


You bet!


You must be logged in to comment.