Adobe Open Source
   Home     Projects     Source     Documentation     Forums    About
Welcome Guest | Sign In
 

Gumbo Text Primitives - Functional and Design Specification



Glossary



FTE - An acronym for Flash Text Engine, a set of new classes baked into 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 Gumbo ActionScript 3.0 Language and Components Reference. However, very few developers are likely to need to use FTE APIs.


TextLine - FTE's display primitive for text rendering. At the level of FTE, displaying text means using a TextBlock to create instances of TextLine – a new subclass of DisplayObject – for each line of text and putting them on the display list. TextLines support alpha and rotation, even with device fonts. When using embedded fonts, FTE requires that they be embedded in the SWF file with a new DefineFont4 tag rather than the old DefineFont3 tag.


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 three SWCs textLayout_core.swc, textLayout_conversion.swc, and textLayout_edit.swc.

The documentation for the TLF APIs can be found under the flashx.textLayout.* package in the Gumbo ActionScript 3.0 Language and Components 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.


text object model - Unlike TextField, TLF uses an ActionScript object model to represent rich text. Concepts like paragraphs, spans, and hyperlinks are not represented as formats that affect the appearance of character runs in a single, central text string. Instead they are represented by runtime-accessible ActionScript objects, with their own properties, methods, and events (but not styles, at least not yet). For example, you can easily write code to change the color of the second paragraph object. The "plain text" that is displayed is actually distributed across the leaf nodes of the text object model.


text markup - Markup languages, such as that defined by the FXG 1.0 specification, are very useful with TLF but have secondary importance compared with the primacy of the text object model. Markup – either as MXML at compile time or as a String at runtime – can be used to create a text object model, but the model does not store the exact markup that was used to create it. To obtain it again, you "export" new markup from the model.


TextFlow - TLF's most important class. It is the root of a TLF text object model, which is a tree of FlowElements such as ParagraphElements (corresponding to <p> tags) and SpanElements (corresponding to <span> tags). TLF's job is to create, render, manipulate, and edit TextFlows.


FlowElement - The base class for all the nodes in a TextFlow. The tags and classes for the nodes inside a TextFlow tree are

Tag Class
<div> flashx.textLayout.elements.DivElement
<p> flashx.textLayout.elements.ParagraphElement
<span> flashx.textLayout.elements.SpanElement
<a> flashx.textLayout.elements.LinkElement
<img> flashx.textLayout.elements.InlineGraphicElement
<br> flashx.textLayout.elements.BreakElement
<tab> flashx.textLayout.elements.TabElement
<tcy> flashx.textLayout.elements.TCYElement


character formats - Text-formatting styles or properties which apply at the level of individual characters, such as fontSize.


paragraph formats - Text-formatting styles or properties which apply at the level of individual paragraphs, such as marginLeft.


container formats - Text-formatting styles or properties which apply at the level of the entire component, such as paddingTop.


anchor position - A character index specifying the end of the selection that stays fixed when you extend the selection with the arrow keys.


active position - A character index specifying the end of the selection that moves when you extend the selection with the arrow keys.


FlowOperation - An editing operation that can be performed on a TextFlow. FlowOperations are often created automatically by user activity such as entering text, backspacing, and cutting/pasting. Events let you intercept them to have control over editing operations.

Summary and Background


Gumbo will have three text primitives – TextBox, TextGraphic, and TextView – which offer new text functionality made possible by Flash Player 10 and AIR 1.5. They are implemented using a combination of FTE and TLF.

These primitives will typically be used in the skins of skinnable components, and having three of them allows a pay-as-you-go strategy: you use the lightest-weight one that meets your needs.

For example, the default skin of a Gumbo Button will a TextBox to render the label of the Button. If you have a Button that requires rich text, you can "upgrade" its skin to use a TextGraphic. The default skins of a Gumbo FxTextInput and FxTextArea will use a TextView to provide an area in which text can be edited (but not the border, background, or scrollbars).

The following table summarizes the features of the three text primitives. Note how TextGraphic has more functionality than TextBox, and TextView more than TextGraphic.

Feature TextBox TextGraphic TextView
Extends GraphicElement GraphicElement UIComponent
Uses FTE TLF TLF
Advanced typography Y Y Y
Alpha* Y Y Y
Rotation* Y Y Y
Bi-directional text Y Y Y
Multiple lines Y Y Y
Default formatting via CSS styles Y** Y Y
Multiple formats N Y Y
Multiple paragraphs N Y Y
Text object model N Y Y
Markup language N Y Y
Inline graphics N Y Y
Hyperlinks N N Y
Scrolling N N Y
Selection N N Y
Editing N N Y
Linked containers N N N

* even with device fonts!

** TextBox supports a "basic" subset of TLF formats, as explained in the styles section below.

Note that none of the text primitives are designed to support flowing text through linked containers. This functionality will be added in a post-Gumbo release.

Note also that TextBox and TextGraphic are GraphicElements. GraphicElement is a new core class in Gumbo which supports UIComponent-like layout and invalidation, but which is not itself a DisplayObject. Instead, multiple GraphicElements can sometimes share a single DisplayObject.

This specification also covers FxTextBase, the base class for skinnable components that include a TextView in their skin, such as Gumbo's new FxTextInput and FxTextArea components. It extends FxComponent, the base class for all Gumbo-skinnable components, which is described in the Gumbo Skinning spec.

This specification does not cover details of functionality which is implemented entirely within FTE and TLF. For example, it does not describe things like the linebreaking algorithm, whether a double-click selects whitespace after a word, what Shift-Right-Arrow does, etc., because these are not implemented in Gumbo code.

Usage Scenarios


These three primitives are the basis for all text display in Gumbo components, so usage scenarios include anything involving text. See the table above to determine which text primitive offers which capabilities.

Detailed Description


Default formatting via CSS styles

The three primitives will support specifying default text formatting via CSS styles. The complete set of styles will support all of TLF's formatting capabilities and is divided into the six include files listed below.

Each category of formatting styles – character, paragraph, and container – is divided into "basic" and "advanced" subsets. Because it relies only on FTE and not TLF, TextBox will support only the "basic" styles below, which are a subset of FXG 1.0. TextGraphic and TextView will support both "basic" and "advanced", which constitute a superset of FXG 1.0.

BasicCharacterFormatStyles.as

[Style(name="alignmentBaseline", type="String",
       enumeration="roman,ascent,descent,ideographicTop,ideographicCenter,
       ideographicBottom,useDominantBaseline", inherit="yes")]

[Style(name="baselineShift", type="Object", inherit="yes")]

[Style(name="cffHinting", type="String",
       enumeration="none,horizontalStem", inherit="yes")]

[Style(name="color", type="uint", format="Color", inherit="yes")]

[Style(name="digitCase", type="String",
       enumeration="default,lining,oldStyle", inherit="yes")]

[Style(name="digitWidth", type="String",
       enumeration="default,proportional,tabular", inherit="yes")]

[Style(name="dominantBaseline", type="String",
       enumeration="roman,ascent,descent,
       ideographicTop,ideographicCenter,ideographicBottom", inherit="yes")]

[Style(name="fontFamily", type="String", inherit="yes")]

[Style(name="fontLookup", type="String",
       enumeration="device,embeddedCFF", inherit="yes")]

[Style(name="fontSize", type="Number", format="Length", inherit="yes")]

[Style(name="fontStyle", type="String",
       enumeration="normal,italic", inherit="yes")]

[Style(name="fontWeight", type="String",
       enumeration="normal,bold", inherit="yes")]

[Style(name="kerning", type="String",
       enumeration="on,off,auto", inherit="yes")]

[Style(name="ligatureLevel", type="String",
       enumeration="none,minimum,common,uncommon,exotic", inherit="yes")]

[Style(name="lineHeight", type="Object", inherit="yes")]

[Style(name="locale", type="String", inherit="yes")]

[Style(name="renderingMode", type="String",
       enumeration="normal,cff", inherit="yes")]

[Style(name="textAlpha", type="Number", inherit="yes")]

[Style(name="textRotation", type="String",
       enumeration="rotate0,rotate90,rotate180,rotate270,auto", inherit="yes")]

[Style(name="trackingLeft", type="Object", inherit="yes")]

[Style(name="trackingRight", type="Object", inherit="yes")]

[Style(name="tracking", type="Object", inherit="yes")]

[Style(name="typographicCase", type="String",
       enumeration="default,title,caps,smallCaps,
       uppercase,lowercase,capsAndSmallCaps", inherit="yes")]

AdvancedCharacterFormatStyles.as

[Style(name="breakOpportunity", type="String",
       enumeration="auto,all,any,none", inherit="yes")]

[Style(name="lineThrough", type="Boolean", inherit="yes")]

[Style(name="textDecoration", type="String",
       enumeration="none,underline", inherit="yes")]

[Style(name="whiteSpaceCollapse", type="String,
       enumeration="preserve,collapse", inherit="yes")]

BasicParagraphFormatStyles.as

[Style(name="textAlign", type="String",
       enumeration="left,right,center,justify,start,end", inherit="yes")]

AdvancedParagraphFormatStyles.as

[Style(name="direction", type="String",
       enumeration="ltr,rtl", inherit="yes")]

[Style(name="justificationRule", type="String",
       enumeration="eastAsian,space", inherit="yes")]

[Style(name="justificationStyle", type="String",
       enumeration="prioritizeLeastAdjustment,pushInKinsoku,pushOutOnly",
       inherit="yes")]

[Style(name="marginBottom", type="Number", format="Length", inherit="yes")]

[Style(name="marginLeft", type="Number", format="Length", inherit="yes")]

[Style(name="marginRight", type="Number", format="Length", inherit="yes")]

[Style(name="marginTop", type="Number", format="Length", inherit="yes")]

[Style(name="tabStops", type="Array", inherit="yes")]

[Style(name="textAlignLast", type="String",
       enumeration="left,right,center,justify,start,end", inherit="yes")]

[Style(name="textIndent", type="Number", format="Length", inherit="yes")]

BasicContainerFormatStyles.as

[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]

[Style(name="paddingLeft", type="Number", format="Length", inherit="no")]

[Style(name="paddingRight", type="Number", format="Length", inherit="no")]

[Style(name="paddingTop", type="Number", format="Length", inherit="no")]

[Style(name="verticalAlign", type="String",
       enumeration="top,middle,bottom,justify", inherit="no")]

AdvancedContainerFormatStyles.as

[Style(name="blockProgression", type="String", enumeration="rl,tb", inherit="yes")]

[Style(name="columnCount", type="Object", inherit="no")]

[Style(name="columnGap", type="Number", format="Length", inherit="no")]

[Style(name="columnWidth", type="Object", inherit="no")]

[Style(name="firstBaselineOffset", type="Object", inherit="yes")]

[Style(name="lineBreak", type="String", enumeration="explicit,toFit", inherit="yes")]

The names, allowed values, and meanings of these styles are the same as those in TLF's ICharacterFormat, IParagraphFormat, and IContainerFormat interfaces. (These are in the flashx.textLayout.formats pacakge.) For details, please see the documentation for these interfaces. Note that some styles are inheriting and others non-inheriting.

TLF's FlowElement tags such as <p> and <span>, which are supported in the content of a TextGraphic or TextView, currently support formatting only via properties, not CSS styles. The CSS styles determine the default formatting for text in a text primitive. Formatting properties on FlowElements are applied after the formatting styles on the component.

The default values for each style will be specified in the global selector:

global
{
    ...

    /* character formats */
    alignmentBaseline: "useDominantBaseline";
    baselineShift: 0;
    breakOpportunity: "auto";
    cffHinting: "horizontalStem";
    color: #000000;
    digitCase: "default";
    digitWidth: "default";
    dominantBaseline: "roman";
    fontFamily: "Times New Roman";
    fontLookup: "device";
    fontSize: 12;
    fontStyle: "normal";
    fontWeight: "normal";
    kerning: "on";
    ligatureLevel: "common";
    lineHeight: "120%";
    lineThrough: false;
    locale: "en";
    renderingMode: "cff";
    textAlpha: 1.0;
    textDecoration: "none";
    textRotation: "auto";
    trackingLeft: 0;
    trackingRight: 0
    typographicCase: "default";
    whiteSpaceCollapse: "collapse";

    /* paragraph formats */
    direction: "ltr";
    justificationRule: "space";
    justificationStyle: "pushInKinsoku";
    marginBottom: 0;
    marginLeft: 0;
    marginRight: 0;
    marginTop: 0;
    tabStops: null;
    textAlign: "start";
    textAlignLast: "start";
    textIndent: 0;

    /* container formats */
    blockProgression: "tb";
    columnCount: "auto";
    columnGap: 0;
    columnWidth: "auto";
    firstBaselineOffset: "ascent";
    lineBreak: "toFit";
    paddingBottom: 0;
    paddingLeft: 0;
    paddingRight: 0;
    paddingTop: 0;
    verticalAlign: "top";
}

Five of these default values – those for color, fontFamily, fontSize, kerning, and textAlign – have Halo-compatible defaults for now. They are likely to change in the future.

Text content

Components like TextGraphic and TextView which support TLF-formatted text expose a content property whose getter always returns a TextFlow which is owned by the component.

Although you can set this property to a TextFlow, it is typed as Object to allow you to set to more convenient things from which the component will automatically create a TextFlow:

If you set it to a String, the String will be assumed to be a markup string to be imported by TLF. Such a markup string can range from plain text such as "Hello, world!", through "partial markup" such as "This is <span fontStyle='italic'>very</span> exciting", to full markup enclosed with a <TextFlow> tag.

If you set it to XML, the XML should start with a <TextFlow> tag, and it will get converted to a String and parsed by the TLF importer.

If you set it to a TLF FlowElement, such as a ParagraphElement, this element will get wrapped into a TextFlow.

If you set it to an Array containing Strings and FlowElements, each String will get wrapped into a SpanElement, and then all the FlowElements will get wrapped into a TextFlow.

Regardless of what you set the content to, it will be transformed into a TextFlow by the component's commitProperties() method, so that if you get the content property later (after an updateComplete event) it will be a TextFlow.

There is of course an interaction between the text and content properties. If you set one and later (after an updateComplete event) get the other, they will be in sync.

TextGraphicElement

TextBox and TextGraphic will extend a new subclass of GraphicElement called TextGraphicElement which implements IStyleClient and supports a text property.

Being an IStyleClient means that TextGraphicElements have the same styling APIs as UIComponents, such as getStyle(), setStyle(), styleName, etc. This spec will not discuss them further because the IStyleclient interface is familiar from Flex 3. Note that other types of GraphicElements do not support CSS styles.

The text property can be used for setting and getting "plain text" without any markup. When set, this text will be rendered using the formats determined by the component's CSS styles.

TextGraphicElement is an abstract class in the sense that it does not actually declare any styles or render any text. You need to use one of its subclasses for useful functionality.

TextBox

TextBox is the most lightweight text primitive, because it offers the least functionality. It is a GraphicElement, not a UIComponent. Although currently it always has its own DisplayObject, eventually it will do so only when necessary. It is implemented using only the FTE classes in Flash Player 10 and therefore doesn't link in any classes from the TLF SWCs.

TextBox is basically Gumbo's replacement for <mx:Label>, with some differences: it can display multiple lines, but only in a single format; it can render bidi text; and it supports rotation and alpha even when you use device fonts. Note that it is completely non-interactive: it doesn't support hyperlinks, scrolling, selection, or editing.

TextBox does not support drawing a background or border; it only renders text. It supports only the basic formatting styles: BasicCharacterTextStyles.as, BasicParagraphTextStyles.as, and BasicContainerTextStyles.as.

TextBox uses FTE to create TextLines to statically display its text String in the format determined by the basic formatting styles. For performance, its TextLines do not contain information about individual glyphs; for more info, see flash.text.engine.TextLineValidity.STATIC.

The specified text is wrapped at the right edge of the component's bounds. If it extends below the bottom, it is clipped. The display cannot be scrolled. Truncation is not currently supported but is under consideration.

TextBox's measure() method is implemented to determine the "natural" size of the text. If the width isn't specified, then text will be broken only at explicit linebreaks such as <p> and <br/>.

The only APIs that TextBox adds to TextGraphicElement are the basic formatting styles.

TextGraphic

TextGraphic is the middle-weight text primitive. Like TextBox, it is a GraphicElement, not a UIComponent. Although currently it always has its own DisplayObject, eventually it will do so only when necessary. It is implemented using TLF's TextLineFactory functionality, so using it increases the size of a SWF.

TextGraphic is basically Gumbo's replacement for <mx:Text>: it can display richly-formatted text, with multiple character and paragraph formats. However, it is completely non-interactive: it doesn't support scrolling, selection, or editing.

TextGraphic does not support drawing a background or border; it only renders text and inline graphics. It supports all the text formatting styles.

TextGraphic adds a content property of type Object, as explained in the section above about content.

TextGraphic uses TLF's TextLineFactory to create TextLines to display its TextFlow. For performance, its TextLines do not contain information about individual glyphs; for more info, see flash.text.engine.TextLineValidity.STATIC.

The specified text is wrapped at the right edge of the component's bounds. If it extends below the bottom, it is clipped. The display cannot be scrolled. Truncation is not currently supported, but is under consideration.

TextGraphics's measure() method is implemented to determine the "natural" size of the text. If the width isn't specified, then text will be broken only at explicit linebreaks such as <p> and <br/>.

TextView

TextView is the most heavyweight of the three text primitives, because it offers the most functionality. Unlike TextBox and TextGraphic, it is a UIComponent rather than a GraphicElement, in order to be able to take focus. It is implemented by having TLF control TextLines within the TextView via a DisplayObjectContainerController. In addition to offering TextGraphic's rendering capabilities, it also supports hyperlinks, scrolling, selection, and editing.

TextView is basically a chromeless <mx:TextArea>: it renders a scrollable rectangle of selectable/editable text and inline graphics, but it doesn't support drawing a background, border, or scrollbars. You combine it with other components to do that. For example, new Gumbo components like FxTextInput and FxTextArea use a TextView in their skin to provide the scrollable area where the text is rendered and edited. TextView supports all the text formatting styles.

For setting the text to display, TextView supports both text and content properties. It also supports insertText() and appendText() methods. The content can be exported to XML using the export() method, which produces XML with a TextFlow root tag.

TextView's measure() method does not determine the measured size from the text to be displayed, because a TextView often starts out with no text. Instead it uses two properties called widthInChars and heightInLines to determine its measuredWidth and measuredHeight. These are similar to the cols and rows of an HTML <TEXTAREA>.

TextView supports autoscrolling while selecting or editing, and also supports user scrolling via the mouse wheel. Although it has no scrollbars, it supports programmatic scrolling via the horizontalScrollPosition and verticalScrollPosition properties. The scrolling range can be determined from the contentWidth and contentHeight properties. A selectionChange event is dispatched when the selection changes. Scrolling is currently pixel-based, but line-based scrolling is likely to be added.

The selectability of the content is determined by the selectable property. The selection range can be determined from the read-only selectionAnchorPosition and selectionActivePosition properties and can be set with the setSelection() method. The format of the selection can be determined with the getSelectionFormat() method and set wtih the setSelectionFormat() method.

The editability of the content is determined by the editable property. Each editing operation is preceded by a cancelable changing event and followed by a change event, which specify the FlowOperation that is occurring. (Note: Unlike a TextField's textInput event, the changing event lets you listen for deletions as well as insertions.)

The multiline property determines the behavior of the Enter key when the content is editable. If this property is true, the Enter key terminates the current paragraph. If this property is false, the Enter key does not affect the content and instead causes an enter event to be dispatched.

FxTextBase

FxTextBase is the base class for skinnable Gumbo components whose skin contains a TextView, such as FxTextInput and FxTextArea. It extends FxComponent, the base class for all Gumbo-skinnable components.

The TextView is available via the textView property. FxTextBase facades some of TextView's APIs for convenience. If you need other TextView functionality, access it through textView.

FxTextBase has a text property, but does not support a content property for rich text. (Nobody needs a single-line rich text editor, do they?) It supports the same text formatting styles as TextView, which provide all of TLF's formatting capabilities. (These are actually declared on FxComponent.) It exposes insertText() and appendText() methods.

For selection, it exposes selectionActivePosition and selectionAnchorPosition read-only properties and a setSelection() method.

FxTextInput redispatches its TextView's selectionChange, changing, and change events.

API Description


Class TextGraphicElement

package mx.graphics.graphicsClasses
{

/**
 *  TextGraphicElement is a base class for TextBox and TextGraphic.
 *  It extends GraphicElement to add a 'text' property
 *  and implements the IStyleClient interface so that
 *  CSS styles can be used to specify the formatting of the text.
 */
public class TextGraphicElement extends GraphicElement implements IStyleClient
{
    //------------------------------------------------------------------------------
    //
    //  Constructor
    //
    //------------------------------------------------------------------------------

    /**
     *  Constructor.
     */
    public function TextGraphicElement()

    //------------------------------------------------------------------------------
    //
    //  Properties
    //
    //------------------------------------------------------------------------------

    //--------------------------------------
    //  text
    //--------------------------------------

    [Bindable]

    /**
     *  The text displayed by this GraphicElement.
     *  The text formatting is controlled by CSS styles,
     *  but the supported styles depend on the subclass.
     *
     *  @default ""
     */
    public function get text():String
    public function set text(value:String):void
}

}

Class TextBox

package mx.graphics
{

//--------------------------------------
// Styles
//--------------------------------------

// Basic formatting only
include BasicCharacterFormatStyles.as;
include BasicParagraphFormatStyles.as;
include BasicContainerFormatStyles.as;

//--------------------------------------
//  Other metadata
//--------------------------------------

[DefaultProperty("text")]

/**
 *  TextBox is a GraphicElement that can render
 *  one or more lines of uniformly-formatted text.
 *  The formatting is specified by styles.
 */
public class TextBox extends TextGraphicElement
{
    //------------------------------------------------------------------------------
    //
    //  Constructor
    //
    //------------------------------------------------------------------------------

    /**
     *  Constructor.
     */
    public function TextBox()
}

}

Class TextGraphic

package mx.graphics
{

//--------------------------------------
// Styles
//--------------------------------------

// All formatting supported by TLF
include BasicCharacterFormatStyles.as;
include AdvancedCharacterFormatStyles.as;
include BasicParagraphFormatStyles.as;
include AdvancedParagraphFormatStyles.as;
include BasicContainerFormatStyles.as;
include AdvancedContainerFormatStyles.as;

//--------------------------------------
//  Other metadata
//--------------------------------------

[DefaultProperty("content")]

/**
 *  TextGraphic is a GraphicElement that can render
 *  one or more lines of richly-formatted text.
 *  The default formatting is specified by styles.
 *  The text content can include TLF elements
 *  such as divs, paragraphs, and spans,
 *  each of which can have its own formatting.
 */
public class TextGraphic extends TextGraphicElement
{
    //------------------------------------------------------------------------------
    //
    //  Constructor
    //
    //------------------------------------------------------------------------------

    /**
     *  Constructor.
     */
    public function TextGraphic()

    //------------------------------------------------------------------------------
    //
    //  Properties
    //
    //------------------------------------------------------------------------------

    //--------------------------------------
    //  content
    //--------------------------------------

    [Bindable]

    /**
     *  The TextFlow displayed by this TextGraphic.
     *  When you get this property, it will always be a TextFlow.
     *  For convenience, you can set it to a TextFlow
     *  or to other things that will be converted to a TextFlow:
     *  1. A text String, possibly including markup.
     *  2. XML markup starting with a <TextFlow> tag.
     *  3. A FlowElement.
     *  4. An Array containing a mixture of Strings and FlowElements.
     *
     *  The default value is a TextFlow containing a single paragraph
     *  which contains a single span with no text.
     */
    public function get content():Object
    public function set content(value:Object):void
}

}

Class TextView

package mx.components
{

//--------------------------------------
// Events
//--------------------------------------

/**
 *  Dispached after the <code>selectionAnchorPosition</code> and/or
 *  <code>selectionActivePosition</code> properties have changed.
 *  due to a user interaction.
 */
[Event(name="selectionChange", type="mx.events.FlexEvent")]

/**
 *  Dispatched before a user editing operation occurs.
 *  You can alter the operation, or cancel the event
 *  to prevent the operation from being processed.
 */
[Event(name="changing", type="mx.events.TextOperationEvent")]

/**
 *  Dispatched after a user editing operation is complete.
 */
[Event(name="change", type="mx.events.TextOperationEvent")]

/**
 *  Dispatched when the user pressed the Enter key
 *  if the 'multiline' property is false.
 */
[Event(name="enter", type="mx.events.FlexEvent")]

//--------------------------------------
//  Styles
//--------------------------------------

// All formatting supported by TLF
include BasicCharacterFormatStyles.as;
include AdvancedCharacterFormatStyles.as;
include BasicParagraphFormatStyles.as;
include AdvancedParagraphFormatStyles.as;
include BasicContainerFormatStyles.as;
include AdvancedContainerFormatStyles.as;

//--------------------------------------
//  Other metadata
//--------------------------------------

[DefaultProperty("content")]

/**
 *  TextView is a UIComponent that supports rich text
 *  which is scrollable, selectable, and editable.
 *  The default formatting is specified by styles.
 *  The text content can include TLF elements
 *  such as divs, paragraphs, and spans,
 *  each of which can have its own formatting.
 */
public class TextView extends UIComponent
{
    //------------------------------------------------------------------------------
    //
    //  Constructor
    //
    //------------------------------------------------------------------------------

    /**
     *  Constructor.
     */
    public function TextView()

    //------------------------------------------------------------------------------
    //
    //  Properties
    //
    //------------------------------------------------------------------------------

    //--------------------------------------
    //  content
    //--------------------------------------

    [Bindable]

   /**
     *  The TextFlow displayed by this TextGraphic.
     *  When you get this property, it will always be a TextFlow.
     *  For convenience, you can set it to a TextFlow
     *  or to other things that will be converted to a TextFlow:
     *  1. A text String, possibly including markup.
     *  2. XML markup starting with a <TextFlow> tag.
     *  3. A FlowElement.
     *  4. An Array containing a mixture of Strings and FlowElements.
     *
     *  The default value is a TextFlow containing a single paragraph
     *  which contains a single span with no text.
     */
    public function get content():Object
    public function set content(value:Object):void

    //--------------------------------------
    //  contentHeight
    //--------------------------------------

    [Bindable]

    /**
     *  The height, in pixels, required to fully display the content.
     *  When this is greater than the height of the TextView,
     *  the content is vertically scrollable.
     *
     *  @default 0 
     */
    public function get contentHeight():Number

    //--------------------------------------
    //  contentWidth
    //--------------------------------------

    [Bindable]

    /**
     *  The width, in pixels, required to fully display the content.
     *  When this is greater than the width of the TextView,
     *  the content is horizontally scrollable.
     *
     *  @default 0 
     */
    public function get contentWidth():Number

    //--------------------------------------
    //  editable
    //--------------------------------------

    /**
     *  A flag indicating whether the content is editable.
     *
     *  @default true
     */
    public function get editable():Boolean
    public function set editable(value:Boolean):void

    //--------------------------------------
    //  heightInLines
    //--------------------------------------

    /**
     *  The default height for the TextView, measured in lines.
     *  The TextView's formatting styles -- such as lineHeight
     *  and fontSize -- are used to determined the line height.
     *  This property is used to calculate the TextView's measuredHeight;
     *  the measuredHeight is not determined from the text
     *  or formats in the content.
     *  It will be ignored if you specify an explicit height
     *  or a percent height.
     *
     *  @default 10
     */
    public function get heightInLines():int
    public function set heightInLines(value:int):void

    //--------------------------------------
    //  horizontalScrollPosition
    //--------------------------------------

    [Bindable]

    /**
     *  The number of pixels by which the TextView
     *  is scrolled horizontally.
     *
     *  @default 0
     */
    public function get horizontalScrollPosition():Number
    public function set horizontalScrollPosition(value:Number):void

    //--------------------------------------
    //  multiline
    //--------------------------------------

    /**
     *  A flag indicating whether how the Enter key is processed
     *  when the component is editable.
     *  If true, the Enter key starts a new paragraph.
     *  If false, the Enter key does not change the content
     *  and instead causes an 'enter' event to be dispatched.
     *
     *  @default false
     */
    public function get multiline():Boolean
    public function set multiline(value:Boolean):void

    //--------------------------------------
    //  selectable
    //--------------------------------------

    [Bindable]

    /**
     *  A flag indicating whether the content is selectable.
     *
     *  @default true;
     */
    public function get selectable():Boolean
    public function set selectable(value:Boolean):void

    //--------------------------------------
    //  selectionActivePosition
    //--------------------------------------

    [Bindable]

    /**
     *  A character position specifying the end of the selection.
     *  that changes when the selection is extended.
     *  A value of -1 indicates "not set".
     *
     *  @default -1
     */
    public function get selectionActivePosition():int

    //--------------------------------------
    //  selectionAnchorPosition
    //--------------------------------------

    [Bindable]

    /**
     *  A character position specifying the end of the selection
     *  that stays fixed when the selection is extended.
     *  The value of -1 indicates "not set".
     *
     *  @default -1
     */
    public function get selectionAnchorPosition():int

    //--------------------------------------
    //  text
    //--------------------------------------

    [Bindable]

    /**
     *  The text displayed by this TextView.
     *  Setting this property affects the 'content' property
     *  and vice versa.
     *
     *  @default ""
     */
    public function get text():String
    public function set text(value:String):void

    //--------------------------------------
    //  verticalScrollPosition
    //--------------------------------------

    [Bindable]

    /**
     *  The number of pixels by which the TextView
     *  is scrolled vertical.
     *
     *  @default 0
     */
    public function get verticalScrollPosition():Number
    public function set verticalScrollPosition(value:Number):void

    //--------------------------------------
    //  widthInChars
    //--------------------------------------

    /**
     *  The default width for the TextView, measured in characters.
     *  The width of the "0" character is used for the calculation,
     *  since in most fonts the digits all have the same width.
     *  So if you set this property to 5, it will be wide enough
     *  to let the user enter 5 digits.
     *  This property is used to calculate the TextView's measuredWidth;
     *  the measuredWidth is not determined from the content.
     *  It will be ignored if you specify an explicit width
     *  or a percent width.
     *
     *  @default 20
     */
    public function get widthInChars():int
    public function set widthInChars(value:int):void

    //------------------------------------------------------------------------------
    //
    //  Methods
    //
    //------------------------------------------------------------------------------

    /**
     *  Inserts the specified text, replacing the current selection.
     *  The formatting will be the same as if the new text were typed.
     *  The selection will change to be an insertion point
     *  after the inserted text.
     *  If necessary, the text will scroll to ensure
     *  that the insertion point is visible.
     */
    public function insertText(text:String):void

    /**
     *  Appends the specified text at the end.
     *  The formatting will be the same as if the new text were typed.
     *  The selection will change to be an insertion point
     *  after the inserted text.
     *  If necessary, the text will scroll to ensure
     *  that the insertion point is visible.
     */
    public function appendText(text:String):void

    /**
     *  Selects a range of text.
     *  If no parameters are specified, the entire text will be selected.
     */
    public function setSelection(anchorPosition:int = 0, activePosition = int.MAX_VALUE)

    /**
     *  Returns an Object containing name/value pairs of text formats
     *  for the selected character range.
     *  If a format is not consistently set across the entire range,
     *  its value will be null.
     *  You can specify an Array containing names of the formats
     *  that you want returned; if you don't, all formats will be returned.
      *  For example, calling
     *  <code>getSelectionFormat([ "fontSize", "color" ])</code>
     *  might return <code>({ fontSize: 12, color: null })</code>
     *  if the selection is uniformly 12-point but has multiple colors.
     *  The supported formats are those in the interfaces
     *  ICharacterFormats, IParagraphFormats, and IContainerFormats.
     */
    public function getSelectionFormat(names:Array = null):Object

    /**
     *  Applies a set of name/value pairs of text formats
     *  to the selected character range.
     *  A value of null does not get applied.
     *  For example, calling
     *  <code>setAttributes({ fontSize: 12, color: 0xFF0000 })</code>
     *  will set the fontSize and color of the selection.
     *  The supported attributes are those in the interfaces
     *  ICharacterFormats, IParagraphFormats, and IContainerFormats.
     */
    public function setSelectionFormat(format:Object):void

    /**
     *  Exports the TextView's content as XML with a <TextFlow> root tag.
     */
    public function export():XML
}

}

Class FxTextBase

package mx.components.baseClasses
{

//--------------------------------------
// Events
//--------------------------------------

/**
 *  Dispached after the <code>selectionAnchorPosition</code> and/or
 *  <code>selectionActivePosition</code> properties have changed.
 *  due to a user interaction.
 */
[Event(name="selectionChange", type="mx.events.FlexEvent")]

/**
 *  Dispatched before a user editing operation occurs.
 *  You can alter the operation, or cancel the event
 *  to prevent the operation from being processed.
 */
[Event(name="changing", type="mx.events.TextOperationEvent")]

/**
 *  Dispatched after a user editing operation is complete.
 */
[Event(name="change", type="mx.events.TextOperationEvent")]

/**
 *  The base classes for skinnable text components
 *  such as FxTextInput and FxTextArea whose skin contains a TextView.
 */
public class FxTextBase extends FxComponent implements IFocusManagerComponent
{
    //------------------------------------------------------------------------------
    //
    //  Constructor
    //
    //------------------------------------------------------------------------------

    /**
     *  Constructor.
     */
    public function FxTextBase()

    //--------------------------------------
    //  selectionActivePosition
    //--------------------------------------

    [Bindable("selectionChange")]

    /**
     *  A character position specifying the end of the selection.
     *  that changes when the selection is extended.
     *  A value of -1 indicates "not set".
     *
     *  @default -1
     */
    public function get selectionActivePosition():int

    //--------------------------------------
    //  selectionAnchorPosition
    //--------------------------------------

    [Bindable("selectionChange")]

    /**
     *  A character position specifying the end of the selection
     *  that stays fixed when the selection is extended.
     *  The value of -1 indicates "not set".
     *
     *  @default -1
     */
    public function get selectionAnchorPosition():int

    //--------------------------------------
    //  text
    //--------------------------------------

    [Bindable("change")]
    [Bindable("textChanged")]

    /**
     *  The text displayed by this component.
     *
     *  @default ""
     */
    public function get text():String
    public function set text(value:String):void 
    
    //----------------------------------
    //  textView
    //----------------------------------

    [SkinPart(required="true")]

    /**
     *  The TextView that must be present
     *  in any skin assigned to this component.
     */
    public var textView:TextView;
 
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Inserts the specified text, replacing the current selection.
     *  The formatting will be the same as if the new text were typed.
     *  The selection will change to be an insertion point
     *  after the inserted text.
     *  If necessary, the text will scroll to ensure
     *  that the insertion point is visible.
     */
    public function insertText(text:String):void

    /**
     *  Appends the specified text at the end.
     *  The formatting will be the same as if the new text were typed.
     *  The selection will change to be an insertion point
     *  after the inserted text.
     *  If necessary, the text will scroll to ensure
     *  that the insertion point is visible.
     */
    public function appendText(text:String):void

    /**
     *  Selects a range of text.
     *  If no parameters are specified, the entire text will be selected.
     */
    public function setSelection(anchorPosition:int = 0, activePosition = int.MAX_VALUE)
}

}

Class TextOperationEvent

package mx.events
{

/**
 *  Represents events that are dispatched when text content
 *  changes due to user operations such as inserting characters,
 *  backspacing, pasting, changing attributes, etc.
 */
public class TextOperationEvent extends Event
{
    //--------------------------------------------------------------------------
    //
    //  Class constants
    //
    //--------------------------------------------------------------------------

    /**
     *  Dispatched before a FlowOperation is applied to edit a TextFlow.
     *  This event is cancelable; if it is canceled,
     *  the FlowOperation is not applied.
     */
    public static const CHANGING:String = "changing";

    /**
     *  Dispatched after a FlowOperation has been applied to edit a TextFlow.
     *  This event is not cancelable.
     */
    public static const CHANGE:String = "change";

    //------------------------------------------------------------------------------
    //
    //  Constructor
    //
    //------------------------------------------------------------------------------

    /**
     *  Constructor.
     *
     *  @param type The event type; indicates the action that caused the event.
     *
     *  @param bubbles Specifies whether the event
     *  can bubble up the display list hierarchy.
     *
     *  @param cancelable Specifies whether the behavior
     *  associated with the event can be prevented.
     *
     *  @param operation Reference to the FlowOperation object
     *  describing the editing operation being performed
     *  on the text by the user.
     */
     public function TextOperationEvent(type:String, bubbles:Boolean = false,
				   cancelable:Boolean = true,
                                        operation:FlowOperation = null)

    //------------------------------------------------------------------------------
    //
    //  Properties
    //
    //------------------------------------------------------------------------------

    //--------------------------------------
    //  operation
    //--------------------------------------

    /**
     *  The FlowOperation being performed by the user.
     */
    public function get operation():FlowOperation
}

}

B Features


None.

Examples and Usage


TextBox

If you simply specify the text, it will be formatted according the text formatting styles found by the usual getStyle() search algorithm. The TextBox will be just large enough to display the specified text.

<TextBox text="Hello, world!"/>

Since text is the default property of a TextBox, you can also specify it like this:

<TextBox>Hello, world!</TextBox>

Since TextBox supports CSS, you can use class selectors and instance styles:

<TextBox styleName="myTextBox" fontSize="12">Hello, world!</TextBox>

If you specify an explicit width or a percentage width, the text will, by default, get wrapped to that width:

<TextBox width="100">Text that will get implicitly wrapped because it is wider than 100 pixels.</TextBox>

You can use newline characters to create explicit line breaks. In this case, the TextBox will be as wide as the longest line.

<TextBox>Text that is explicitly&#10;wrapped onto two lines with a newline character.</TextBox>

Of course, you can specify explicit linebreaks even when using implicit wrapping. If you use neither, all the text will appear in a single, wide line.

If you don't specify a height, the height is calculated to be big enough to display all the text. If you specify an explicit height or a percent height and the text doesn't fit, the glyphs are clipped to the bounds you specify.

TextGraphic

The examples above for TextBox are also valid for TextGraphic, although when you use TextGraphic the default property is content. However, you can go further and use rich text. The most explicit way to do this is to set the content to a TextFlow instance:

<TextGraphic fontSize="12">
    <content>
        <TextFlow color="0x222222">
            <p>
                <span>Hello, </span>
                <span fontWeight="bold">World!</span>
            <p>
        </TextFlow>
    </content>
</TextGraphic>

Since content is the default property of TextGraphic, you can omit it:

<TextGraphic fontSize="12">
    <TextFlow color="0x222222">
        <p>
            <span>Hello, </span>
            <span fontWeight="bold">World!</span>
        <p>
    </TextFlow>
</TextGraphic>

You can also get terser by setting the content to an Array of Strings and FlowElements, such as in this example:

<TextGraphic fontSize="12">Hello, <span fontWeight="bold">world!</span></TextGraphic>

The MXML compiler treats the character data "Hello, " as if it were wrapped in a <String> tag:

<TextGraphic fontSize="12"><String>Hello, </String><span fontWeight="bold">world!</span></TextGraphic>

You can also set the content to a single FlowElement:

<TextGraphic fontSize="12"><span fontWeight="bold">Hello, world!</span></TextGraphic>

or to a single String:

<TextGraphic fontSize="12">Hello, world</TextGraphic>

TextView

The examples for TextBox and TextGraphic are also valid for TextView. But if you use TextView, the text will by default be scrollable, selectable, and editable.

Additional Implementation Details


None.

Prototype Work


None.

Compiler Work


The MXML compiler has already been modified to support "mixed content", and it is being modified to support enhanced font embedding using the new DefineFont4 SWF tag, as required for use with FTE.

Web Tier Compiler Impact


None.

Flex Feature Dependencies


The skins for the Gumbo components will make use of these text primitives.

TextGraphic and TextView depend on the TLF library.

Backwards Compatibility


Syntax changes

None.

Behavior

None.

Warnings/Deprecation

None.

Accessibility


This is nontrivial and under investigation. It should be possible to get a screen reader to read the entire text of these components using Flash Player 10.0. However, reading the selection will require a new API in Flash Player 10.X.

Performance


The goal is to match Halo components, which used TextField, in speed and memory. Achieving this will depend on further optimizations in FTE beyond those in Flash Player 10.

Globalization


The goal is to accept Unicode input in any language, but Flash Player 10.0 doesn't make this possible. (In particular, Arabic and Hebrew input are not possible on the Mac.) This should improve in Flash Player 10.X.

Localization


Compiler Features

None.

Framework Features

None. The Flex code for these components does not throw any RTEs. But TLF needs to be able to hook into Flex's ResourceManager to get localized RTE messages.

Issues and Recommendations


1. Player 10.X needs to reduce the memory footprint of FTE.

2. It would be natural for TLF FlowElements such as paragraphs and spans to support CSS, but TLF is not currently architected for this. There are ongoing discussions with the TLF team regarding this.

3. It would be natural for all FlowElements – not just LinkElements – to support mouse events, but TLF is not currently architected for this. There are ongoing discussions with the TLF team regarding this.

4. Player 10.X needs to support a new accessibility API for conveying the selection from TLF to the Player.

5. Player 10.X needs to support Unicode input with any input system on Windows and Macintosh.

6. We need to make sure that FTE and TLF can support cross-SWF font embedding without using Font.registerFont().

7. Player 10.X should either support countable mouse events (e.g., second mouseDown) or expose the system's doubleclick threshold.

8. Player 10.X should have an API for getting the system's text selection color.

9. The tabStops style is supposed to be a possibly-empty Array of TabStopFormat instances, but it isn't clear how to specify this in CSS syntax.

10. TextView needs to support line-by-line vertical scrolling, including for nonuniform lineheights.

Documentation


None.

QA


TBD


Flex SDK Project
Home
About
Versions
Downloads
Source
Bug Database
Submitting a Patch
Developer Documentation
Forums
License

Pages
Comments

Other Projects
BlazeDS
Cairngorm
Corelib
FlexUnit

More related projects ›
More Adobe projects ›
You must be logged in to comment.

Amazing!

and to think, there was a time when all was was hoping for from vm10 was that the <ul><li> html text rendering was fixed to help with text formatting.

I hardly know where to start. This is so much more than I could of hoped for.

Thank you!

(ps. thats twice now that the 'please type this word graphic thingy' has said fatter!, are you trying to tell me something?)

I'm glad you're excited by what FTE and TCAL make possible. However, I feel duty-bound to point out that TCAL doesn't yet support <ul>, <ol>, or <li> tags. However, the TCAL team hopes to get these in by the time Gumbo ships. Tables will probably have to wait until after Gumbo.

Hi Gordon,

ul,li etc.. so not a problem. It was only the limited set of formatting options we had with Fx3/Fp9 that made me what these to function. Now it really hardly matters. My formatting scope has just become endless! It's all just so much more than I could have hoped for even in my most wishful imaginings.

At least we now have the primitives that will allow us to do just about anything format wise.

I read the first specs of the player 10 text engine and then these documents and I swear to you , my head was in a spin. The amount of functionality I could build on top of the base engine is boggling.

The only problem is I can no longer make that oft repeated phone call to clients informing them just how much extra development time would be required to fulfill some for there text layout demands (with the usual reply from the client being 'ok well cut it back to basics'

OK, I admit it, I'm an Alpha Geek I know, but this really does excite me!

Great work and thanks to the whole team who decided to take this major leap forward.

onwards and upwards people!

cheers
glenn
tinylion development UK

I've just re-read this document, and had to just comment again.

This Rocks!

I'm not sure which is out of date, the source code or this document, but the API description lists that TextView has an editable property, while the actual source code does not list such a property. Should there be an editable property on it?

The source code is evolving to match the spec. There will eventually be an 'editable' property.

Pretty cool, but only thing make me sad is that there's no workaround on around-image while i have to create a custom component on TCAL and FTE, right?

And wiil RTE be updated to leverage these great features~
Anyway you guys did great job. thanks to Adobe

TCAL (now renamed to TLF) doesn't currently support wrapping text aroud images, but this is under consideration and may get implemented before Flex 4 ships.

A Gumbo version of RichTextEditor is not planned for Flex 4. However, with the getSelectionFormat() and setSelectionFormat() APIs, it should be easy to build one by hooking up controls in a toolbar to a TextView.

Great stuff but it's sad to read that tables aren't supported yet

Wouldn't it be possible to trow in (the Flash Player 10.1) a WebKit based HTML component for the time being It would also allow Google to build the next generation of its GMail application

 
Last Modified: 2008-10-28 15:27:58.0
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki.

Company | Online Privacy Policy | Terms of Use | Contact Us | Accessibility | Report Piracy | Permissions & Trademarks

Copyright @ 2008 Adobe Systems Incorporated.
Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.
Search powered by Google