////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package spark.components
{

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Graphics;
import flash.display.Shape;
import flash.geom.Rectangle;
import flash.text.TextFormat;
import flash.text.engine.EastAsianJustifier;
import flash.text.engine.ElementFormat;
import flash.text.engine.FontDescription;
import flash.text.engine.FontLookup;
import flash.text.engine.FontMetrics;
import flash.text.engine.Kerning;
import flash.text.engine.LineJustification;
import flash.text.engine.SpaceJustifier;
import flash.text.engine.TextBaseline;
import flash.text.engine.TextBlock;
import flash.text.engine.TextElement;
import flash.text.engine.TextLine;
import flash.text.engine.TypographicCase;

import flashx.textLayout.compose.ISWFContext;
import flashx.textLayout.compose.TextLineRecycler;
import flashx.textLayout.formats.BaselineShift;
import flashx.textLayout.formats.TLFTypographicCase;

import mx.core.IEmbeddedFontRegistry;
import mx.core.IFlexModuleFactory;
import mx.core.IUIComponent;
import mx.core.Singleton;
import mx.core.mx_internal;

import spark.components.supportClasses.TextBase;
import spark.utils.TextUtil;

use namespace mx_internal;

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

include "../styles/metadata/BasicInheritingTextStyles.as"
include "../styles/metadata/BasicNonInheritingTextStyles.as"

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

[DefaultProperty("text")]

[IconFile("Label.png")]

/**
 *  Label is a low-level UIComponent that can render
 *  one or more lines of uniformly-formatted text.
 *  The text to be displayed is determined by the
 *  <code>text</code> property inherited from TextBase.
 *  The formatting of the text is specified by the element's CSS styles,
 *  such as <code>fontFamily</code> and <code>fontSize</code>.
 *
 *  <p>Label uses of the 
 *  Flash Text Engine (FTE) in Flash Player to provide high-quality
 *  international typography.
 *  Because Label is fast and lightweight, it is especially suitable
 *  for use cases that involve rendering many small pieces of non-interactive
 *  text, such as item renderers and labels in Button skins.</p>
 *
 *  <p>The Spark architecture provides three text "primitives" -- 
 *  Label, RichText, and RichEditableText --
 *  as part of its pay-only-for-what-you-need philosophy.
 *  Label is the fastest and most lightweight,
 *  but is limited in its capabilities: no complex formatting,
 *  no scrolling, no selection, no editing, and no hyperlinks.
 *  RichText and RichEditableText are built on the Text Layout
 *  Framework (TLF) library, rather than on FTE.
 *  RichText adds the ability to render rich HTML-like text
 *  with complex formatting, but is still completely non-interactive.
 *  RichEditableText is the slowest and heaviest,
 *  but can do it all: it supports scrolling with virtualized TextLines,
 *  selection, editing, hyperlinks, and images loaded from URLs.
 *  You should use the fastest one that meets your needs.</p>
 *
 *  <p>The Spark Label control is similar to the MX Label control, mx.controls.Label.
 *  The most important differences are:
 *  <ul>
 *    <li>Spark Label uses FTE, the player's new text engine,
 *        while MX Label uses the TextField class.</li>
 *    <li>Spark Label offers better typography, and better support
 *        for international languages, than MX Label.</li>
 *    <li>Spark Label can display multiple lines, which MX Label cannot.</li>
 *    <li>MX Label can display a limited subset of HTML,
 *        while Spark Label can only display text with uniform formatting.</li>
 *    <li>MX Label can be made selectable, while Spark Label cannot.</li>
 *  </ul></p>
 *
 *  <p>In Spark Label, three character sequences are recognized
 *  as explicit line breaks: CR (<code>"\r"</code>), LF (<code>"\n"</code>),
 *  and CR+LF (<code>"\r\n"</code>).</p>
 *
 *  <p>If you don't specify any kind of width for a Label,
 *  then the longest line, as determined by these explicit line breaks,
 *  determines the width of the Label.</p>
 *
 *  <p>If you do specify some kind of width, then the specified text is
 *  word-wrapped at the right edge of the component's bounds, because the
 *  default value of the <code>lineBreak</code> style is <code>"toFit"</code>.
 *  If the text extends below the bottom of the component,
 *  it is clipped.</p>
 *
 *  <p>To disable this automatic wrapping, set the <code>lineBreak</code>
 *  style to <code>"explicit"</code>. Then lines are broken only where
 *  the <code>text</code> contains an explicit line break,
 *  and the ends of lines extending past the right edge is clipped.</p>
 *
 *  <p>If you have more text than you have room to display it,
 *  Label can truncate the text for you.
 *  Truncating text means replacing excess text
 *  with a truncation indicator such as "...".
 *  See the inherited properties <code>maxDisplayedLines</code>
 *  and <code>isTruncated</code>.</p>
 *
 *  <p>You can control the line spacing with the <code>lineHeight</code> style.
 *  You can horizontally and vertically align the text within the element's
 *  bounds using the <code>textAlign</code>, <code>textAlignLast</code>,
 *  and <code>verticalAlign</code> styles.
 *  You can inset the text from the element's edges using the
 *  <code>paddingLeft</code>, <code>paddingTop</code>, 
 *  <code>paddingRight</code>, and <code>paddingBottom</code> styles.</p>
 *
 *  <p>By default a Label has no background,
 *  but you can draw one using the <code>backgroundColor</code>
 *  and <code>backgroundAlpha</code> styles.
 *  Borders are not supported.
 *  If you need a border, or a more complicated background, use a separate
 *  graphic element, such as a Rect, behind the Label.</p>
 *
 *  <p>Label 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 paragraph.
 *  If the predominant text direction is right-to-left,
 *  set the <code>direction</code> style to <code>"rtl"</code>.
 *  The <code>textAlign</code> style defaults to <code>"start"</code>,
 *  which makes the text left-aligned when <code>direction</code>
 *  is <code>"ltr"</code> and right-aligned when <code>direction</code>
 *  is <code>"rtl"</code>.
 *  To get the opposite alignment,
 *  set <code>textAlign</code> to <code>"end"</code>.</p>
 *
 *  <p>Label uses the TextBlock class in the Flash Text Engine
 *  to create one or more TextLine objects to statically display
 *  its text String in the format determined by its CSS styles.
 *  For performance, its TextLines do not contain information
 *  about individual glyphs; for more info, see
 *  flash.text.engine.TextLineValidity.STATIC.</p>
 *
 *  <p>The Label control has the following default characteristics:</p>
 *  <table class="innertable">
 *     <tr><th>Characteristic</th><th>Description</th></tr>
 *     <tr><td>Default size</td><td>0 pixels wide by 12 pixels high if it contains no text, 
 *        and large enough ti display the text if it does</td></tr>
 *     <tr><td>Minimum size</td><td>0 pixels</td></tr>
 *     <tr><td>Maximum size</td><td>10000 pixels wide and 10000 pixels high</td></tr>
 *  </table>
 *
 *  @mxml <p>The <code>&lt;s:Label&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;s:Label 
 *    <strong>Styles</strong>
 *    alignmentBaseline="baseline"
 *    baselineShift="0"
 *    cffHinting="0.0"
 *    color="0x000000"
 *    digitCase="default"
 *    digitWidth="default"
 *    direction="ltr"
 *    dominantBaseline="auto"
 *    fontFamily="Arial"
 *    fontLookup="embeddedCFF"
 *    fontSize="12"
 *    fontStyle="normal"
 *    fontWeight="normal"
 *    justificationRule="auto"
 *    justificationStyle="auto"
 *    kerning="false"
 *    ligatureLevel="common"
 *    lineBreak="toFit"
 *    lineHeight="120%"
 *    lineThrough="false"
 *    locale="en"
 *    paddingBottom="0"
 *    paddingLeft="0"
 *    paddingRight="0"
 *    paddingTop="0"
 *    renderingMode="cff"
 *    textAlign="start"
 *    textAlignLast="start"
 *    textAlpha="1"
 *    textDecoration="start"
 *    textJustify="interWord"
 *    trackingLeft="0"
 *    trackingRight="00"
 *    typographicCase="default"
 *    verticalAlign="top"
 *  /&gt;
 *  </pre>
 *
 *  @see spark.components.RichEditableText
 *  @see spark.components.RichText
 *  @see flash.text.engine.TextLineValidity#STATIC
 *
 *  @includeExample examples/LabelExample.mxml
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
public class Label extends TextBase
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class initialization
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private static function initClass():void
    {
        staticTextBlock = new TextBlock();
        
        staticTextElement = new TextElement();
        
        staticSpaceJustifier = new SpaceJustifier();
        
        staticEastAsianJustifier = new EastAsianJustifier();
        
        if ("recreateTextLine" in staticTextBlock)
            recreateTextLine = staticTextBlock["recreateTextLine"];
    }
    
    initClass();

    //--------------------------------------------------------------------------
    //
    //  Class variables
    //
    //--------------------------------------------------------------------------
        
    // We can re-use single instances of a few FTE classes over and over,
    // since they just serve as a factory for the TextLines that we care about.
    
    /**
     *  @private
     */
    private static var staticTextBlock:TextBlock;

    /**
     *  @private
     */
    private static var staticTextElement:TextElement;

    /**
     *  @private
     */
    private static var staticSpaceJustifier:SpaceJustifier;

    /**
     *  @private
     */
    private static var staticEastAsianJustifier:EastAsianJustifier;
    
    /**
     *  @private
     *  A reference to the recreateTextLine() method in staticTextBlock,
     *  if it exists. This method was added in player 10.1.
     *  It allows better performance by making it possible to reuse
     *  existing TextLines instead of having to create new ones.
     */
    private static var recreateTextLine:Function;

    //--------------------------------------------------------------------------
    //
    //  Class properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  embeddedFontRegistry
    //----------------------------------

    /**
     *  @private
     *  Storage for the _embeddedFontRegistry property.
     *  Note: This gets initialized on first access,
     *  not when this class is initialized, in order to ensure
     *  that the Singleton registry has already been initialized.
     */
    private static var _embeddedFontRegistry:IEmbeddedFontRegistry;

    /**
     *  @private
     *  A reference to the embedded font registry.
     *  Single registry in the system.
     *  Used to look up the moduleFactory of a font.
     */
    private static function get embeddedFontRegistry():IEmbeddedFontRegistry
    {
        if (!_embeddedFontRegistry)
        {
            _embeddedFontRegistry = IEmbeddedFontRegistry(
                Singleton.getInstance("mx.core::IEmbeddedFontRegistry"));
        }

        return _embeddedFontRegistry;
    }

    //--------------------------------------------------------------------------
    //
    //  Class methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private static function getNumberOrPercentOf(value:Object,
                                                 n:Number):Number
    {
        // If 'value' is a Number like 10.5, return it.
        if (value is Number)
            return Number(value);

        // If 'value' is a percentage String like "10.5%",
        // return that percentage of 'n'.
        if (value is String)
        {
            var len:int = String(value).length;
            if (len >= 1 && value.charAt(len - 1) == "%")
            {
                var percent:Number = Number(value.substring(0, len - 1));
                return percent / 100 * n;
            }
        }

        // Otherwise, return NaN.
        return NaN;
    }

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

    /**
     *  Constructor. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 1.5
     *  @productversion Flex 4
     */
    public function Label()
    {
        super();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Holds the last recorded value of the module factory
     *  used to create the font.
     */
    private var embeddedFontContext:IFlexModuleFactory;
    
    /**
     *  @private
     *  When we render the text using FTE, this object represents the formatting 
     *  for our text element(s). Every time format related styles change, this 
     *  object is released because it is invalid. It is regenerated just in time 
     *  to render the text.
     */
    private var elementFormat:ElementFormat;

    //--------------------------------------------------------------------------
    //
    //  Overidden Methods: ISimpleStyleClient
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override public function stylesInitialized():void
    {
        super.stylesInitialized();
        elementFormat = null;
    }
    
    /**
     *  @private
     */
    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged(styleProp);
        elementFormat = null;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden methods: TextBase
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     *  This helper method is used by measure() and updateDisplayList().
     *  It composes TextLines to render the 'text' String,
     *  using the staticTextBlock as a factory,
     *  and using the 'width' and 'height' parameters to define the size
     *  of the composition rectangle, with NaN meaning "no limit".
     *  It stops composing when the composition rectangle has been filled.
     *  Returns true if all lines were composed, otherwise false.
     */
    override mx_internal function composeTextLines(width:Number = NaN,
                                                   height:Number = NaN):Boolean
    {
        super.composeTextLines(width, height);
        
        if (!elementFormat)
            elementFormat = createElementFormat(); 
            
        // Set the composition bounds to be used by createTextLines().
        // If the width or height is NaN, it will be computed by this method
        // by the time it returns.
        // The bounds are then used by the addTextLines() method
        // to determine the isOverset flag.
        // The composition bounds are also reported by the measure() method.
        bounds.x = 0;
        bounds.y = 0;
        bounds.width = width;
        bounds.height = height;

        // Remove the TextLines from the container and then release them for
        // reuse, if supported by the player.
        removeTextLines();
        releaseTextLines();
        
        // Create the TextLines.
        var allLinesComposed:Boolean = createTextLines(elementFormat);
        
        // Need truncation if all the following are true
        // - there is text (even if there is no text there is may be padding
        //       which may not fit and the text would be reported as truncated)
        // - truncation options exist (0=no trunc, -1=fill up bounds then trunc,
        //      n=n lines then trunc)
        // - compose width is specified
        // - content doesn't fit
        var lb:String = getStyle("lineBreak");
        if (text != null && text.length > 0 &&
            maxDisplayedLines &&
            !doesComposedTextFit(height, width, allLinesComposed, maxDisplayedLines, lb))
        {
            truncateText(width, height, lb);
        }
        
        // Detach the TextLines from the TextBlock that created them.
        releaseLinesFromTextBlock();
                                                       
        // Add the new text lines to the container.
        addTextLines();

        // Figure out if a scroll rect is needed.
        isOverset = isTextOverset(width, height);
        
        // Just recomposed so reset.
        invalidateCompose = false;     
        
        return allLinesComposed;           
    }

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

    /**
     *  @private
     *  Creates an ElementFormat (and its FontDescription)
     *  based on the Label's CSS styles.
     *  These must be recreated each time because FTE
     *  does not allow them to be reused.
     *  As a side effect, this method also sets embeddedFontContext
     *  so that we know which SWF should be used to create TextLines.
     *  (TextLines using an embedded font must be created in the SWF
     *  where the font is.)
     */
    private function createElementFormat():ElementFormat
    {
        // When you databind to a text formatting style on a Label,
        // as in <Label fontFamily="{fontCombo.selectedItem}"/>
        // the databinding can cause the style to be set to null.
        // Setting null values for properties in an FTE FontDescription
        // or ElementFormat throw an error, so the following code does
        // null-checking on the problematic properties.

        var s:String;
        
        // If the CSS styles for this component specify an embedded font,
        // embeddedFontContext will be set to the module factory that
        // should create TextLines (since they must be created in the
        // SWF where the embedded font is.)
        // Otherwise, this will be null.
        embeddedFontContext = getEmbeddedFontContext();

        // Fill out a FontDescription based on the CSS styles.
        
        var fontDescription:FontDescription = new FontDescription();
        
        s = getStyle("cffHinting");
        if (s != null)
            fontDescription.cffHinting = s;
        
        s = getStyle("fontLookup");
        if (s != null)
        {
            // FTE understands only "device" and "embeddedCFF"
            // for fontLookup. But Flex allows this style to be
            // set to "auto", in which case we automatically
            // determine it based on whether the CSS styles
            // specify an embedded font.
            if (s == "auto")
            {
                s = embeddedFontContext ?
                    FontLookup.EMBEDDED_CFF :
                    FontLookup.DEVICE;
            }
            else if (s == FontLookup.EMBEDDED_CFF && !embeddedFontContext)
            {
                // If the embedded font isn't found, fall back to device font,
                // before falling back to the player's default font.
                s = FontLookup.DEVICE;
            }
            fontDescription.fontLookup = s;
        }
        
        s = getStyle("fontFamily");
        if (s != null)
            fontDescription.fontName = s;
        
        s = getStyle("fontStyle");
        if (s != null)
            fontDescription.fontPosture = s;
        
        s = getStyle("fontWeight");
        if (s != null)
            fontDescription.fontWeight = s;
            
        s = getStyle("renderingMode");
        if (s != null)
            fontDescription.renderingMode = s;
        
        // Fill our an ElementFormat based on the CSS styles.
        
        var elementFormat:ElementFormat = new ElementFormat();
        
        // Out of order so it can be used by baselineShift.
        elementFormat.fontSize = getStyle("fontSize");
        
        s = getStyle("alignmentBaseline");
        if (s != null)
            elementFormat.alignmentBaseline = s;
            
        elementFormat.alpha = getStyle("textAlpha");
            
        setBaselineShift(elementFormat);
        
        // Note: Label doesn't support a breakOpportunity style,
        // so we leave elementFormat.breakOpportunity with its
        // default value of "auto".
            
        elementFormat.color = getStyle("color");
        
        s = getStyle("digitCase");
        if (s != null)
            elementFormat.digitCase = s;
            
        s = getStyle("digitWidth");
        if (s != null)
            elementFormat.digitWidth = s;
            
        s = getStyle("dominantBaseline");
        if (s != null)
        {
            // TLF adds the concept of a locale-based "auto" setting for
            // dominantBaseline, so we support that in Label as well
            // so that "auto" can be used in the global selector.
            // TLF's rule is that "auto" means "ideographicCenter"
            // for Japanese and Chinese locales and "roman" for other locales.
            // (See TLF's LocaleUtil, which we avoid linking in here.)
            if (s == "auto")
            {
                s = TextBaseline.ROMAN;
                var locale:String = getStyle("locale");
                if (locale != null)
                {
                    var lowercaseLocale:String = locale.toLowerCase();
                    if (lowercaseLocale.indexOf("ja") == 0 ||
                        lowercaseLocale.indexOf("zh") == 0)
                    {
                        s = TextBaseline.IDEOGRAPHIC_CENTER;
                    }
                }
            }
            elementFormat.dominantBaseline = s;
        }
            
        elementFormat.fontDescription = fontDescription;
        
        setKerning(elementFormat);

        s = getStyle("ligatureLevel");
        if (s != null)
            elementFormat.ligatureLevel = s;
        
        s = getStyle("locale");
        if (s != null)
            elementFormat.locale = s;
        
        setTracking(elementFormat);

        setTypographicCase(elementFormat);
        
        return elementFormat;
    }

    /**
     *  @private
     */
    private function setBaselineShift(elementFormat:ElementFormat):void
    {
        var baselineShift:* = getStyle("baselineShift");
        var fontSize:Number = elementFormat.fontSize;
        
        if (baselineShift == BaselineShift.SUPERSCRIPT || 
            baselineShift == BaselineShift.SUBSCRIPT)
        {
            var fontMetrics:FontMetrics;
            if (embeddedFontContext)
                fontMetrics = embeddedFontContext.callInContext(elementFormat.getFontMetrics, elementFormat, null);
            else
                fontMetrics = elementFormat.getFontMetrics();
            if (baselineShift == BaselineShift.SUPERSCRIPT)
            {
                elementFormat.baselineShift = 
                    fontMetrics.superscriptOffset * fontSize;
                elementFormat.fontSize = fontMetrics.superscriptScale * fontSize;
            }
            else // it's subscript
            {
                elementFormat.baselineShift = 
                    fontMetrics.subscriptOffset * fontSize;
                elementFormat.fontSize = fontMetrics.subscriptScale * fontSize;
            }
        }			
        else
        {
            // TLF will throw a range error if percentage not between
            // -1000% and 1000%.  Label does not.
            baselineShift = 
                getNumberOrPercentOf(baselineShift, fontSize);
            if (!isNaN(baselineShift))
                elementFormat.baselineShift = -baselineShift;
                    // Note: The negative sign is because, as in TLF,
                    // we want a positive number to shift the baseline up,
                    // whereas FTE does it the opposite way.
                    // In FTE, a positive baselineShift increases
                    // the y coordinate of the baseline, which is
                    // mathematically appropriate, but unintuitive.    
        }
    }
    
    /**
     *  @private
     */
    private function setKerning(elementFormat:ElementFormat):void
    {
        var kerning:Object = getStyle("kerning");
        
        // In Halo components based on TextField,
        // kerning is supposed to be true or false.
        // The default in TextField and Flex 3 is false
        // because kerning doesn't work for device fonts
        // and is slow for embedded fonts.
        // In Spark components based on TLF and FTE,
        // kerning is "auto", "on", or, "off".
        // The default in TLF and FTE is "auto"
        // (which means kern non-Asian characters)
        // because kerning works even on device fonts
        // and has miminal performance impact.
        // Since a CSS selector or parent container
        // can affect both Halo and Spark components,
        // we need to map true to "on" and false to "off"
        // here and in Label.
        // For Halo components, UITextField and UIFTETextField
        // do the opposite mapping
        // of "auto" and "on" to true and "off" to false.
        // We also support a value of "default"
        // (which we set in the global selector)
        // to mean "auto" for Spark and false for Halo
        // to get the recommended behavior in both sets of components.
        if (kerning === "default")
            kerning = Kerning.AUTO;
        else if (kerning === true)
            kerning = Kerning.ON;
        else if (kerning === false)
            kerning = Kerning.OFF;
        
        if (kerning != null)
           elementFormat.kerning = String(kerning);
    }

    /**
     *  @private
     */
    private function setTracking(elementFormat:ElementFormat):void
    {
        var trackingLeft:Object = getStyle("trackingLeft");
        var trackingRight:Object = getStyle("trackingRight");
        
        var value:Number;
        var fontSize:Number = elementFormat.fontSize;
       
        value = getNumberOrPercentOf(trackingLeft, fontSize);
        if (!isNaN(value))
            elementFormat.trackingLeft = value;

        value = getNumberOrPercentOf(trackingRight, fontSize);
        if (!isNaN(value))
            elementFormat.trackingRight = value;
    }

    /**
     *  @private
     */
    private function setTypographicCase(elementFormat:ElementFormat):void
    {
        var s:String = getStyle("typographicCase");
        if (s != null)
        {
            switch (s)
            {
                case TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS:
                {
                    elementFormat.typographicCase = 
                        TypographicCase.CAPS_AND_SMALL_CAPS;
                    break;
                }
                case TLFTypographicCase.CAPS_TO_SMALL_CAPS:
                {
                    elementFormat.typographicCase = TypographicCase.SMALL_CAPS;
                    break;
                }
                default:
                {
                    // Others map directly so handle it in the default case.
                    elementFormat.typographicCase = s;
                    break;
                }
            }
        }        
    }

    
    /**
     *  @private
     *  Stuffs the specified text and formatting info into a TextBlock
     *  and uses it to create as many TextLines as fit into the bounds.
     *  Returns true if all the text was composed into textLines.
     */
    private function createTextLines(elementFormat:ElementFormat):Boolean
    {
        // Get CSS styles that affect a TextBlock and its justifier.
        var direction:String = getStyle("direction");
        var justificationRule:String = getStyle("justificationRule");
        var justificationStyle:String = getStyle("justificationStyle");
        var textAlign:String = getStyle("textAlign");
        var textAlignLast:String = getStyle("textAlignLast");
        var textJustify:String = getStyle("textJustify");

        // TLF adds the concept of a locale-based "auto" setting for
        // justificationRule and justificationStyle, so we support
        // that in Label as well so that "auto" can be used
        // in the global selector.
        // TLF's rule is that "auto" for justificationRule means "eastAsian"
        // for Japanese and Chinese locales and "space" for other locales,
        // and that "auto" for justificationStyle (which only affects
        // the EastAsianJustifier) always means "pushInKinsoku".
        // (See TLF's LocaleUtil, which we avoid linking in here.)
        if (justificationRule == "auto")
        {
            justificationRule = "space";
            var locale:String = getStyle("locale");
            if (locale != null)
            {
                var lowercaseLocale:String = locale.toLowerCase();
                if (lowercaseLocale.indexOf("ja") == 0 ||
                    lowercaseLocale.indexOf("zh") == 0)
                {
                    justificationRule = "eastAsian";
                }
            }
        }
        if (justificationStyle == "auto")
            justificationStyle = "pushInKinsoku";

        // Set the TextBlock's content.
        // Note: If there is no text, we do what TLF does and compose
        // a paragraph terminator character, so that a TextLine
        // gets created and we can measure it.
        // It will have a width of 0 but a height equal
        // to the font's ascent plus descent.
        staticTextElement.text = text != null && text.length > 0 ? text : "\u2029";
        staticTextElement.elementFormat = elementFormat;
        staticTextBlock.content = staticTextElement;

        // And its bidiLevel.
        staticTextBlock.bidiLevel = direction == "ltr" ? 0 : 1;

        // And its justifier.
        var lineJustification:String;
        if (textAlign == "justify")
        {
            lineJustification = textAlignLast == "justify" ?
                                LineJustification.ALL_INCLUDING_LAST :
                                LineJustification.ALL_BUT_LAST;
        }
        else
        {
            lineJustification = LineJustification.UNJUSTIFIED;
        }
        if (justificationRule == "space")
        {
            staticSpaceJustifier.lineJustification = lineJustification;
            staticSpaceJustifier.letterSpacing = textJustify == "distribute";
            staticTextBlock.textJustifier = staticSpaceJustifier;
        }
        else
        {
            staticEastAsianJustifier.lineJustification = lineJustification;
            staticEastAsianJustifier.justificationStyle = justificationStyle;
            
            staticTextBlock.textJustifier = staticEastAsianJustifier;
        }
                
        // Then create TextLines using this TextBlock.
        return createTextLinesFromTextBlock(staticTextBlock, textLines, bounds);
    }

    /**
     *  @private
     *  Compose into textLines.  bounds on input is size of composition
     *  area and on output is the size of the composed content.
     *  The caller must call releaseLinesFromTextBlock() to release the
     *  textLines from the TextBlock.  This must be done after truncation
     *  so that the composed lines can be broken into atoms to figure out
     *  where the truncation indicator should be placed.
     * 
     *  Returns true if all the text was composed into textLines.
     */
    private function createTextLinesFromTextBlock(textBlock:TextBlock,
                                                  textLines:Vector.<DisplayObject>,
                                                  bounds:Rectangle):Boolean
    {
        // Start with 0 text lines.
        releaseTextLines(textLines);
           
        // Get CSS styles for formats that we have to apply ourselves.
        var direction:String = getStyle("direction");
        var lineBreak:String = getStyle("lineBreak");
        var lineHeight:Object = getStyle("lineHeight");
        var lineThrough:Boolean = getStyle("lineThrough");
        var paddingBottom:Number = getStyle("paddingBottom");
        var paddingLeft:Number = getStyle("paddingLeft");
        var paddingRight:Number = getStyle("paddingRight");
        var paddingTop:Number = getStyle("paddingTop");
        var textAlign:String = getStyle("textAlign");
        var textAlignLast:String = getStyle("textAlignLast");
        var textDecoration:String = getStyle("textDecoration");
        var verticalAlign:String = getStyle("verticalAlign");

        var innerWidth:Number = bounds.width - paddingLeft - paddingRight;
        var innerHeight:Number = bounds.height - paddingTop - paddingBottom;
                
        var measureWidth:Boolean = isNaN(innerWidth);
        if (measureWidth)
            innerWidth = maxWidth;
        
        var maxLineWidth:Number = lineBreak == "explicit" ?
                                  TextLine.MAX_LINE_WIDTH :
                                  innerWidth;
        
        if (innerWidth < 0 || innerHeight < 0 || !textBlock)
        {
            bounds.width = 0;
            bounds.height = 0;
            return false;
        }

        var fontSize:Number = staticTextElement.elementFormat.fontSize;
        var actualLineHeight:Number;
        if (lineHeight is Number)
        {
            actualLineHeight = Number(lineHeight);
        }
        else if (lineHeight is String)
        {
            var len:int = lineHeight.length;
            var percent:Number =
                Number(String(lineHeight).substring(0, len - 1));
            actualLineHeight = percent / 100 * fontSize;
        }
        if (isNaN(actualLineHeight))
            actualLineHeight = 1.2 * fontSize;
        
        var maxTextWidth:Number = 0;
        var totalTextHeight:Number = 0;
        var n:int = 0;
        var nextTextLine:TextLine;
        var nextY:Number = 0;
        var textLine:TextLine;
        
        var swfContext:ISWFContext = ISWFContext(embeddedFontContext);
                    
        // For truncation, need to know if all lines have been composed.
        var createdAllLines:Boolean = false;
        // sometimes we need to create an extra line in order to compute
        // truncation
        var extraLine:Boolean;
        
        // Generate TextLines, stopping when we run out of text
        // or reach the bottom of the requested bounds.
        // In this loop the lines are positioned within the rectangle
        // (0, 0, innerWidth, innerHeight), with top-left alignment.
        while (true)
        {
            var recycleLine:TextLine = TextLineRecycler.getLineForReuse();
            if (recycleLine)
            {
                if (swfContext)
                {
                    nextTextLine = swfContext.callInContext(
                        textBlock["recreateTextLine"], textBlock,
                        [ recycleLine, textLine, maxLineWidth ]);       
                }        
                else
                {
                    nextTextLine = recreateTextLine(
                        recycleLine, textLine, maxLineWidth);
                }  
            }
            else
            {
                if (swfContext)
                {
                    nextTextLine = swfContext.callInContext(
                        textBlock.createTextLine, textBlock,
                        [ textLine, maxLineWidth ]);
                }
                else
                {
                    nextTextLine = textBlock.createTextLine(
                        textLine, maxLineWidth);
                }
            }
            
            if (!nextTextLine)
            {
                createdAllLines = !extraLine;
                break;
            }
            
            // Determine the natural baseline position for this line.
            // Note: The y coordinate of a TextLine is the location
            // of its baseline, not of its top.
            nextY += (n == 0 ? nextTextLine.ascent : actualLineHeight);
            
            // If verticalAlign is top and the next line is completely outside 
            // the rectangle, we're done.  If verticalAlign is middle or bottom
            // then we need to compose all the lines so the alignment is done
            // correctly.
            if (verticalAlign == "top" && 
                nextY - nextTextLine.ascent > innerHeight)
            {
                // make an extra line so we can compute truncation
                if (!extraLine) 
                    extraLine = true;
                else
                    break;
            }

            // We'll keep this line. Put it into the textLines array.
            textLine = nextTextLine;
            textLines[n++] = textLine;

            // Assign its location based on left/top alignment.
            // Its x position is 0 by default.
            textLine.y = nextY;
            
            // Keep track of the maximum textWidth 
            // and the accumulated textHeight of the TextLines.
            maxTextWidth = Math.max(maxTextWidth, textLine.textWidth);
            totalTextHeight += textLine.textHeight;

            if (lineThrough || textDecoration == "underline")
            {
                // FTE doesn't render strikethroughs or underlines,
                // but it can tell us where to draw them.
                // You can't draw in a TextLine but it can have children,
                // so we create a child Shape to draw them in.
                
                var elementFormat:ElementFormat =
                    TextElement(textBlock.content).elementFormat;
                var fontMetrics:FontMetrics;
                if (embeddedFontContext)
                    fontMetrics = embeddedFontContext.callInContext(elementFormat.getFontMetrics, elementFormat, null);
                else
                    fontMetrics = elementFormat.getFontMetrics();
                
                var shape:Shape = new Shape();
                var g:Graphics = shape.graphics;
                if (lineThrough)
                {
                    g.lineStyle(fontMetrics.strikethroughThickness, 
                                elementFormat.color, elementFormat.alpha);
                    g.moveTo(0, fontMetrics.strikethroughOffset);
                    g.lineTo(textLine.textWidth, fontMetrics.strikethroughOffset);
                }
                if (textDecoration == "underline")
                {
                    g.lineStyle(fontMetrics.underlineThickness, 
                                elementFormat.color, elementFormat.alpha);
                    g.moveTo(0, fontMetrics.underlineOffset);
                    g.lineTo(textLine.textWidth, fontMetrics.underlineOffset);
                }
                
                textLine.addChild(shape);
            }
        }

        // At this point, n is the number of lines that fit
        // and textLine is the last line that fit.

        if (n == 0)
        {
            bounds.width = paddingLeft + paddingRight;
            bounds.height = paddingTop + paddingBottom;
            return false;
        }
        
        // If not measuring the width, innerWidth remains the same since 
        // alignment is done over the innerWidth not over the width of the
        // text that was just composed.
        if (measureWidth)
            innerWidth = maxTextWidth;

        if (isNaN(bounds.height))
            innerHeight = textLine.y + textLine.descent;
        
        // Ensure we snap for consistent results.
        innerWidth = Math.ceil(innerWidth);
        innerHeight = Math.ceil(innerHeight);
        
        var leftAligned:Boolean = 
            textAlign == "start" && direction == "ltr" ||
            textAlign == "end" && direction == "rtl" ||
            textAlign == "left" ||
            textAlign == "justify";
        var centerAligned:Boolean = textAlign == "center";
        var rightAligned:Boolean =
            textAlign == "start" && direction == "rtl" ||
            textAlign == "end" && direction == "ltr" ||
            textAlign == "right"; 

        // Calculate loop constants for horizontal alignment.
        var leftOffset:Number = bounds.left + paddingLeft;
        var centerOffset:Number = leftOffset + innerWidth / 2;
        var rightOffset:Number =  leftOffset + innerWidth;
        
        // Calculate loop constants for vertical alignment.
        var topOffset:Number = bounds.top + paddingTop;
        var bottomOffset:Number = innerHeight - (textLine.y + textLine.descent);
        var middleOffset:Number = bottomOffset / 2;
        bottomOffset += topOffset;
        middleOffset += topOffset;
        var leading:Number = (innerHeight - totalTextHeight) / (n - 1);
        
        var previousTextLine:TextLine;
        var y:Number = 0;

        var lastLineIsSpecial:Boolean =
            textAlign == "justify" && createdAllLines;

        var minX:Number = innerWidth;
        var minY:Number = innerHeight;
        var maxX:Number = 0;
        
        var clipping:Boolean = (n) ? (textLines[n - 1].y + TextLine(textLines[n - 1]).descent > innerHeight) : false;

        // Reposition each line if necessary.
        // based on the horizontal and vertical alignment.
        for (var i:int = 0; i < n; i++)
        {
            textLine = TextLine(textLines[i]);

            // If textAlign is "justify" and there is more than one line,
            // the last one (if we created it) gets horizontal aligned
            // according to textAlignLast.
            if (lastLineIsSpecial && i == n - 1)
            {
                leftAligned = 
                    textAlignLast == "start" && direction == "ltr" ||
                    textAlignLast == "end" && direction == "rtl" ||
                    textAlignLast == "left" ||
                    textAlignLast == "justify";
                centerAligned = textAlignLast == "center";
                rightAligned =
                    textAlignLast == "start" && direction == "rtl" ||
                    textAlignLast == "end" && direction == "ltr" ||
                    textAlignLast == "right";
            } 

            if (leftAligned)
                textLine.x = leftOffset;
            else if (centerAligned)
                textLine.x = centerOffset - textLine.textWidth / 2;
            else if (rightAligned)
                textLine.x = rightOffset - textLine.textWidth;            
            
            if (verticalAlign == "top" || !createdAllLines || clipping)
            {
                textLine.y += topOffset;
            }
            else if (verticalAlign == "middle")
            {
                textLine.y += middleOffset;
            }
            else if (verticalAlign == "bottom")
            {
                textLine.y += bottomOffset;
            }
            else if (verticalAlign == "justify")
            {
                // Determine the natural baseline position for this line.
                // Note: The y coordinate of a TextLine is the location
                // of its baseline, not of its top.
                y += i == 0 ?
                     topOffset + textLine.ascent :
                     previousTextLine.descent + leading + textLine.ascent;
            
                textLine.y = y;
                previousTextLine = textLine;
            }

            // Upper left corner of bounding box may not be 0,0 after
            // styles are applied or rounding error from minY calculation.
            // y is one decimal place and ascent isn't rounded so minY can be 
            // slightly less than zero. 
            minX = Math.min(minX, textLine.x);             
            minY = Math.min(minY, textLine.y - textLine.ascent);
            maxX = Math.max(maxX, textLine.x + textLine.textWidth); 
        }

        bounds.x = minX - paddingLeft;
        bounds.y = minY - paddingTop;
        bounds.right = maxX + paddingRight;
        bounds.bottom = textLine.y + textLine.descent + paddingBottom;
        
        return createdAllLines;
    }
 
    /**
     *  @private
     *  Create textLine using paragraph terminator "\u2029" so it creates one
     *  text line that we can use to get the baseline.  The height is 
     *  important if the text is vertically aligned.
     */ 
    override mx_internal function createEmptyTextLine(height:Number=NaN):void
    {
        staticTextElement.text = "\u2029";
        
        bounds.width = NaN;
        bounds.height = height;
        
        createTextLinesFromTextBlock(staticTextBlock, textLines, bounds);
        
        releaseLinesFromTextBlock();
    }
    
    /**
     *  @private
     *  Determines if the composed text fits in the given height and 
     *  line count limit. 
     */ 
    private function doesComposedTextFit(height:Number, width:Number,
                                         createdAllLines:Boolean,
                                         lineCountLimit:int, lineBreak:String):Boolean
    {
        // Not all text composed because it didn't fit within bounds.
        if (!createdAllLines)
            return false;
                    
        // More text lines than allowed lines.                    
        if (lineCountLimit != -1 && textLines.length > lineCountLimit)
            return false;
        
        if (lineBreak == "explicit")
        {
            // if explicit, if the right edge of any lines go outside the
            // desired width
            if (bounds.right > width)
                return false;
        }

        // No lines or one line or no height restriction.  We don't truncate away
        // the one and only line just because height is too small.  Clipping
        // will take care of it later
        if (textLines.length <= 1 || isNaN(height))
            return true;
                                             
        // Does the bottom of the last line fall within the bounds?                                                    
        var lastLine:TextLine = TextLine(textLines[textLines.length - 1]);        
        var lastLineExtent:Number = lastLine.y + lastLine.descent;
        
        return lastLineExtent <= height;
    }

    /**
     *  @private
     *  width and height are the ones used to do the compose, not the measured
     *  results resulting from the compose.
     * 
     *  Adapted from justification code in TLF's
     *  TextLineFactory.textLinesFromString().
     */
    private function truncateText(width:Number, height:Number, lineBreak:String):void
    {
        var lineCountLimit:int = maxDisplayedLines;
        var somethingFit:Boolean = false;
        var truncLineIndex:int = 0;    

        if (lineBreak == "explicit")
        {
            truncateExplicitLineBreakText(width, height);
            return;
        }

        // Compute the truncation line.
        truncLineIndex = computeLastAllowedLineIndex(height, lineCountLimit);
        
        // Add extra line in case we wordwrapped some characters
        // onto extra lines.  If we truncate in the middle of the last word
        // it may then fit on the line above.
        var extraLine:Boolean;
        if (truncLineIndex + 1 < textLines.length)
        {
            truncLineIndex++;
            extraLine = true;
        }
                                             
        if (truncLineIndex >= 0)
        {
            // Estimate the initial truncation position using the following 
            // steps. 
            
            // 1. Measure the space that the truncation indicator will take
            // by composing the truncation resource using the same bounds
            // and formats.  The measured indicator lines could be cached but
            // as well as being dependent on the indicator string, they are 
            // dependent on the given width.            
            staticTextElement.text = truncationIndicatorResource;
            var indicatorLines:Vector.<DisplayObject> =
                new Vector.<DisplayObject>();
            var indicatorBounds:Rectangle = new Rectangle(0, 0, width, NaN);
    
            var indicatorFits:Boolean = createTextLinesFromTextBlock(staticTextBlock, 
                                                                     indicatorLines, 
                                                                     indicatorBounds);
                                               
            releaseLinesFromTextBlock();
                                                                                                         
            // 2. Move target line for truncation higher by as many lines 
            // as the number of full lines taken by the truncation 
            // indicator. Indicator should also be able to fit.
            truncLineIndex -= (indicatorLines.length - 1);
            if (truncLineIndex >= 0 && indicatorFits)
            {
                // 3. Calculate allowed width (width left over from the 
                // last line of the truncation indicator).
                var measuredTextLine:TextLine = 
                    TextLine(indicatorLines[indicatorLines.length - 1]);      
                var allowedWidth:Number = 
                    measuredTextLine.specifiedWidth -
                    measuredTextLine.unjustifiedTextWidth;                          
                                        
                measuredTextLine = null;                                        
                releaseTextLines(indicatorLines);
                                                        
                // 4. Get the initial truncation position on the target 
                // line given this allowed width. 
                var truncateAtCharPosition:int = getTruncationPosition(
                    TextLine(textLines[truncLineIndex]), allowedWidth, extraLine);

                // The following loop executes repeatedly composing text until 
                // it fits.  In each iteration, an atoms's worth of characters 
                // of original content is dropped
                do
                {
                    // Replace all content starting at the inital truncation 
                    // position with the truncation indicator.
                    var truncText:String = text.slice(0, truncateAtCharPosition) +
                                           truncationIndicatorResource;

                    // (Re)-initialize bounds for next compose.
                    bounds.x = 0;
                    bounds.y = 0;
                    bounds.width = width;
                    bounds.height = height;
                                                                                    
                    staticTextElement.text = truncText;
                    
                    var createdAllLines:Boolean = createTextLinesFromTextBlock(
                        staticTextBlock, textLines, bounds);
        
                    if (doesComposedTextFit(height, width,
                                            createdAllLines, 
                                            lineCountLimit, lineBreak))

                    {
                        somethingFit = true;
                        break; 
                    }       
                    
                     // No original content left to make room for 
                     // truncation indicator.
                    if (truncateAtCharPosition == 0)
                        break;
                    
                    // sometimes the player decides there isn't enough
                    // room to render anything so bail
                    if (textLines.length == 0)
                        break;
                    
                    // Try again by truncating at the beginning of the 
                    // preceding atom.
                    var oldCharPosition:int = truncateAtCharPosition;
                    truncateAtCharPosition = getNextTruncationPosition(
                        truncLineIndex, truncateAtCharPosition);  
                    // check to see if we've run out of chars
                    if (oldCharPosition == truncateAtCharPosition)
                        break;
                }
                while (true);
            }
        }

        // If nothing fit, return no lines and bounds that just contains
        // padding.
        if (!somethingFit)
        {
            releaseTextLines();

            var paddingBottom:Number = getStyle("paddingBottom");
            var paddingLeft:Number = getStyle("paddingLeft");
            var paddingRight:Number = getStyle("paddingRight");
            var paddingTop:Number = getStyle("paddingTop");
            
            bounds.x = 0;
            bounds.y = 0;
            bounds.width = paddingLeft + paddingRight;
            bounds.height = paddingTop + paddingBottom;
        }
        
        // The text was truncated.
        setIsTruncated(true);
    }
        
    /**
     *  @private
     *  width and height are the ones used to do the compose, not the measured
     *  results resulting from the compose.
     */
    private function truncateExplicitLineBreakText(width:Number, height:Number):void
    {
        // 1. Measure the space that the truncation indicator will take
        // by composing the truncation resource using the same bounds
        // and formats.  The measured indicator lines could be cached but
        // as well as being dependent on the indicator string, they are 
        // dependent on the given width.            
        staticTextElement.text = truncationIndicatorResource;
        var indicatorLines:Vector.<DisplayObject> =
            new Vector.<DisplayObject>();
        var indicatorBounds:Rectangle = new Rectangle(0, 0, width, NaN);

        createTextLinesFromTextBlock(staticTextBlock, 
                                     indicatorLines, 
                                     indicatorBounds);
                                           
        releaseLinesFromTextBlock();

        // check each line to see if it needs truncation
        var n:int = textLines.length;
        for (var i:int = 0; i < n; i++)
        {
            var line:TextLine = textLines[i] as TextLine;
            // if the line is wider than bounds or off the left side
            // TODO (aharui): What if text runs off left side because of
            // alignment or direction?
            if ((line.x + line.width) > width)
            {
                // clip this line
                var lineLength:int = line.rawTextLength;
                // start chopping from the end until it fits
                while (--lineLength > 0)
                {
                    var lineStr:String = text.substr(line.textBlockBeginIndex, lineLength);
                    lineStr += truncationIndicatorResource;
                    staticTextElement.text = lineStr;
                    var clippedLines:Vector.<DisplayObject> =
                        new Vector.<DisplayObject>();

                    createTextLinesFromTextBlock(staticTextBlock, 
                                                 clippedLines, 
                                                 indicatorBounds);
                                           
                    releaseLinesFromTextBlock();
                    if (clippedLines.length == 1 && 
                        (clippedLines[0].x + clippedLines[0].width) <= width)
                    {
                        // replace with the clipped line
                        clippedLines[0].x = line.x;
                        clippedLines[0].y = line.y;
                        textLines[i] = clippedLines[0];
                        break;
                    }
                    
                }
            }
        }
    }

    /** 
     *  @private
     *  Calculates the last line that fits in the given height and line count 
     *  limit.
     */
    private function computeLastAllowedLineIndex(height:Number,
                                                 lineCountLimit:int):int
    {           
        var truncationLineIndex:int = textLines.length - 1;
        // return -1 if no textLines (usually because zero size)
        if (truncationLineIndex < 0)
            return truncationLineIndex;
        
        if (!isNaN(height))
        {
            // Search in reverse order since truncation near the end is the 
            // more common use case.
            do
            {
                var textLine:TextLine = TextLine(textLines[truncationLineIndex]);
                if (textLine.y + textLine.descent <= height)
                    break;
                                
                truncationLineIndex--;
            }
            while (truncationLineIndex >= 0);
        }   
    
        // if line count limit is smaller, use that
        if (lineCountLimit != -1 && lineCountLimit <= truncationLineIndex)
            truncationLineIndex = lineCountLimit - 1;            
            
        return truncationLineIndex;            
    }

    /** 
     *  @private
     *  Gets the initial truncation position on a line.
     * 
     *  If there is an extra line, start at the first word boundary since
     *  truncating characters in this word may make it fit on the line above.
     * 
     *  If there is not an extra line, start at the allowed width.
     * 
     *  - Must be at an atom boundary.
     *  - Must scan the line for atoms in logical order, not physical position 
     *    order.
     *  For example, given bi-di text ABאבCD
     *  atoms must be scanned in this order: 
     *  A, B, א
     *  ג, C, D  
     */
    private function getTruncationPosition(line:TextLine, 
                                           allowedWidth:Number, 
                                           extraLine:Boolean):int
    {           
        var consumedWidth:Number = 0;
        var charPosition:int = line.textBlockBeginIndex;
        
        while (charPosition < line.textBlockBeginIndex + line.rawTextLength)
        {
            var atomIndex:int = line.getAtomIndexAtCharIndex(charPosition);
            if (extraLine)
            {
                // Skip the initial word boundary.
                if (charPosition != line.textBlockBeginIndex &&
                    line.getAtomWordBoundaryOnLeft(atomIndex))
                {
                    break;
                }
            }
            else
            {
                var atomBounds:Rectangle = line.getAtomBounds(atomIndex); 
                consumedWidth += atomBounds.width;
                if (consumedWidth > allowedWidth)
                    break;
            }

            charPosition = line.getAtomTextBlockEndIndex(atomIndex);
        }
                
        return charPosition;
    }
        
    /** 
     *  @private
     *  Gets the next truncation position by shedding an atom's worth of 
     *  characters.
     */
    private function getNextTruncationPosition(truncationLineIndex:int,
                                               truncateAtCharPosition:int):int
    {
        // 1. Get the position of the last character of the preceding atom
        // truncateAtCharPosition-1, because truncateAtCharPosition is an 
        // atom boundary.
        truncateAtCharPosition--; 
        
        // 2. Find the new target line (i.e., the line that has the new 
        // truncation position).  If the last truncation position was at the 
        // beginning of the target line, the new position may have moved to a 
        // previous line.  It is also possible for this position to be found 
        // in the next line because the truncation indicator may have combined 
        // with original content to form a word that may not have afforded a 
        // suitable break opportunity.  In any case, the new truncation 
        // position lies in the vicinity of the previous target line, so a 
        // linear search suffices.
        var line:TextLine = TextLine(textLines[truncationLineIndex]);
        do
        {
            if (truncateAtCharPosition >= line.textBlockBeginIndex && 
                truncateAtCharPosition < line.textBlockBeginIndex + line.rawTextLength)
            {
                break;
            }
            
            if (truncateAtCharPosition < line.textBlockBeginIndex)
            {
                truncationLineIndex--;
                // if we run out of chars, just return the same
                // position to warn the caller to stop
                if (truncationLineIndex < 0)
                    return truncateAtCharPosition;
            }
            else
            {
                truncationLineIndex++;
                // if we run out of chars, just return the same
                // position to warn the caller to stop
                if (truncationLineIndex >= textLines.length)
                    return truncateAtCharPosition;
            }
                
            line = TextLine(textLines[truncationLineIndex]);
        }
        while (true);

        // 3. Get the line atom index at this position          
        var atomIndex:int = 
                        line.getAtomIndexAtCharIndex(truncateAtCharPosition);
        
        // 4. Get the char index for this atom index
        var nextTruncationPosition:int = 
                        line.getAtomTextBlockBeginIndex(atomIndex);
                
        return nextTruncationPosition;
    }
    
    /**
     *  @private
     *  Cleans up and sets the validity of the lines associated 
     *  with the TextBlock to TextLineValidity.INVALID.
     */
    private function releaseLinesFromTextBlock():void
    {
        var firstLine:TextLine = staticTextBlock.firstLine;
        var lastLine:TextLine = staticTextBlock.lastLine;
        
        if (firstLine)
            staticTextBlock.releaseLines(firstLine, lastLine);        
     }
}

}
