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;
+ }
+ }
+
+}
+