FTE - Flash Text Engine. A new text rendering engine added to Flash Player 10.
TLF - Text Layout Framework. A high-level text engine written on top of FTE.
TextField - The legacy text type in the Flash Player.
CFF - Compact Font Format. Embedded font format that can only be rendered by FTE and TLF.
Primarily for performance reasons and support for native predictive text input and editing, mobile will use TextField-based text in all critical areas. This is expected to be a short-term solution until a performant version of FTE arrives on mobile. With this in mind, this feature is designed to be hidden from Flex developers for most of the common use cases. The only time you need to know the details is if you are creating a mobile-optimized skin or item renderer.
This feature includes:
StyleableTextField
primitive. This extends TextField
, adds support for styles, and implements the IDisplayText
and IEditableText
interfaces (see next bullet point). This class does not implement IUIComponent
or ILayoutElement
, so it cannot be used as a child in a container. It is designed to be used in ActionScript skins and item renderers only.IDisplayText
and IEditableText
interfaces. These define the contract for simple text display and editable text. Text skin parts in Spark components are updated to use these interfaces instead of the TextBase
and RichEditableText
types currently used. TextBase
implements IDisplayText
and RichEditableText
implements IEditableText
(which extends IDisplayText
).TextInput
and TextArea
components. These skins utilize the new StyleableTextField
primitive.The existing Label
component is unchanged. It is a non-skinned component based on FTE, so the performance is not as good as StyleableTextField
, but is significantly better than TLF-based solutions. Since all performance-critical areas will be using StyleableTextField
(skins and item renderers), the performance impact of Label
should be minimal.
Mark, an experienced Flex developer, is creating his first Flex Mobile application. He opens up design view and sees the familiar text components: Label, TextInput, and TextArea. Mark is able to quickly assemble the UI for his application, and is blissfully unaware of the underlying text primitives used by the skins.
Nigel is creating custom mobile skins and item renderers for his application. He uses the default skins as a starting point, and notices they are using a new StyleableTextField primitive. He looks at the documentation for StyleableTextField, sees that it is for use in optimized AS skins and item renderers, and decides to use it for his skins and item renderers.
There are three primary areas of performance consideration for mobile text:
The StyleableTextField
class is a lightweight subclass of the Flash TextField
class. It implements the IDisplayText
and IEditableText
interfaces (see below), and supports minimal styling through CSS.
This class does not implement IUIComponent
or IVisualElement
, so it cannot be used in MXML markup. It is designed exclusively for use in ActionScript skins and item renderers only.
Styling is done by setting the styleProvider
property and calling the styleChanged()
method. See the "Examples and Usage" section for details on usage.
The IDisplayText
interface is used for display of static text. The IEditableText
interface extends IDisplayText
and adds support for text editing.
StyleableTextField
implements IEditableText
(and IDisplayText
by extension). TextBase
implements IDisplayText
, and RichEditableText
implements IEditableText
.
See the API Description section for details on these interfaces.
The text skin parts for all Spark components are changed to IDisplayText
and IEditableText
. Text skin parts extend InteractiveObject
, so it is safe to cast the parts to InteractiveObject
when needed.
IEditableText
does not support TLF markup, so TextArea
needs to check the type of the skin part before accessing TLF-specific functionality.
Here is a chart listing the Spark components that have text skin parts:
Component
Skin Part
Old Type
New Type
Notes
ButtonBase
labelDisplay
TextBase
IDisplayText
Base class for Button, RadioButton, CheckBox, etc.
SkinnableTextBase
textDisplay
RichEditableText
IEditableText
Base class for TextInput and TextArea
FormHeading
labelDisplay
TextBase
IDisplayText
FormItem
labelDisplay, sequenceLabelDisplay, errorTextDisplay
TextBase
IDisplayText
Panel
titleDisplay
TextBase
IDisplayText
VideoPlayer
currentTimeDisplay, durationDisplay
TextBase
IDisplayText
The following TextArea properties and methods are not supported in mobile:
Name
Type
Notes
content
property
TLF markup is not supported
heightInLines
property
textFlow
property
widthInChars
property
selectionHighlighting
property
Always uses WHEN_FOCUSED
getFormatOfRange()
method
setFormatOfRange()
method
The following text styles are supported by StyleableTextField. These are the only text styles that will function on TextInput and TextArea for mobile.
TextInput (and editable TextArea) support on-screen keyboards and predictive text entry to the extent these are supported by AIR. AIR ensures the editable text is never obscured by the on-screen keyboard, and will scroll the screen contents vertically if needed.
The standard focus ring is drawn around editable text components. Support for 5-way/trackball navigation is planned for post-beta, and details will be in a separate spec.
Touch+drag gestures always select text (when text is selectable or editable). If the text is inside a Scroller, the Scroller will only scroll if the gesture is outside the text component.
package spark.core
{
/**
* The IDisplayText interface defines the properties and methods
* for simple text display.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
public interface IDisplayText
{
/**
* The text displayed by this text component.
*
* <p>The formatting of this text is controlled by CSS styles.
* The supported styles depend on the subclass.</p>
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get text():String;
function set text(value:String):void;
/**
* A flag that indicates whether the text has been truncated.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get isTruncated():Boolean;
}
}
package spark.core
{
/**
* The IEditableText interface defines the properties and methods
* for editable text.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
public interface IEditableText extends IDisplayText
{
/**
* @copy flash.text.TextField#displayAsPassword
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get displayAsPassword():Boolean;
function set displayAsPassword(value:Boolean):void;
/**
* Flag that indicates whether the text is editable.
*
* @default false
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get editable():Boolean;
function set editable(value:Boolean):void;
/**
* @copy flash.text.TextField#maxChars
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get maxChars():int;
function set maxChars(value:int):void;
/**
* @copy flash.text.TextField#restrict
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get restrict():String;
function set restrict(value:String):void;
/**
* @copy flash.text.TextField#selectable
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get selectable():Boolean;
function set selectable(value:Boolean):void;
/**
* @copy flash.display.DisplayObject#accessibilityProperties
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get accessibilityProperties():AccessibilityProperties;
function set accessibilityProperties(value:AccessibilityProperties):void;
/**
* @copy flash.display.InteractiveObject#tabIndex
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get tabIndex():int;
function set tabIndex(value:int):void;
/**
* @copy mx.core.UIComponent#focusEnabled
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get focusEnabled():Boolean;
function set focusEnabled(value:Boolean):void;
/**
* @copy flash.text.TextField#multiline
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get multiline():Boolean;
function set multiline(value:Boolean):void;
/**
* @copy mx.core.UIComponent#enabled
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function get enabled():Boolean;
function set enabled(value:Boolean):void;
/**
* Scroll so the specified range is in view.
*
* @param anchorPosition The anchor position of the selection range.
* @param activePosition The active position of the selection range.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function scrollToRange(anchorPosition:int, activePosition:int):void;
/**
* Inserts the specified text into the text component
* as if you had typed it.
*
* <p>If a range was selected, the new text replaces the selected text.
* If there was an insertion point, the new text is inserted there.</p>
*
* <p>An insertion point is then set after the new text.
* If necessary, the text will scroll to ensure
* that the insertion point is visible.</p>
*
* @param text The text to be inserted.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function insertText(text:String):void;
/**
* Appends the specified text to the end of the text component,
* as if you had clicked at the end and typed.
*
* <p>An insertion point is then set after the new text.
* If necessary, the text will scroll to ensure
* that the insertion point is visible.</p>
*
* @param text The text to be appended.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function appendText(text:String):void;
/**
* Selects a specified range of characters.
*
* <p>If either position is negative, it will deselect the text range.</p>
*
* @param anchorPosition The character position specifying the end
* of the selection that stays fixed when the selection is extended.
*
* @param activePosition The character position specifying the end
* of the selection that moves when the selection is extended.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function selectRange(anchorIndex:int, activeIndex:int):void;
/**
* Selects all of the text.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
function selectAll():void;
}
}
package spark.components.supportClasses
{
/**
* The StyleableTextField class is a text primitive for use in ActionScript
* skins and item renderers. It cannot be used in MXML markup.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
public class StyleableTextField extends TextField implements IEditableText
{
//////////////////////////////////////////////////////
// IDisplayText properties and methods
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// IEditableText properties and methods
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// Properties
//////////////////////////////////////////////////////
/**
* The object that provides styles for this text component. This
* property must be set for the text to pick up the correct styles.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
public var styleProvider:IStyleClient;
//////////////////////////////////////////////////////
// Methods
//////////////////////////////////////////////////////
/**
* Commit the styles into the TextField. This method must be called
* before the text is displayed, and any time the styles have changed.
* This method does nothing if the styles have already been committed.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
public function commitStyles():void
/**
* Notify the text field that a style is changed. This method is typically
* called by the styleChanged() method of the style provider.
*
* @langversion 3.0
* @playerversion Flash 10.1
* @playerversion AIR 2.0
* @productversion Flex 4.5
*/
public function styleChanged(styleProp:String):void
/**
* Truncate text to make it fit horizontally in the area defined for the control,
* and append an ellipsis, three periods (...), to the text.
*
* @param truncationIndicator The text to be appended after truncation.
* If you pass <code>null</code>, a localizable string
* such as <code>"..."</code> will be used.
*
* @return <code>true</code> if the text needed truncation.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function truncateToFit(truncationIndicator:String = "..."):Boolean
}
}
This example shows how to incorporate StyleableTextField into a Button skin:
...
public var labelDisplay:StyleableTextField;
...
override protected function createChildren():void
{
...
// Create the StyleableTextField
textDisplay = new StyleableTextField(createInFontContext(StyleableTextField));
// Set the styleProvider of the text field. The text field will be picking up
// styles from this skin.
textDisplay.styleProvider = this;
// For editable text...
textDisplay.editable = true|false;
// For selectable text...
textDisplay.selectable = true|false;
// For multiline text...
textDisplay.multiline = true|false;
// For word-wrapped text...
textDisplay.wordWrap = true|false;
addChild(textDisplay);
...
}
override protected function measure():void
{
...
// Use the UIComponent.measureText() function for measuring
var lineMetrics:TextLineMetrics = measureText(textDisplay.text);
...
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
...
// Commit the styles in the text field
textDisplay.commitStyles();
textDisplay.width = textWidth;
textDisplay.height = textHeight;
textDisplay.x = textX;
textDisplay.y = textY;
// Truncate the text
textDisplay.truncateToFit();
....
}
override public function styleChanged(styleProp:String):void
{
...
textDisplay.styleChanged(styleProp);
...
}
None.
None.
None.
The mobile skin for TextArea doesn't support TLF-formatted text.
None.
None.
See overview and detailed description sections.
The first release of mobile will not support bidi or mirroring. This will come in a future release.
None.
Possibly an RTE when accessing TLF-specific properties on TextArea.
None.
|| Description || Resolution || Status || | Embedded Font Support - Label uses CFF fonts, StyleableTextField (which is used for all skins and item renderers) uses the older style embedded fonts. There are two options for font embedding: 1). Embed two versions of the font (cff and non-cff). 2). Use TextArea (non-editable, without border) instead of Label. | We will embed non-cff fonts by default, and recommend using TextArea instead of Label when embedding fonts. | Closed | | How to disable mutli-style support in TextArea. ASDoc will mention unsupported properties. Should we throw an RTE, or just silently fail? | Unsupported properties and methods will be clearly noted in ASDoc. The compiler can't provide compiler errors or warnings since the functionality is determined by the skin, not the component. At runtime we will silently fail when accessing unsupported properties or methods. | Closed | | How do we reconcile gesture support for scrolling vs. selection/editing? | Initially the touch+drag gesture will always select text (and cancel any pending scrolling on an outer Scroller). We will evaluate this behavior post-beta and make adjustments as needed. | Closed |
\