You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by ah...@apache.org on 2018/08/14 07:58:19 UTC

[royale-asjs] 06/07: get RichText to use TLF

This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit e80ef04b08f9e6245496b2b293733dcab3670fd8
Author: Alex Harui <ah...@apache.org>
AuthorDate: Mon Aug 13 23:29:58 2018 -0700

    get RichText to use TLF
---
 .../src/main/royale/spark/components/RichText.as   | 194 +++++++++++++--------
 .../spark/components/supportClasses/TextBase.as    |  73 +++++---
 .../main/royale/spark/core/CSSTextLayoutFormat.as  | 153 ++++++++++++++++
 3 files changed, 322 insertions(+), 98 deletions(-)

diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/RichText.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/RichText.as
index 5292fd0..4a77c87 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/RichText.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/RichText.as
@@ -26,36 +26,37 @@ import flash.text.TextFormat;
 import flashx.textLayout.compose.ISWFContext;
 import flashx.textLayout.conversion.ConversionType;
 import flashx.textLayout.conversion.ITextExporter;
-import flashx.textLayout.conversion.ITextImporter;
-import flashx.textLayout.conversion.TextConverter;
 import flashx.textLayout.elements.Configuration;
 import flashx.textLayout.elements.GlobalSettings;
-import flashx.textLayout.elements.TextFlow;
-import flashx.textLayout.events.DamageEvent;
-import flashx.textLayout.factory.StringTextLineFactory;
-import flashx.textLayout.factory.TextFlowTextLineFactory;
-import flashx.textLayout.factory.TextLineFactoryBase;
-import flashx.textLayout.factory.TruncationOptions;
-import flashx.textLayout.formats.ITextLayoutFormat;
-import flashx.textLayout.tlf_internal;
-
-import mx.core.IEmbeddedFontRegistry;
-import mx.core.IFlexModuleFactory;
-import mx.core.IUIComponent;
-import mx.core.Singleton;
-import mx.core.UIComponent;
+*/
+import mx.core.mx_internal;
+import mx.styles.IStyleClient;
 
+import spark.components.supportClasses.TextBase;
 import spark.core.CSSTextLayoutFormat;
-import spark.core.MaskType;
-import spark.utils.MaskUtil;
-import spark.utils.TextUtil;
 
-use namespace tlf_internal
-*/
-import spark.components.supportClasses.TextBase;
-import mx.core.mx_internal;
+import org.apache.royale.text.engine.ITextLine;
+import org.apache.royale.textLayout.conversion.ITextImporter;
+import org.apache.royale.textLayout.conversion.TextConverter;
+import org.apache.royale.textLayout.elements.ITextFlow;
+import org.apache.royale.textLayout.elements.TextFlow;
+import org.apache.royale.textLayout.events.DamageEvent;
+import org.apache.royale.textLayout.factory.StringTextLineFactory;
+import org.apache.royale.textLayout.factory.TLFFactory;
+import org.apache.royale.textLayout.factory.StandardTLFFactory;
+import org.apache.royale.textLayout.factory.TextFlowTextLineFactory;
+import org.apache.royale.textLayout.factory.TextLineFactoryBase;
+import org.apache.royale.textLayout.formats.ITextLayoutFormat;
+
 use namespace mx_internal;
 
+COMPILE::JS
+{
+    import org.apache.royale.html.util.addElementToWrapper;
+    import org.apache.royale.core.WrappedHTMLElement;        
+}
+import org.apache.royale.events.Event;        
+
 //--------------------------------------
 //  Styles
 //--------------------------------------
@@ -232,7 +233,7 @@ include "../styles/metadata/AdvancedNonInheritingTextStyles.as"
  *  
  *  @includeExample examples/RichTextExample.mxml
  */
-public class RichText extends TextBase
+public class RichText extends TextBase implements IStyleClient
 {
 //    include "../core/Version.as";
 
@@ -245,7 +246,7 @@ public class RichText extends TextBase
     /**
      *  @private
      */
-    //private static var classInitialized:Boolean = false;
+    private static var classInitialized:Boolean = false;
     
     /**
      *  @private
@@ -253,7 +254,7 @@ public class RichText extends TextBase
      *  We use it when the 'text' property is set to a String
      *  that doesn't contain linebreaks.
      */
-    //private static var staticStringFactory:StringTextLineFactory;
+    private static var staticStringFactory:StringTextLineFactory;
     
     /**
      *  @private
@@ -263,14 +264,14 @@ public class RichText extends TextBase
      *  that contains linebreaks (and therefore is interpreted
      *  as multiple paragraphs).
      */
-    //private static var staticTextFlowFactory:TextFlowTextLineFactory;
+    private static var staticTextFlowFactory:TextFlowTextLineFactory;
     
     /**
      *  @private
      *  This TLF object is used to import a 'text' String
      *  containing linebreaks to create a multiparagraph TextFlow.
      */
-    //private static var staticPlainTextImporter:ITextImporter;
+    private static var staticPlainTextImporter:ITextImporter;
     
     /**
      *  @private
@@ -295,24 +296,28 @@ public class RichText extends TextBase
      *  By doing so, we avoid any static initialization issues
      *  related to whether this class or the TLF classes
      *  that it uses are initialized first.
+     */
     private static function initClass():void
     {
         if (classInitialized)
             return;
-            
+
+        if (!TLFFactory.defaultTLFFactory)
+            TLFFactory.defaultTLFFactory = new StandardTLFFactory();        
+
         // Set the TLF hook used for localizing runtime error messages.
         // TLF itself has English-only messages,
         // but higher layers like Flex can provide localized versions.
-        GlobalSettings.resourceStringFunction = TextUtil.getResourceString;
+        //GlobalSettings.resourceStringFunction = TextUtil.getResourceString;
 
         // Set the TLF hook used to specify the callback used for changing 
         // the FontLookup based on SWFContext.  
-        GlobalSettings.resolveFontLookupFunction = TextUtil.resolveFontLookup;
+        //GlobalSettings.resolveFontLookupFunction = TextUtil.resolveFontLookup;
 
         // Pre-FP10.1, set default tab stops in TLF.  Without this, if there
         // is a tab and TLF is measuring width, the tab will
         // measure as the rest of the remaining width up to 10000.
-        GlobalSettings.enableDefaultTabStops = !Configuration.playerEnablesArgoFeatures;
+        //GlobalSettings.enableDefaultTabStops = !Configuration.playerEnablesArgoFeatures;
         
         staticStringFactory = new StringTextLineFactory();
         
@@ -321,12 +326,11 @@ public class RichText extends TextBase
         staticPlainTextImporter =
             TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);
         
-        staticPlainTextExporter =
-            TextConverter.getExporter(TextConverter.PLAIN_TEXT_FORMAT);
+        //staticPlainTextExporter =
+        //    TextConverter.getExporter(TextConverter.PLAIN_TEXT_FORMAT);
             
         classInitialized = true;
     }
-     */
     
     //--------------------------------------------------------------------------
     //
@@ -346,11 +350,40 @@ public class RichText extends TextBase
     {
         super();
         
-//        initClass();
+        initClass();
         
         text = "";
+        
+        addEventListener("sizeChanged", sizeChangedHandler);
     }
-     
+    
+    private function sizeChangedHandler(event:Event):void
+    {
+        updateDisplayList(width, height);
+    }
+    
+    COMPILE::JS
+    override public function setActualSize(w:Number, h:Number):void
+    {
+        setWidthAndHeight(w, h);
+    }
+    
+    COMPILE::JS
+    override protected function createElement():WrappedHTMLElement
+    {
+        addElementToWrapper(this,'div');
+                
+        return element;
+    }
+
+    override public function addedToParent():void
+    {
+        super.addedToParent();
+        commitProperties();
+        if (isWidthSizedToContent() && isHeightSizedToContent())
+            updateDisplayList(getExplicitOrMeasuredWidth(), getExplicitOrMeasuredHeight());
+    }
+
     //--------------------------------------------------------------------------
     //
     //  Variables
@@ -364,7 +397,7 @@ public class RichText extends TextBase
      *  It is set to null by stylesInitialized() and styleChanged(),
      *  and recreated whenever necessary in commitProperties().
      */
-    //private var hostFormat:ITextLayoutFormat;
+    private var hostFormat:ITextLayoutFormat;
 
     /**
      *  @private
@@ -372,7 +405,7 @@ public class RichText extends TextBase
      *  Used to determine whether to return immediately from damage event if 
      *  there have been no changes.
      */
-    //private var lastGeneration:uint = 0;    // 0 means not set
+    private var lastGeneration:uint = 0;    // 0 means not set
         
     /**
      *  @private
@@ -390,13 +423,13 @@ public class RichText extends TextBase
      *  and when 'text' is set to a string without linebreaks;
      *  otherwise, a TextFlowTextLineFactory is used.
      */
-    //private var factory:TextLineFactoryBase;
+    private var factory:TextLineFactoryBase;
 
     /**
      *  @private
      *  If true, the damage handler will return immediately.
      */
-    //private var ignoreDamageEvent:Boolean;
+    private var ignoreDamageEvent:Boolean;
     
     //--------------------------------------------------------------------------
     //
@@ -487,7 +520,6 @@ public class RichText extends TextBase
         textChanged = true;
         source = "text";
         
-        /*
         // If more than one of 'text', 'textFlow', and 'content' is set,
         // the last one set wins.
         textFlowChanged = false;
@@ -502,6 +534,7 @@ public class RichText extends TextBase
         
         factory = staticStringFactory;
         
+        /*
         invalidateTextLines();
         invalidateProperties();
         invalidateSize();
@@ -615,15 +648,15 @@ public class RichText extends TextBase
         textFlowChanged = false;
         
         // If there was a textFlow remove its damage handler.
-        //removeDamageHandler();
+        removeDamageHandler();
 
         // The other two are now invalid and must be recalculated when needed.
         _text = null;
         _textFlow = null;
         
-        /*
         factory = staticTextFlowFactory;
         
+        /*
         invalidateTextLines();
         invalidateProperties();
         invalidateSize();
@@ -877,7 +910,7 @@ public class RichText extends TextBase
      *  @private
      *  Storage for the textFlow property.
      */
-    private var _textFlow:String // TextFlow;
+    private var _textFlow:TextFlow;
     
     /**
      *  @private
@@ -928,7 +961,7 @@ public class RichText extends TextBase
      *  @playerversion AIR 2.5
      *  @productversion Flex 4.5
      */
-    public function get textFlow():String //TextFlow
+    public function get textFlow():TextFlow
     {
         // We might not have a valid _textFlow for two reasons:
         // either because the 'text' was set (which is the state
@@ -962,7 +995,7 @@ public class RichText extends TextBase
     /**
      *  @private
      */
-    public function set textFlow(value:String /*TextFlow*/):void
+    public function set textFlow(value:TextFlow):void
     {
         // Treat setting the 'textFlow' to null
         // as if 'text' were being set to the empty String
@@ -977,7 +1010,7 @@ public class RichText extends TextBase
             return;
                     
         // If there was a textFlow remove its damage handler.
-        //removeDamageHandler();
+        removeDamageHandler();
         
         _textFlow = value;
         textFlowChanged = true;
@@ -1010,9 +1043,12 @@ public class RichText extends TextBase
     
     /**
      *  @private
+     */
     override protected function commitProperties():void
     {
+        /*
         super.commitProperties();
+        */
         
         // Only one of textChanged, textFlowChanged, and contentChanged
         // will be true; the other two will be false because each setter
@@ -1027,7 +1063,7 @@ public class RichText extends TextBase
             // and FTE performance will degrade on a large paragraph.
             if (_text.indexOf("\n") != -1 || _text.indexOf("\r") != -1)
             {
-                _textFlow = staticPlainTextImporter.importToFlow(_text);
+                _textFlow = staticPlainTextImporter.importToFlow(_text) as TextFlow;
                 factory = staticTextFlowFactory;
             }
             textChanged = false;
@@ -1072,6 +1108,7 @@ public class RichText extends TextBase
                                        textFlow_damageHandler);
         }
         
+        /*
         if (maskChanged)
         {
             if (mask && !mask.parent)
@@ -1097,8 +1134,8 @@ public class RichText extends TextBase
 
             maskTypeChanged = false;
         }
+        */
     }
-         */
 
     /**
      *  @private
@@ -1131,9 +1168,11 @@ public class RichText extends TextBase
 
     /**
      *  @private
+     */
     override protected function updateDisplayList(unscaledWidth:Number, 
                                                   unscaledHeight:Number):void
     {
+        /*
         // The factory will compose just enough lines to fill the 
         // compositionHeight.  If not all the text is composed, the reported
         // contentHeight will be an estimate of what the height will be when
@@ -1146,8 +1185,15 @@ public class RichText extends TextBase
         }
 
         super.updateDisplayList(unscaledWidth, unscaledHeight);
-    }    
-     */
+        */
+        
+        // Compose will add the new text lines to the display object container.
+        // Otherwise, if the text is in a shared container, make sure the 
+        // position of the lines has remained the same.
+        TLFFactory.defaultTLFFactory.currentContainer = this;
+        composeTextLines(unscaledWidth, unscaledHeight);
+
+    }
     
     //--------------------------------------------------------------------------
     //
@@ -1158,6 +1204,7 @@ public class RichText extends TextBase
     /**
      *  @private
      *  Returns true to indicate all lines were composed.
+     */
     override mx_internal function composeTextLines(width:Number = NaN,
                                                    height:Number = NaN):Boolean
     {   
@@ -1194,7 +1241,7 @@ public class RichText extends TextBase
         // toFit.  So if we are measuring, create the text lines to figure
         // out their size and then recreate them using this size so truncation 
         // will be done.
-        if (maxDisplayedLines != 0 && !isTruncated &&
+        if (maxDisplayedLines != 0 && /*!isTruncated &&*/
             getStyle("lineBreak") == "toFit")
         {
             var bp:String = getStyle("blockProgression");
@@ -1210,10 +1257,10 @@ public class RichText extends TextBase
         addTextLines();
         
         // Figure out if the text overruns the available space for composition.
-        isOverset = isTextOverset(width, height);
+        //isOverset = isTextOverset(width, height);
         
         // Just recomposed so reset.
-        invalidateCompose = false;
+        //invalidateCompose = false;
         
         // Listen for "damage" events in case the textFlow is 
         // modified programatically.
@@ -1222,7 +1269,6 @@ public class RichText extends TextBase
         // Created all lines.
         return true;      
     }
-     */
     
     //--------------------------------------------------------------------------
     //
@@ -1232,6 +1278,7 @@ public class RichText extends TextBase
 
     /**
      *  @private
+     */
     private function createTextFlowFromContent(content:Object):TextFlow
     {
         var textFlow:TextFlow ;
@@ -1242,14 +1289,14 @@ public class RichText extends TextBase
         }
         else if (content is Array)
         {
-            textFlow = new TextFlow();
+            textFlow = new TextFlow(TLFFactory.defaultTLFFactory);
             textFlow.whiteSpaceCollapse = getStyle("whiteSpaceCollapse");
             textFlow.mxmlChildren = content as Array;
             textFlow.whiteSpaceCollapse = undefined;
         }
         else
         {
-            textFlow = new TextFlow();
+            textFlow = new TextFlow(TLFFactory.defaultTLFFactory);
             textFlow.whiteSpaceCollapse = getStyle("whiteSpaceCollapse");
             textFlow.mxmlChildren = [ content ];
             textFlow.whiteSpaceCollapse = undefined;
@@ -1257,12 +1304,12 @@ public class RichText extends TextBase
         
         return textFlow;
     }
-     */
     
     /**
      *  @private
      *  Uses TextLineFactory to compose the textFlow
      *  into as many TextLines as fit into the bounds.
+     */
     private function createTextLines():void
     {
         // Clear any previously generated TextLines from the textLines Array.
@@ -1278,6 +1325,7 @@ public class RichText extends TextBase
         factory.compositionBounds = bounds;   
         
         // Set up the truncation options.
+        /*
         var truncationOptions:TruncationOptions;
         if (maxDisplayedLines != 0)
         {
@@ -1287,37 +1335,37 @@ public class RichText extends TextBase
                 TextBase.truncationIndicatorResource;
         }        
         factory.truncationOptions = truncationOptions;
+        */
         
         // 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();
+        //embeddedFontContext = getEmbeddedFontContext();
        
         if (factory is StringTextLineFactory)
         {
             // We know text is non-null since it got this far.
             staticStringFactory.text = _text;
             staticStringFactory.textFlowFormat = hostFormat;
-            staticStringFactory.swfContext = ISWFContext(embeddedFontContext);
+            //staticStringFactory.swfContext = ISWFContext(embeddedFontContext);
             staticStringFactory.createTextLines(addTextLine);
         }
         else if (factory is TextFlowTextLineFactory)
         {
             if (_textFlow && _textFlow.flowComposer)
             {
-                _textFlow.flowComposer.swfContext = 
-                    ISWFContext(embeddedFontContext);
+                //_textFlow.flowComposer.swfContext = 
+                //    ISWFContext(embeddedFontContext);
             }
             
-            staticTextFlowFactory.swfContext = ISWFContext(embeddedFontContext);
+            //staticTextFlowFactory.swfContext = ISWFContext(embeddedFontContext);
             staticTextFlowFactory.createTextLines(addTextLine, _textFlow);
         }
         
         bounds = factory.getContentBounds();
-        setIsTruncated(factory.isTruncated);
+        //setIsTruncated(factory.isTruncated);
     }
-     */
 
     /**
      *  @private
@@ -1358,15 +1406,16 @@ public class RichText extends TextBase
     /**
      *  @private
      *  Callback passed to createTextLines().
-    private function addTextLine(textLine:DisplayObject):void
+     */
+    private function addTextLine(textLine:ITextLine):void
     {
         textLines.push(textLine);
     }
-     */
 
     /**
      *  @private
      *  Make sure to remove the damage handler before resetting the text flow.
+     */
     private function removeDamageHandler():void
     {
         // Could check factory is TextFlowTextLineFactory but be safe and 
@@ -1377,7 +1426,6 @@ public class RichText extends TextBase
                 textFlow_damageHandler);
         }
     }
-     */
 
     //--------------------------------------------------------------------------
     //
@@ -1390,6 +1438,7 @@ public class RichText extends TextBase
      *  Called when the TextFlow dispatches a 'damage' event
      *  to indicate it has been modified.  This could mean the styles changed
      *  or the content changed, or both changed.
+     */
     private function textFlow_damageHandler(event:DamageEvent):void
     {
         // If there are no changes to the generation, don't recompose.  
@@ -1410,18 +1459,17 @@ public class RichText extends TextBase
         factory = staticTextFlowFactory;
         
         // Force recompose since text and/or styles may have changed.
-        invalidateTextLines();
+        //invalidateTextLines();
         
         // We don't need to call invalidateProperties()
         // because the hostFormat and the _textFlow are still valid.
 
         // This is smart enough not to remeasure if the explicit width/height
         // were specified.
-        invalidateSize();
+        //invalidateSize();
         
-        invalidateDisplayList();  
+        //invalidateDisplayList();  
     }    
-     */
 }
 
 }
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as
index 43297a3..685cf0b 100644
--- a/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/components/supportClasses/TextBase.as
@@ -20,14 +20,16 @@
 package spark.components.supportClasses
 {
 
-/* import flash.display.DisplayObject;
+import org.apache.royale.geom.Rectangle;
+COMPILE::SWF
+{
+    import flash.display.DisplayObject;      
+}
+/*
 import flash.display.Graphics;
 import flash.display.Shape;
 import flash.events.Event;
-import flash.geom.Rectangle;
 import flash.text.engine.FontLookup;
-import flash.text.engine.TextLine;
-import flash.text.engine.TextLineValidity;
 
 import mx.core.IFlexModuleFactory;
 
@@ -37,7 +39,7 @@ import mx.resources.ResourceManager;
 import spark.core.IDisplayText;
 import spark.utils.TextUtil;
 
-import flashx.textLayout.compose.TextLineRecycler; */
+*/
 import mx.core.UIComponent;
 import mx.core.mx_internal;
 import mx.events.FlexEvent;
@@ -51,6 +53,10 @@ COMPILE::JS
     import org.apache.royale.html.util.addElementToWrapper;
     import org.apache.royale.core.WrappedHTMLElement;
 }
+import org.apache.royale.text.html.TextLine;
+import org.apache.royale.text.engine.ITextLine;
+import org.apache.royale.text.engine.TextLineValidity;
+import org.apache.royale.textLayout.compose.TextLineRecycler;
 import org.apache.royale.core.ITextModel;
 
 use namespace mx_internal;
@@ -201,16 +207,15 @@ public class TextBase extends UIComponent
      *  @private
      *  The composition bounds used when creating the TextLines.
      */
-   // mx_internal var bounds:Rectangle = new Rectangle(0, 0, NaN, NaN);
+    mx_internal var bounds:Rectangle = new Rectangle(0, 0, NaN, NaN);
 
     /**
      *  @private
 	 *  The TextLines and Shapes created to render the text.
 	 *  (Shapes are used to render the backgroundColor format for RichText.)
      */
-   /*  mx_internal var textLines:Vector.<DisplayObject> =
-    	new Vector.<DisplayObject>();
- */
+    mx_internal var textLines:Array = []; //Vector.<DisplayObject> = new Vector.<DisplayObject>();
+ 
     /**
      *  @private
      *  This flag is set to true if the text must be clipped.
@@ -236,13 +241,13 @@ public class TextBase extends UIComponent
      *  @private
      *  The value of bounds.width, before the compose was done.
      */
-  //  mx_internal var _composeWidth:Number;
+    mx_internal var _composeWidth:Number;
 
     /**
      *  @private
      *  The value of bounds.height, before the compose was done.
      */
-   // mx_internal var _composeHeight:Number;
+    mx_internal var _composeHeight:Number;
     
     /**
      *  @private
@@ -949,22 +954,24 @@ public class TextBase extends UIComponent
      *  @private
      *  Returns false to indicate no lines were composed.
      */
-    /* mx_internal function composeTextLines(width:Number = NaN,
+    mx_internal function composeTextLines(width:Number = NaN,
 										height:Number = NaN):Boolean
 	{
 	    _composeWidth = width;
 	    _composeHeight = height;
-	    
+	 
+        /*
 	    setIsTruncated(false);
+        */
 	    
 	    return false;
-	} */
+	}
 
 	/**
 	 *  @private
 	 *  Adds the TextLines created by composeTextLines() to this container.
 	 */
-	/* mx_internal function addTextLines():void
+	mx_internal function addTextLines():void
 	{
 		var n:int = textLines.length;
         if (n == 0)
@@ -972,11 +979,18 @@ public class TextBase extends UIComponent
 
         for (var i:int = n - 1; i >= 0; i--)
         {
-            var textLine:DisplayObject = textLines[i];		
+            var textLine:ITextLine = textLines[i];
             // Add new TextLine accounting for our background Shape.
-            $addChildAt(textLine, 1);
+            COMPILE::SWF
+            {
+                $addChildAt(textLine as DisplayObject, 1);
+            }
+            COMPILE::JS
+            {
+                addElementAt(textLine, 1);
+            }
         }
-	} */
+	}
 
 	/**
 	 *  @private
@@ -985,7 +999,7 @@ public class TextBase extends UIComponent
      * 
 	 *  This does not empty the textLines Array.
 	 */
-	/* mx_internal function removeTextLines():void
+	mx_internal function removeTextLines():void
 	{
 		var n:int = textLines.length;		
 		if (n == 0)
@@ -993,19 +1007,28 @@ public class TextBase extends UIComponent
 
 		for (var i:int = 0; i < n; i++)
 		{
-			var textLine:DisplayObject = textLines[i];	
+			var textLine:ITextLine = textLines[i];	
             var parent:UIComponent = textLine.parent as UIComponent;
             if (parent)
-                UIComponent(textLine.parent).$removeChild(textLine);
+            {
+                COMPILE::SWF
+                {
+                    UIComponent(textLine.parent).$removeChild(textLine as DisplayObject);                        
+                }
+                COMPILE::JS
+                {
+                    UIComponent(textLine.parent).removeElement(textLine);                        
+                }
+            }
 		}
-	} */
+	}
 
     /**
      *  @private
      *  Adds the TextLines to the reuse cache, and clears the textLines array.
      */
-    /* mx_internal function releaseTextLines(
-    	textLinesVector:Vector.<DisplayObject> = null):void
+    mx_internal function releaseTextLines(
+    	textLinesVector:Array = null):void
     {
         if (!textLinesVector)
             textLinesVector = textLines;
@@ -1030,7 +1053,7 @@ public class TextBase extends UIComponent
         }
         
         textLinesVector.length = 0;
-   } */
+   }
     
     /**
      *  @private
diff --git a/frameworks/projects/SparkRoyale/src/main/royale/spark/core/CSSTextLayoutFormat.as b/frameworks/projects/SparkRoyale/src/main/royale/spark/core/CSSTextLayoutFormat.as
new file mode 100644
index 0000000..c7db0ba
--- /dev/null
+++ b/frameworks/projects/SparkRoyale/src/main/royale/spark/core/CSSTextLayoutFormat.as
@@ -0,0 +1,153 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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.core
+{
+    
+    import org.apache.royale.text.engine.FontLookup;
+    import org.apache.royale.text.engine.Kerning;
+    import org.apache.royale.textLayout.formats.TextLayoutFormat;
+    import org.apache.royale.textLayout.property.Property;
+    //import org.apache.royale.textLayout.tlf_internal;
+    import mx.core.mx_internal;
+    import mx.styles.IStyleClient;
+    
+    [ExcludeClass]
+    
+    /**
+     *  @private
+     *  This class is used by components such as RichText
+     *  and RichEditableText which use TLF to display their text.
+     *  The default formatting for their text is determined
+     *  by the component's CSS styles.
+     *
+     *  TLF recognizes the copy that is done in this constructor and does not
+     *  do another one. If TLF adds formats to TextLayoutFormats this should
+     *  continue to work as long as Flex doesn't want some alterate behavior.
+     *
+     *  The only extra functionality supported here, beyond what TLF has,
+     *  is the ability for the fontLookup style to have the value "auto";
+     *  in this case, the client object's embeddedFontContext is used
+     *  to determine whether the the fontLookup format in TLF should be
+     *  "embeddedCFF" or "device".
+     */
+    public class CSSTextLayoutFormat extends TextLayoutFormat
+    {
+//        include "../core/Version.as";
+        
+        //--------------------------------------------------------------------------
+        //
+        //  Constructor
+        //
+        //--------------------------------------------------------------------------
+        
+        /**
+         *  @private
+         *  Constructor
+         */
+        public function CSSTextLayoutFormat(client:IStyleClient)
+        {
+            super();
+            
+            for each (var prop:Property in TextLayoutFormat.description)
+            {
+                const propName:String = prop.name;
+                if (propName == "fontLookup")
+                {
+                    this[propName] = convertedFontLookup(client);
+                }
+                else if (propName == "kerning")
+                {
+                    this[propName] = convertedKerning(client);
+                }
+                else
+                {
+                    const value:* = client.getStyle(propName);
+                    if (value !== undefined)
+                        this[propName] = value;
+                }
+            }		
+        }
+        
+        
+        /**
+         *  @private
+         */
+        private static function convertedFontLookup(client:IStyleClient):*
+        {
+            var value:String = client.getStyle("fontLookup");
+            
+            // Special processing of the "auto" value is required,
+            // because this value has meaning only in Flex, not in TLF.
+            // It tells Flex to use its EmbeddedFontRegistry to determine
+            // whether the font is embedded or not.
+            if (value == "auto")
+            {
+                if (client.mx_internal::embeddedFontContext)
+                    value = FontLookup.EMBEDDED_CFF;
+                else
+                    value = FontLookup.DEVICE;
+            }
+            
+            return value;
+        }
+        
+        
+        /**
+         *  @private
+         */
+        private static function convertedKerning(client:IStyleClient):*
+        {
+            var kerning:Object = client.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;
+            
+            return kerning;
+        }
+    }
+    
+}
+