////////////////////////////////////////////////////////////////////////////////
//
//  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 flashx.textLayout.formats
{
    /**
     * This interface provides read access to FlowElements-related properties.
     * 
     * @playerversion Flash 10
     * @playerversion AIR 1.5
     * @langversion 3.0
     */
    public interface ITextLayoutFormat
    {
        /**
         * Return the value of the style specified by the <code>styleProp</code> parameter
         * which specifies the style name.
         * 
         * @param styleProp The name of the style whose value is to be retrieved.
         * @return The value of the specified style.  The type varies depending on the type of the style being
         * accessed.  Returns <code>undefined</code> if the style is not set.
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function getStyle(styleName:String):*;
        /**
         * Color of the text. A hexadecimal number that specifies three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green. 
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get color():*;

        /**
         * Background color of the text (adopts default value if undefined during cascade). Can be either the constant value  <code>BackgroundColor.TRANSPARENT</code>, or a hexadecimal value that specifies the three 8-bit RGB (red, green, blue) values; for example, 0xFF0000 is red and 0x00FF00 is green.
         * <p>Legal values as a string are BackgroundColor.TRANSPARENT, FormatValue.INHERIT and uints from 0x0 to 0xffffffff.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of BackgroundColor.TRANSPARENT.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.BackgroundColor
         */
        function get backgroundColor():*;

        /**
         * If <code>true</code>, applies strikethrough, a line drawn through the middle of the text.
         * <p>Legal values are true, false and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of false.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get lineThrough():*;

        /**
         * Alpha (transparency) value for the text. A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with <code>textAlpha</code> set to 0 are active, even though they are invisible.
         * <p>Legal values are numbers from 0 to 1 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 1.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get textAlpha():*;

        /**
         * Alpha (transparency) value for the background (adopts default value if undefined during cascade). A value of 0 is fully transparent, and a value of 1 is fully opaque. Display objects with alpha set to 0 are active, even though they are invisible.
         * <p>Legal values are numbers from 0 to 1 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of 1.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get backgroundAlpha():*;

        /**
         * The size of the text in pixels.
         * <p>Legal values are numbers from 1 to 720 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 12.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get fontSize():*;

        /**
         * Amount to shift the baseline from the <code>dominantBaseline</code> value. Units are in pixels, or a percentage of <code>fontSize</code> (in which case, enter a string value, like 140%).  Positive values shift the line up for horizontal text (right for vertical) and negative values shift it down for horizontal (left for vertical). 
         * <p>Legal values are BaselineShift.SUPERSCRIPT, BaselineShift.SUBSCRIPT, FormatValue.INHERIT.</p>
         * <p>Legal values as a number are from -1000 to 1000.</p>
         * <p>Legal values as a percent are numbers from -1000 to 1000.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.BaselineShift
         */
        function get baselineShift():*;

        /**
         * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the left of each character. If kerning is enabled, the <code>trackingLeft</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingLeft</code> value is used as a manual kerning value. Supports both positive and negative values. 
         * <p>Legal values as a number are from -1000 to 1000.</p>
         * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get trackingLeft():*;

        /**
         * Number in pixels (or percent of <code>fontSize</code>, like 120%) indicating the amount of tracking (manual kerning) to be applied to the right of each character.  If kerning is enabled, the <code>trackingRight</code> value is added to the values in the kerning table for the font. If kerning is disabled, the <code>trackingRight</code> value is used as a manual kerning value. Supports both positive and negative values. 
         * <p>Legal values as a number are from -1000 to 1000.</p>
         * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get trackingRight():*;

        /**
         * Leading controls for the text. The distance from the baseline of the previous or the next line (based on <code>LeadingModel</code>) to the baseline of the current line is equal to the maximum amount of the leading applied to any character in the line. This is either a number or a percent.  If specifying a percent, enter a string value, like 140%.<p><img src='../../../images/textLayout_lineHeight1.jpg' alt='lineHeight1' /><img src='../../../images/textLayout_lineHeight2.jpg' alt='lineHeight2' /></p>
         * <p>Legal values as a number are from -720 to 720.</p>
         * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 120%.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get lineHeight():*;

        /**
         * Controls where lines are allowed to break when breaking wrapping text into multiple lines. Set to <code>BreakOpportunity.AUTO</code> to break text normally. Set to <code>BreakOpportunity.NONE</code> to <em>not</em> break the text unless the text would overrun the measure and there are no other places to break the line. Set to <code>BreakOpportunity.ANY</code> to allow the line to break anywhere, rather than just between words. Set to <code>BreakOpportunity.ALL</code> to have each typographic cluster put on a separate line (useful for text on a path).
         * <p>Legal values are BreakOpportunity.ALL, BreakOpportunity.ANY, BreakOpportunity.AUTO, BreakOpportunity.NONE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of BreakOpportunity.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.BreakOpportunity
         */
        function get breakOpportunity():*;

        /**
         * The type of digit case used for this text. Setting the value to <code>DigitCase.OLD_STYLE</code> approximates lowercase letterforms with varying ascenders and descenders. The figures are proportionally spaced. This style is only available in selected typefaces, most commonly in a supplemental or expert font. The <code>DigitCase.LINING</code> setting has all-cap height and is typically monospaced to line up in charts.<p><img src='../../../images/textLayout_digitcase.gif' alt='digitCase' /></p>
         * <p>Legal values are DigitCase.DEFAULT, DigitCase.LINING, DigitCase.OLD_STYLE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DigitCase.DEFAULT.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.DigitCase
         */
        function get digitCase():*;

        /**
         * Type of digit width used for this text. This can be <code>DigitWidth.PROPORTIONAL</code>, which looks best for individual numbers, or <code>DigitWidth.TABULAR</code>, which works best for numbers in tables, charts, and vertical rows.<p><img src='../../../images/textLayout_digitwidth.gif' alt='digitWidth' /></p>
         * <p>Legal values are DigitWidth.DEFAULT, DigitWidth.PROPORTIONAL, DigitWidth.TABULAR, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of DigitWidth.DEFAULT.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.DigitWidth
         */
        function get digitWidth():*;

        /**
         * Specifies which element baseline snaps to the <code>alignmentBaseline</code> to determine the vertical position of the element on the line. A value of <code>TextBaseline.AUTO</code> selects the dominant baseline based on the <code>locale</code> property of the parent paragraph.  For Japanese and Chinese, the selected baseline value is <code>TextBaseline.IDEOGRAPHIC_CENTER</code>; for all others it is <code>TextBaseline.ROMAN</code>. These baseline choices are determined by the choice of font and the font size.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
         * <p>Legal values are FormatValue.AUTO, TextBaseline.ROMAN, TextBaseline.ASCENT, TextBaseline.DESCENT, TextBaseline.IDEOGRAPHIC_TOP, TextBaseline.IDEOGRAPHIC_CENTER, TextBaseline.IDEOGRAPHIC_BOTTOM, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of FormatValue.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.TextBaseline
         */
        function get dominantBaseline():*;

        /**
         * Kerning adjusts the pixels between certain character pairs to improve readability. Kerning is supported for all fonts with kerning tables.
         * <p>Legal values are Kerning.ON, Kerning.OFF, Kerning.AUTO, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of Kerning.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.Kerning
         */
        function get kerning():*;

        /**
         * Controls which of the ligatures that are defined in the font may be used in the text. The ligatures that appear for each of these settings is dependent on the font. A ligature occurs where two or more letter-forms are joined as a single glyph. Ligatures usually replace consecutive characters sharing common components, such as the letter pairs 'fi', 'fl', or 'ae'. They are used with both Latin and Non-Latin character sets. The ligatures enabled by the values of the LigatureLevel class - <code>MINIMUM</code>, <code>COMMON</code>, <code>UNCOMMON</code>, and <code>EXOTIC</code> - are additive. Each value enables a new set of ligatures, but also includes those of the previous types.<p><b>Note: </b>When working with Arabic or Syriac fonts, <code>ligatureLevel</code> must be set to MINIMUM or above.</p><p><img src='../../../images/textLayout_ligatures.png' alt='ligatureLevel' /></p>
         * <p>Legal values are LigatureLevel.MINIMUM, LigatureLevel.COMMON, LigatureLevel.UNCOMMON, LigatureLevel.EXOTIC, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of LigatureLevel.COMMON.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.LigatureLevel
         */
        function get ligatureLevel():*;

        /**
         * Specifies the baseline to which the dominant baseline aligns. For example, if you set <code>dominantBaseline</code> to ASCENT, setting <code>alignmentBaseline</code> to DESCENT aligns the top of the text with the DESCENT baseline, or below the line.  The largest element in the line generally determines the baselines.<p><img src='../../../images/textLayout_baselines.jpg' alt='baselines' /></p>
         * <p>Legal values are TextBaseline.ROMAN, TextBaseline.ASCENT, TextBaseline.DESCENT, TextBaseline.IDEOGRAPHIC_TOP, TextBaseline.IDEOGRAPHIC_CENTER, TextBaseline.IDEOGRAPHIC_BOTTOM, TextBaseline.USE_DOMINANT_BASELINE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TextBaseline.USE_DOMINANT_BASELINE.</p>
         * @includeExample examples\TextLayoutFormat_alignmentBaselineExample.as -noswf
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.TextBaseline
         */
        function get alignmentBaseline():*;

        /**
         * The locale of the text. Controls case transformations and shaping. Standard locale identifiers as described in Unicode Technical Standard #35 are used. For example en, en_US and en-US are all English, ja is Japanese. 
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of en.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get locale():*;

        /**
         * The type of typographic case used for this text. Here are some examples:<p><img src='../../../images/textLayout_typographiccase.png' alt='typographicCase' /></p>
         * <p>Legal values are TLFTypographicCase.DEFAULT, TLFTypographicCase.CAPS_TO_SMALL_CAPS, TLFTypographicCase.UPPERCASE, TLFTypographicCase.LOWERCASE, TLFTypographicCase.LOWERCASE_TO_SMALL_CAPS, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TLFTypographicCase.DEFAULT.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.TLFTypographicCase
         */
        function get typographicCase():*;

        /**
         *  The name of the font to use, or a comma-separated list of font names. The Flash runtime renders the element with the first available font in the list. For example Arial, Helvetica, _sans causes the player to search for Arial, then Helvetica if Arial is not found, then _sans if neither is found.
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of Arial.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get fontFamily():*;

        /**
         * Decoration on text. Use to apply underlining; default is none.
         * <p>Legal values are TextDecoration.NONE, TextDecoration.UNDERLINE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TextDecoration.NONE.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.TextDecoration
         */
        function get textDecoration():*;

        /**
         * Weight of text. May be <code>FontWeight.NORMAL</code> for use in plain text, or <code>FontWeight.BOLD</code>. Applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
         * <p>Legal values are FontWeight.NORMAL, FontWeight.BOLD, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of FontWeight.NORMAL.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.FontWeight
         */
        function get fontWeight():*;

        /**
         * Style of text. May be <code>FontPosture.NORMAL</code>, for use in plain text, or <code>FontPosture.ITALIC</code> for italic. This property applies only to device fonts (<code>fontLookup</code> property is set to flash.text.engine.FontLookup.DEVICE).
         * <p>Legal values are FontPosture.NORMAL, FontPosture.ITALIC, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of FontPosture.NORMAL.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.FontPosture
         */
        function get fontStyle():*;

        /**
         * Collapses or preserves whitespace when importing text into a TextFlow. <code>WhiteSpaceCollapse.PRESERVE</code> retains all whitespace characters. <code>WhiteSpaceCollapse.COLLAPSE</code> removes newlines, tabs, and leading or trailing spaces within a block of imported text. Line break tags (<br/>) and Unicode line separator characters are retained.
         * <p>Legal values are WhiteSpaceCollapse.PRESERVE, WhiteSpaceCollapse.COLLAPSE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of WhiteSpaceCollapse.COLLAPSE.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.WhiteSpaceCollapse
         */
        function get whiteSpaceCollapse():*;

        /**
         * The rendering mode used for this text.  Applies only to embedded fonts (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>).
         * <p>Legal values are RenderingMode.NORMAL, RenderingMode.CFF, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of RenderingMode.CFF.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.RenderingMode
         */
        function get renderingMode():*;

        /**
         * The type of CFF hinting used for this text. CFF hinting determines whether the Flash runtime forces strong horizontal stems to fit to a sub pixel grid or not. This property applies only if the <code>renderingMode</code> property is set to <code>RenderingMode.CFF</code>, and the font is embedded (<code>fontLookup</code> property is set to <code>FontLookup.EMBEDDED_CFF</code>). At small screen sizes, hinting produces a clear, legible text for human readers.
         * <p>Legal values are CFFHinting.NONE, CFFHinting.HORIZONTAL_STEM, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of CFFHinting.HORIZONTAL_STEM.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.CFFHinting
         */
        function get cffHinting():*;

        /**
         * Font lookup to use. Specifying <code>FontLookup.DEVICE</code> uses the fonts installed on the system that is running the SWF file. Device fonts result in a smaller movie size, but text is not always rendered the same across different systems and platforms. Specifying <code>FontLookup.EMBEDDED_CFF</code> uses font outlines embedded in the published SWF file. Embedded fonts increase the size of the SWF file (sometimes dramatically), but text is consistently displayed in the chosen font.
         * <p>Legal values are FontLookup.DEVICE, FontLookup.EMBEDDED_CFF, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of FontLookup.DEVICE.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.FontLookup
         */
        function get fontLookup():*;

        /**
         * Determines the number of degrees to rotate this text.
         * <p>Legal values are TextRotation.ROTATE_0, TextRotation.ROTATE_180, TextRotation.ROTATE_270, TextRotation.ROTATE_90, TextRotation.AUTO, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TextRotation.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.TextRotation
         */
        function get textRotation():*;

        /**
         * A Number that specifies, in pixels, the amount to indent the first line of the paragraph.
         * A negative indent will push the line into the margin, and possibly out of the container.
         * <p>Legal values are numbers from -8000 to 8000 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get textIndent():*;

        /**
         * A Number that specifies, in pixels, the amount to indent the paragraph's start edge. Refers to the left edge in left-to-right text and the right edge in right-to-left text. 
         * <p>Legal values are numbers from 0 to 8000 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get paragraphStartIndent():*;

        /**
         * A Number that specifies, in pixels, the amount to indent the paragraph's end edge. Refers to the right edge in left-to-right text and the left edge in right-to-left text. 
         * <p>Legal values are numbers from 0 to 8000 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get paragraphEndIndent():*;

        /**
         * A Number that specifies the amount of space, in pixels, to leave before the paragraph. 
         * Collapses in tandem with <code>paragraphSpaceAfter</code>.
         * <p>Legal values are numbers from 0 to 8000 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get paragraphSpaceBefore():*;

        /**
         * A Number that specifies the amount of space, in pixels, to leave after the paragraph.
         * Collapses in tandem with  <code>paragraphSpaceBefore</code>.
         * <p>Legal values are numbers from 0 to 8000 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 0.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get paragraphSpaceAfter():*;

        /**
         * Alignment of lines in the paragraph relative to the container.
         * <code>TextAlign.LEFT</code> aligns lines along the left edge of the container. <code>TextAlign.RIGHT</code> aligns on the right edge. <code>TextAlign.CENTER</code> positions the line equidistant from the left and right edges. <code>TextAlign.JUSTIFY</code> spreads the lines out so they fill the space. <code>TextAlign.START</code> is equivalent to setting left in left-to-right text, or right in right-to-left text. <code>TextAlign.END</code> is equivalent to setting right in left-to-right text, or left in right-to-left text.
         * <p>Legal values are TextAlign.LEFT, TextAlign.RIGHT, TextAlign.CENTER, TextAlign.JUSTIFY, TextAlign.START, TextAlign.END, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TextAlign.START.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.TextAlign
         */
        function get textAlign():*;

        /**
         * Alignment of the last (or only) line in the paragraph relative to the container in justified text.
         * If <code>textAlign</code> is set to <code>TextAlign.JUSTIFY</code>, <code>textAlignLast</code> specifies how the last line (or only line, if this is a one line block) is aligned. Values are similar to <code>textAlign</code>.
         * <p>Legal values are TextAlign.LEFT, TextAlign.RIGHT, TextAlign.CENTER, TextAlign.JUSTIFY, TextAlign.START, TextAlign.END, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TextAlign.START.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.TextAlign
         */
        function get textAlignLast():*;

        /**
         * Specifies options for justifying text.
         * Default value is <code>TextJustify.INTER_WORD</code>, meaning that extra space is added to the space characters. <code>TextJustify.DISTRIBUTE</code> adds extra space to space characters and between individual letters. Used only in conjunction with a <code>justificationRule</code> value of <code>JustificationRule.SPACE</code>.
         * <p>Legal values are TextJustify.INTER_WORD, TextJustify.DISTRIBUTE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of TextJustify.INTER_WORD.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.TextJustify
         */
        function get textJustify():*;

        /**
         * Rule used to justify text in a paragraph.
         * Default value is <code>FormatValue.AUTO</code>, which justifies text based on the paragraph's <code>locale</code> property. For all languages except Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustificationRule.SPACE</code>, which adds extra space to the space characters.  For Japanese and Chinese, <code>FormatValue.AUTO</code> becomes <code>JustficationRule.EAST_ASIAN</code>. In part, justification changes the spacing of punctuation. In Roman text the comma and Japanese periods take a full character's width but in East Asian text only half of a character's width. Also, in the East Asian text the spacing between sequential punctuation marks becomes tighter, obeying traditional East Asian typographic conventions. Note, too, in the example below the leading that is applied to the second line of the paragraphs. In the East Asian version, the last two lines push left. In the Roman version, the second and following lines push left.<p><img src='../../../images/textLayout_justificationrule.png' alt='justificationRule' /></p>
         * <p>Legal values are JustificationRule.EAST_ASIAN, JustificationRule.SPACE, FormatValue.AUTO, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of FormatValue.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.JustificationRule
         */
        function get justificationRule():*;

        /**
         * The style used for justification of the paragraph. Used only in conjunction with a <code>justificationRule</code> setting of <code>JustificationRule.EAST_ASIAN</code>.
         * Default value of <code>FormatValue.AUTO</code> is resolved to <code>JustificationStyle.PUSH_IN_KINSOKU</code> for all locales.  The constants defined by the JustificationStyle class specify options for handling kinsoku characters, which are Japanese characters that cannot appear at either the beginning or end of a line. If you want looser text, specify <code>JustificationStyle.PUSH-OUT-ONLY</code>. If you want behavior that is like what you get with the  <code>justificationRule</code> of <code>JustificationRule.SPACE</code>, use <code>JustificationStyle.PRIORITIZE-LEAST-ADJUSTMENT</code>.
         * <p>Legal values are JustificationStyle.PRIORITIZE_LEAST_ADJUSTMENT, JustificationStyle.PUSH_IN_KINSOKU, JustificationStyle.PUSH_OUT_ONLY, FormatValue.AUTO, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of FormatValue.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flash.text.engine.JustificationStyle
         */
        function get justificationStyle():*;

        /**
         * Specifies the default bidirectional embedding level of the text in the text block. 
         * Left-to-right reading order, as in Latin-style scripts, or right-to-left reading order, as in Arabic or Hebrew. This property also affects column direction when it is applied at the container level. Columns can be either left-to-right or right-to-left, just like text. Below are some examples:<p><img src='../../../images/textLayout_direction.gif' alt='direction' /></p>
         * <p>Legal values are Direction.LTR, Direction.RTL, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of Direction.LTR.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.Direction
         */
        function get direction():*;

        /**
         * Specifies the optimum, minimum, and maximum spacing (as a multiplier of the width of a normal space) between words to use during justification.
         * The optimum space is used to indicate the desired size of a space, as a fraction of the value defined in the font. The minimum and maximum values are the used when textJustify is distribute to determine how wide or narrow the spaces between the words may grow before letter spacing is used to justify the line.
         * <p>Legal values as a percent are numbers from -1000% to 1000%.</p>
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 100%, 50%, 150%.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get wordSpacing():*;

        /**
         * Specifies the tab stops associated with the paragraph.
         * Setters can take an array of TabStopFormat, a condensed string representation, undefined, or <code>FormatValue.INHERIT</code>. 
         * The condensed string representation is always converted into an array of TabStopFormat. 
         * 
         * <p>The string-based format is a list of tab stops, where each tab stop is delimited by one or more spaces.</p>
         * 
         * <p>A tab stop takes the following form: &lt;alignment type&gt;&lt;alignment position&gt;|&lt;alignment token&gt;.</p>
         * 
         * <p>The alignment type is a single character, and can be S, E, C, or D (or lower-case equivalents). S or s for start, E or e for end, C or c for center, D or d for decimal. 
         * The alignment type is optional, and if its not specified will default to S.</p>
         * 
         * <p>The alignment position is a Number, and is specified according to FXG spec for Numbers (decimal or scientific notation). 
         * The alignment position is required.</p>
         * 
         * <p>The vertical bar is used to separate the alignment position from the alignment token, and should only be present if the alignment token is present.</p>
         * 
         * <p>The alignment token is optional if the alignment type is D, and should not be present if the alignment type is anything other than D. 
         * The alignment token may be any sequence of characters terminated by the space that ends the tab stop (for the last tab stop, the terminating space is optional; end of alignment token is implied). 
         * A space may be part of the alignment token if it is escaped with a backslash (\ ). A backslash may be part of the alignment token if it is escaped with another backslash (\\). 
         * If the alignment type is D, and the alignment token is not specified, it will take on the default value of <code>null</code>.</p>
         * 
         * <p>Default value is undefined indicating not set.</p>
         * 
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
         * 
         * @see flashx.textLayout.formats.TabStopFormat
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get tabStops():*;

        /**
         * Specifies the leading model, which is a combination of leading basis and leading direction.
         * Leading basis is the baseline to which the <code>lineHeight</code> property refers. Leading direction determines whether the <code>lineHeight</code> property refers to the distance of a line's baseline from that of the line before it or the line after it. The default value of <code>FormatValue.AUTO</code> is resolved based on the paragraph's <code>locale</code> property.  For Japanese and Chinese, it is <code>LeadingModel.IDEOGRAPHIC_TOP_DOWN</code> and for all others it is <code>LeadingModel.ROMAN_UP</code>.<p><strong>Leading Basis:</strong></p><p><img src='../../../images/textLayout_LB1.png' alt='leadingBasis1' />    <img src='../../../images/textLayout_LB2.png' alt='leadingBasis2' />    <img src='../../../images/textLayout_LB3.png' alt='leadingBasis3' /></p><p><strong>Leading Direction:</strong></p><p><img src='../../../images/textLayout_LD1.png' alt='leadingDirection1' />    <img src='../../../images/textLayout_LD2.png' alt='leadingDirection2' />    <img src='../../../images/textLayout_LD3.png' alt='leadingDirection3' /></p>
         * <p>Legal values are LeadingModel.ROMAN_UP, LeadingModel.IDEOGRAPHIC_TOP_UP, LeadingModel.IDEOGRAPHIC_CENTER_UP, LeadingModel.IDEOGRAPHIC_TOP_DOWN, LeadingModel.IDEOGRAPHIC_CENTER_DOWN, LeadingModel.APPROXIMATE_TEXT_FIELD, LeadingModel.ASCENT_DESCENT_UP, LeadingModel.BOX, LeadingModel.AUTO, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of LeadingModel.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.LeadingModel
         */
        function get leadingModel():*;

        /**
         * Specifies the amount of gutter space, in pixels, to leave between the columns (adopts default value if undefined during cascade).
         * Value is a Number
         * <p>Legal values are numbers from 0 to 1000 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of 20.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get columnGap():*;

        /**
         * Left inset in pixels.  Default of auto is zero except in lists which get a start side padding of 45. (adopts default value if undefined during cascade).
         * Space between the left edge of the container and the text.  Value is a Number or auto.<p> With vertical text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the end of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
         * <p>Legal values as a string are FormatValue.AUTO, FormatValue.INHERIT and numbers from -8000 to 8000.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of FormatValue.AUTO.</p>
         * @see flashx.textLayout.elements.Configuration#autoListElementStartPadding
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.FormatValue
         */
        function get paddingLeft():*;

        /**
         * Top inset in pixels.  Default of auto is zero except in lists which get a start side padding of 45. (adopts default value if undefined during cascade).
         * Space between the top edge of the container and the text.  Value is a Number or auto.
         * <p>Legal values as a string are FormatValue.AUTO, FormatValue.INHERIT and numbers from -8000 to 8000.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of FormatValue.AUTO.</p>
         * @see flashx.textLayout.elements.Configuration#autoListElementStartPadding
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.FormatValue
         */
        function get paddingTop():*;

        /**
         * Right inset in pixels.  Default of auto is zero except in lists which get a start side padding of 45. (adopts default value if undefined during cascade).
         * Space between the right edge of the container and the text.  Value is a Number or auto. 
         * <p>Legal values as a string are FormatValue.AUTO, FormatValue.INHERIT and numbers from -8000 to 8000.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of FormatValue.AUTO.</p>
         * @see flashx.textLayout.elements.Configuration#autoListElementStartPadding
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.FormatValue
         */
        function get paddingRight():*;

        /**
         * Bottom inset in pixels.  Default of auto is zero except in lists which get a start side padding of 45.  (adopts default value if undefined during cascade).
         * Space between the bottom edge of the container and the text.  Value is a Number  or auto. <p> With horizontal text, in scrollable containers with multiple columns, the first and following columns will show the padding as blank space at the bottom of the container, but for the last column, if the text doesn't all fit, you may have to scroll in order to see the padding.</p>
         * <p>Legal values as a string are FormatValue.AUTO, FormatValue.INHERIT and numbers from -8000 to 8000.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of FormatValue.AUTO.</p>
         * @see flashx.textLayout.elements.Configuration#autoListElementStartPadding
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.FormatValue
         */
        function get paddingBottom():*;

        /**
         * Number of text columns (adopts default value if undefined during cascade).
         * The column number overrides the  other column settings. Value is an integer, or <code>FormatValue.AUTO</code> if unspecified. If <code>columnCount</code> is not specified,<code>columnWidth</code> is used to create as many columns as can fit in the container.
         * <p>Legal values as a string are FormatValue.AUTO, FormatValue.INHERIT and from ints from 1 to 50.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of FormatValue.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.FormatValue
         */
        function get columnCount():*;

        /**
         * Column width in pixels (adopts default value if undefined during cascade).
         * If you specify the width of the columns, but not the count, TextLayout will create as many columns of that width as possible, given the  container width and <code>columnGap</code> settings. Any remainder space is left after the last column. Value is a Number.
         * <p>Legal values as a string are FormatValue.AUTO, FormatValue.INHERIT and numbers from 0 to 8000.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of FormatValue.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.FormatValue
         */
        function get columnWidth():*;

        /**
         * Specifies the baseline position of the first line in the container. Which baseline this property refers to depends on the container-level locale.  For Japanese and Chinese, it is <code>TextBaseline.IDEOGRAPHIC_BOTTOM</code>; for all others it is <code>TextBaseline.ROMAN</code>.
         * The offset from the top inset (or right inset if <code>blockProgression</code> is RL) of the container to the baseline of the first line can be either <code>BaselineOffset.ASCENT</code>, meaning equal to the ascent of the line, <code>BaselineOffset.LINE_HEIGHT</code>, meaning equal to the height of that first line, or any fixed-value number to specify an absolute distance. <code>BaselineOffset.AUTO</code> aligns the ascent of the line with the container top inset.<p><img src='../../../images/textLayout_FBO1.png' alt='firstBaselineOffset1' /><img src='../../../images/textLayout_FBO2.png' alt='firstBaselineOffset2' /><img src='../../../images/textLayout_FBO3.png' alt='firstBaselineOffset3' /><img src='../../../images/textLayout_FBO4.png' alt='firstBaselineOffset4' /></p>
         * <p>Legal values as a string are BaselineOffset.AUTO, BaselineOffset.ASCENT, BaselineOffset.LINE_HEIGHT, FormatValue.INHERIT and numbers from 0 to 1000.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of BaselineOffset.AUTO.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.BaselineOffset
         */
        function get firstBaselineOffset():*;

        /**
         * Vertical alignment or justification (adopts default value if undefined during cascade).
         * Determines how TextFlow elements align within the container.
         * <p>Legal values are VerticalAlign.TOP, VerticalAlign.MIDDLE, VerticalAlign.BOTTOM, VerticalAlign.JUSTIFY, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of VerticalAlign.TOP.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.VerticalAlign
         */
        function get verticalAlign():*;

        /**
         * Specifies a vertical or horizontal progression of line placement.
         * Lines are either placed top-to-bottom (<code>BlockProgression.TB</code>, used for horizontal text) or right-to-left (<code>BlockProgression.RL</code>, used for vertical text).
         * <p>Legal values are BlockProgression.RL, BlockProgression.TB, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of BlockProgression.TB.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.BlockProgression
         */
        function get blockProgression():*;

        /**
         * Controls word wrapping within the container (adopts default value if undefined during cascade).
         * Text in the container may be set to fit the width of the container (<code>LineBreak.TO_FIT</code>), or can be set to break only at explicit return or line feed characters (<code>LineBreak.EXPLICIT</code>).
         * <p>Legal values are LineBreak.EXPLICIT, LineBreak.TO_FIT, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of LineBreak.TO_FIT.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.LineBreak
         */
        function get lineBreak():*;

        /**
         * <p>Legal values are ListStyleType.UPPER_ALPHA, ListStyleType.LOWER_ALPHA, ListStyleType.UPPER_ROMAN, ListStyleType.LOWER_ROMAN, ListStyleType.NONE, ListStyleType.DISC, ListStyleType.CIRCLE, ListStyleType.SQUARE, ListStyleType.BOX, ListStyleType.CHECK, ListStyleType.DIAMOND, ListStyleType.HYPHEN, ListStyleType.ARABIC_INDIC, ListStyleType.BENGALI, ListStyleType.DECIMAL, ListStyleType.DECIMAL_LEADING_ZERO, ListStyleType.DEVANAGARI, ListStyleType.GUJARATI, ListStyleType.GURMUKHI, ListStyleType.KANNADA, ListStyleType.PERSIAN, ListStyleType.THAI, ListStyleType.URDU, ListStyleType.CJK_EARTHLY_BRANCH, ListStyleType.CJK_HEAVENLY_STEM, ListStyleType.HANGUL, ListStyleType.HANGUL_CONSTANT, ListStyleType.HIRAGANA, ListStyleType.HIRAGANA_IROHA, ListStyleType.KATAKANA, ListStyleType.KATAKANA_IROHA, ListStyleType.LOWER_ALPHA, ListStyleType.LOWER_GREEK, ListStyleType.LOWER_LATIN, ListStyleType.UPPER_ALPHA, ListStyleType.UPPER_GREEK, ListStyleType.UPPER_LATIN, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of ListStyleType.DISC.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.ListStyleType
         */
        function get listStyleType():*;

        /**
         * <p>Legal values are ListStylePosition.INSIDE, ListStylePosition.OUTSIDE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of ListStylePosition.OUTSIDE.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.ListStylePosition
         */
        function get listStylePosition():*;

        /**
         * This specifies an auto indent for the start edge of lists when the padding value of the list on that side is <code>auto</code>.
         * <p>Legal values are numbers from -1000 to 1000 and FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of 40.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get listAutoPadding():*;

        /**
         * Controls how text wraps around a float. A value of none will allow the text to wrap most closely around a float. A value of left will cause the text to skip over any portion of the container that has a left float, and a value of right will cause the text to skip over any portion of the container that has a right float. A value of both will cause the text to skip over any floats.
         * <p>Legal values are ClearFloats.START, ClearFloats.END, ClearFloats.LEFT, ClearFloats.RIGHT, ClearFloats.BOTH, ClearFloats.NONE, FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of ClearFloats.NONE.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         * @see flashx.textLayout.formats.ClearFloats
         */
        function get clearFloats():*;

        /**
         * Assigns an identifying class to the element, making it possible to set a style for the element by referencing the <code>styleName</code>.
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will have a value of null.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get styleName():*;

        /**
         * Defines the formatting attributes used for links in normal state. This value will cascade down the hierarchy and apply to any links that are descendants.
         * Accepts <code>inherit</code>, an <code>ITextLayoutFormat</code> or converts an array of objects with key and value as members to a TextLayoutFormat.
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get linkNormalFormat():*;

        /**
         * Defines the formatting attributes used for links in normal state. This value will cascade down the hierarchy and apply to any links that are descendants.
         * Accepts <code>inherit</code>, an <code>ITextLayoutFormat</code> or converts an array of objects with key and value as members to a TextLayoutFormat.
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get linkActiveFormat():*;

        /**
         * Defines the formatting attributes used for links in hover state, when the mouse is within the bounds (rolling over) a link. This value will cascade down the hierarchy and apply to any links that are descendants.
         * Accepts <code>inherit</code>, an <code>ITextLayoutFormat</code> or converts an array of objects with key and value as members to a TextLayoutFormat.
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get linkHoverFormat():*;

        /**
         * Defines the formatting attributes list markers. This value will cascade down the hierarchy and apply to any links that are descendants.
         * Accepts <code>inherit</code>, an <code>IListMarkerFormat</code> or converts an array of objects with key and value as members to a ListMarkerFormat.
         * <p>Legal values include FormatValue.INHERIT.</p>
         * <p>Default value is undefined indicating not set.</p>
         * <p>If undefined during the cascade this property will inherit its value from an ancestor. If no ancestor has set this property, it will have a value of null.</p>
         * 
         * @throws RangeError when set value is not within range for this property
         * 
         * @playerversion Flash 10
         * @playerversion AIR 1.5
         * @langversion 3.0
         */
        function get listMarkerFormat():*;
    }
}
