Created
July 24, 2012 03:20
-
-
Save jamikado/3167820 to your computer and use it in GitHub Desktop.
TLFSprite is a Starling extension that provides an alternative to starling.text.TextField to render text from OpenType or TrueType fonts (both device and embedded CFF) using the Text Layout Framework instead of flash.text.TextField
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ================================================================================================= | |
// | |
// based on starling.text.TextField | |
// modified to use text layout framework engine for rendering text | |
// | |
// ================================================================================================= | |
package starling.extensions | |
{ | |
import flash.display.BitmapData; | |
import flash.display.DisplayObject; | |
import flash.geom.Matrix; | |
import flash.geom.Rectangle; | |
import flashx.textLayout.conversion.TextConverter; | |
import flashx.textLayout.elements.TextFlow; | |
import flashx.textLayout.factory.TextFlowTextLineFactory; | |
import flashx.textLayout.factory.TruncationOptions; | |
import flashx.textLayout.formats.ITextLayoutFormat; | |
import flashx.textLayout.formats.TextLayoutFormat; | |
import starling.core.RenderSupport; | |
import starling.core.Starling; | |
import starling.display.DisplayObject; | |
import starling.display.DisplayObjectContainer; | |
import starling.display.Image; | |
import starling.display.Quad; | |
import starling.display.Sprite; | |
import starling.events.Event; | |
import starling.textures.Texture; | |
import starling.textures.TextureSmoothing; | |
/** A TLFSprite displays text, using standard open type or true type fonts. | |
* | |
* Rendering is done with a backing of the text layout framework engine as opposed | |
* to the classic flash.text.TextField as the standard starling.text.TextField employs. | |
* | |
* If relying on embedded font use ensure TextLayoutFormat.fontLookup is set to FontLookup.EMBEDDED_CFF, | |
* this defaults to FontLookup.DEVICE, expecting device fonts. | |
* | |
* Additionally, note that TLF expects embedded fonts with CFF, embedAsCFF="true" unlike | |
* classic TextField which uses embedded fonts with CFF disabled, embedAsCFF="false" | |
* | |
* Download and find out more about the latest Text Layout Framework at | |
* <a href="http://sourceforge.net/adobe/tlf/home/Home/">Text Layout Framework</a> | |
*/ | |
public class TLFSprite extends Sprite | |
{ | |
private var mTextFlow:TextFlow; | |
private var mFormat:TextLayoutFormat; | |
private var mRequiresRedraw:Boolean; | |
private var mBorder:DisplayObjectContainer; | |
private var mImage:Image; | |
private var mSmoothing:String; | |
private var mTruncationOptions:TruncationOptions; | |
private var mCompositionBounds:Rectangle; | |
// TLF rendering objects | |
private static var sTextLineFactory:TextFlowTextLineFactory; | |
private static var sTextLinesOrShapes:Vector.<flash.display.DisplayObject>; | |
private static var sHelperMatrix:Matrix = new Matrix(); | |
/** Creates a TLFSprite from plain text. | |
* Optionally providing default formatting with TextLayoutFormat and composition | |
* width and height to limit active drawing area for rendering text | |
* */ | |
public static function fromPlainText(text:String, format:TextLayoutFormat = null, | |
compositionWidth:Number = 2048, compositionHeight:Number = 2048):TLFSprite | |
{ | |
return fromFormat(text, TextConverter.PLAIN_TEXT_FORMAT, format, compositionWidth, compositionHeight); | |
} | |
/** Creates a TLFSprite from a string of HTML text, limited by the HTML tags the TLF engine supports. | |
* See the Text Layout Framework documentation for supported tags. | |
* | |
* Optionally providing default formatting with TextLayoutFormat and composition | |
* width and height to limit active drawing area for rendering text | |
* */ | |
public static function fromHTML(htmlString:String, format:TextLayoutFormat = null, | |
compositionWidth:Number = 2048, compositionHeight:Number = 2048):TLFSprite | |
{ | |
return fromFormat(htmlString, TextConverter.TEXT_FIELD_HTML_FORMAT, format, compositionWidth, compositionHeight); | |
} | |
/** Creates a TLFSprite from a string of text layout XML text, limited by the XML tags the TLF engine supports. | |
* See the Text Layout Framework documentation for supported tags. | |
* | |
* Optionally providing default formatting with TextLayoutFormat and composition | |
* width and height to limit active drawing area for rendering text | |
* */ | |
public static function fromTextLayout(layoutXMLString:String, format:TextLayoutFormat = null, | |
compositionWidth:Number = 2048, compositionHeight:Number = 2048):TLFSprite | |
{ | |
return fromFormat(layoutXMLString, TextConverter.TEXT_LAYOUT_FORMAT, format, compositionWidth, compositionHeight); | |
} | |
private static function fromFormat(text:String, type:String, format:TextLayoutFormat = null, | |
compositionWidth:Number = 2048, compositionHeight:Number = 2048):TLFSprite | |
{ | |
var tlfSprite:TLFSprite = null; | |
var textFlow:TextFlow = TextConverter.importToFlow(text ? text : "", type); | |
if (textFlow) | |
tlfSprite = new TLFSprite(textFlow, format, compositionWidth, compositionHeight); | |
return tlfSprite; | |
} | |
/** | |
* Basic constructor that takes an already constructed TLF TextFlow with optional | |
* default format and composition limits | |
* | |
* See the static helper methods for quickly instantiating a TLFSprite from | |
* a simple plain text unformatted string, HTML or TLF text layout markup. | |
* */ | |
public function TLFSprite(textFlow:TextFlow, format:TextLayoutFormat = null, | |
compositionWidth:Number = 2048, compositionHeight:Number = 2048) | |
{ | |
super(); | |
initTLF(); | |
mTextFlow = textFlow; | |
mTruncationOptions = new TruncationOptions(); | |
mCompositionBounds = new Rectangle( 0, 0, compositionWidth, compositionHeight); | |
if (format) mFormat = format; | |
else { | |
mFormat = new TextLayoutFormat(); | |
} | |
mSmoothing = TextureSmoothing.BILINEAR; | |
addEventListener(Event.FLATTEN, onFlatten); | |
mRequiresRedraw = true; | |
} | |
/** Disposes the underlying texture data. */ | |
public override function dispose():void | |
{ | |
removeEventListener(Event.FLATTEN, onFlatten); | |
if (mImage) mImage.texture.dispose(); | |
super.dispose(); | |
} | |
private function onFlatten(event:Event):void | |
{ | |
if (mRequiresRedraw) redrawContents(); | |
} | |
/** @inheritDoc */ | |
public override function render(support:RenderSupport, parentAlpha:Number):void | |
{ | |
if (mRequiresRedraw) redrawContents(); | |
super.render(support, parentAlpha); | |
} | |
private function redrawContents():void | |
{ | |
createRenderedContents(); | |
mRequiresRedraw = false; | |
} | |
private function createRenderedContents():void | |
{ | |
var scale:Number = Starling.contentScaleFactor; | |
var bitmapData:BitmapData = createRenderedBitmap(); | |
if (!bitmapData) return; | |
var texture:Texture = Texture.fromBitmapData(bitmapData, false, false, scale); | |
if (mImage == null) | |
{ | |
mImage = new Image(texture); | |
mImage.touchable = false; | |
mImage.smoothing = mSmoothing; | |
addChild(mImage); | |
} | |
else | |
{ | |
if (mImage.texture) mImage.texture.dispose(); | |
mImage.texture = texture; | |
mImage.readjustSize(); | |
} | |
updateBorder(); | |
} | |
/** public in case one wants to use this class as a pipeline for | |
* creating bitmap data outside the typical end use of a sprite's texture | |
* */ | |
public function createRenderedBitmap():BitmapData | |
{ | |
if (!mTextFlow) return null; | |
var scale:Number = Starling.contentScaleFactor; | |
// clear out any existing text lines or shapes | |
sTextLinesOrShapes.length = 0; | |
sTextLineFactory.compositionBounds = mCompositionBounds; | |
sTextLineFactory.truncationOptions = mTruncationOptions; | |
// NOTE: so that we function similar to Starling's TextField that hides | |
// the fontSize scaling of Starling.contentScaleFactor internally, | |
// we temporarily also scale up the format's fontSize setting only | |
// to then reset it when finished | |
if (scale != 1.0) { | |
var origFontSize:* = mFormat.fontSize; | |
mFormat.fontSize = Math.max(1, Math.min(720, | |
(origFontSize == undefined ? 12 : origFontSize as Number)*scale)); | |
} | |
mTextFlow.hostFormat = mFormat; | |
sTextLineFactory.createTextLines( generatedTextLineOrShape, mTextFlow); | |
// after lines are generated we can ask the factory for the content | |
// bounds that encompasses the current line renderings | |
var contentBounds:Rectangle = sTextLineFactory.getContentBounds(); | |
// Reset modified fontSize value | |
if (scale != 1.0) mFormat.fontSize = origFontSize; | |
var textWidth:Number = Math.min(2048, contentBounds.width*scale); | |
var textHeight:Number = Math.min(2048, contentBounds.height*scale); | |
var bitmapData:BitmapData = new BitmapData(textWidth, textHeight, true, 0x0); | |
// draw each text line or shape into bitmap | |
var lineOrShape:flash.display.DisplayObject; | |
for (var i:int = 0; i < sTextLinesOrShapes.length; ++i) { | |
lineOrShape = sTextLinesOrShapes[i]; | |
sHelperMatrix.setTo(scale, 0, 0, scale, | |
(lineOrShape.x - contentBounds.x)*scale, (lineOrShape.y - contentBounds.y)*scale); | |
bitmapData.draw(lineOrShape, sHelperMatrix); | |
} | |
// finished need for generated lines or shapes | |
sTextLinesOrShapes.length = 0; | |
return bitmapData; | |
} | |
private static function initTLF():void | |
{ | |
if (sTextLineFactory == null) { | |
sTextLineFactory = new TextFlowTextLineFactory(); | |
sTextLinesOrShapes = new <flash.display.DisplayObject>[]; | |
} | |
} | |
/** generated TextLines or Shapes (from background colors etc..) | |
* get added to a collected vector of results | |
* */ | |
private function generatedTextLineOrShape( lineOrShape:flash.display.DisplayObject ):void | |
{ | |
sTextLinesOrShapes.push(lineOrShape); | |
} | |
private function updateBorder():void | |
{ | |
if (mBorder == null || mImage == null) return; | |
var width:Number = mImage.width; | |
var height:Number = mImage.height; | |
var topLine:Quad = mBorder.getChildAt(0) as Quad; | |
var rightLine:Quad = mBorder.getChildAt(1) as Quad; | |
var bottomLine:Quad = mBorder.getChildAt(2) as Quad; | |
var leftLine:Quad = mBorder.getChildAt(3) as Quad; | |
topLine.width = width; topLine.height = 1; | |
bottomLine.width = width; bottomLine.height = 1; | |
leftLine.width = 1; leftLine.height = height; | |
rightLine.width = 1; rightLine.height = height; | |
rightLine.x = width - 1; | |
bottomLine.y = height - 1; | |
topLine.color = rightLine.color = bottomLine.color = leftLine.color = mFormat.color; | |
} | |
/** @inheritDoc */ | |
public override function getBounds(targetSpace:starling.display.DisplayObject, resultRect:Rectangle=null):Rectangle | |
{ | |
return mImage.getBounds(targetSpace, resultRect); | |
} | |
/** Calling set text makes the assumption that you now expect only | |
* simple content with external formats and completely replace any | |
* previously set content, plain text, html or otherwise | |
* */ | |
public function set text(value:String):void | |
{ | |
mTextFlow = TextConverter.importToFlow(value ? value : "", TextConverter.PLAIN_TEXT_FORMAT); | |
mRequiresRedraw = true; | |
} | |
/** Calling set html makes the assumption that you now expect | |
* HTML content and completely replace any | |
* previously set content, plain text, html or otherwise | |
* */ | |
public function set html(value:String):void | |
{ | |
mTextFlow = TextConverter.importToFlow(value ? value : "", TextConverter.TEXT_FIELD_HTML_FORMAT); | |
mRequiresRedraw = true; | |
} | |
/** Calling set textLayout makes the assumption that you now expect | |
* Text layout markup content and completely replace any | |
* previously set content, plain text, html or otherwise | |
* */ | |
public function set textLayout(value:String):void | |
{ | |
mTextFlow = TextConverter.importToFlow(value ? value : "", TextConverter.TEXT_LAYOUT_FORMAT); | |
mRequiresRedraw = true; | |
} | |
public function get compositionWidth():Number {return mCompositionBounds.width;} | |
public function set compositionWidth(value:Number):void | |
{ | |
if (value != mCompositionBounds.width) { | |
mCompositionBounds.width = value; | |
mRequiresRedraw = true; | |
} | |
} | |
public function get compositionHeight():Number {return mCompositionBounds.height;} | |
public function set compositionHeight(value:Number):void | |
{ | |
if (value != mCompositionBounds.height) { | |
mCompositionBounds.height = value; | |
mRequiresRedraw = true; | |
} | |
} | |
public function get truncationOptions():TruncationOptions {return mTruncationOptions;} | |
public function set truncationOptions(value:TruncationOptions):void | |
{ | |
mTruncationOptions = value; | |
mRequiresRedraw = true; | |
} | |
/** Draws a border around the edges of the text field. Useful for visual debugging. | |
* @default false */ | |
public function get border():Boolean { return mBorder != null; } | |
public function set border(value:Boolean):void | |
{ | |
if (value && mBorder == null) | |
{ | |
mBorder = new Sprite(); | |
addChild(mBorder); | |
for (var i:int=0; i<4; ++i) | |
mBorder.addChild(new Quad(1.0, 1.0)); | |
updateBorder(); | |
} | |
else if (!value && mBorder != null) | |
{ | |
mBorder.removeFromParent(true); | |
mBorder = null; | |
} | |
} | |
/** The smoothing filter that is used for the image texture. | |
* @default bilinear | |
* @see starling.textures.TextureSmoothing */ | |
public function get smoothing():String { return mSmoothing; } | |
public function set smoothing(value:String):void | |
{ | |
if (TextureSmoothing.isValid(value)) { | |
mSmoothing = value; | |
if (mImage) mImage.smoothing = mSmoothing; | |
} | |
else | |
throw new ArgumentError("Invalid smoothing mode: " + value); | |
} | |
/** Returns the value of the style specified by the <code>styleProp</code> parameter, which specifies | |
* the style name from the text's TextLayoutFormat. | |
* | |
* @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. | |
*/ | |
public function getStyle(styleProp:String):* | |
{ | |
return mFormat.getStyle(styleProp); | |
} | |
/** Sets the style specified by the <code>styleProp</code> parameter to the value specified by the | |
* <code>newValue</code> parameter. | |
* | |
* Contents are redrawn with the updated property changes on the next render. | |
* | |
* @param styleProp The name of the style to set. | |
* @param newValue The value to which to set the style. | |
*/ | |
public function setStyle(styleProp:String,newValue:*):void | |
{ | |
mFormat.setStyle(styleProp, newValue); | |
mRequiresRedraw = true; | |
} | |
/** Returns the styles on this text's TextLayoutFormat. Note that the getter makes a copy of the | |
* styles dictionary. The coreStyles object encapsulates all styles set in the format property including core and user styles. The | |
* returned object consists of an array of <em>stylename-value</em> pairs. | |
* | |
* @see flashx.textLayout.formats.TextLayoutFormat | |
*/ | |
public function get styles():Object | |
{ | |
return mFormat.styles; | |
} | |
/** | |
* Replaces property values in this text's TextLayoutFormat object with the values of properties that are set in | |
* the <code>incoming</code> ITextLayoutFormat instance. Properties that are <code>undefined</code> in the <code>incoming</code> | |
* ITextLayoutFormat instance are not changed in this object. | |
* | |
* Contents are redrawn with the updated property changes on the next render. | |
* | |
* @param incoming instance whose property values are applied to this text's TextLayoutFormat object. | |
*/ | |
public function apply(incoming:ITextLayoutFormat):void | |
{ | |
mFormat.apply(incoming); | |
mRequiresRedraw = true; | |
} | |
/** | |
* Concatenates the values of properties in the <code>incoming</code> ITextLayoutFormat instance | |
* with the values of this text's TextLayoutFormat object. In this (the receiving) TextLayoutFormat object, properties whose values are <code>FormatValue.INHERIT</code>, | |
* and inheriting properties whose values are <code>undefined</code> will get new values from the <code>incoming</code> object. | |
* Non-inheriting properties whose values are <code>undefined</code> will get their default values. | |
* All other property values will remain unmodified. | |
* | |
* Contents are redrawn with the updated property changes on the next render. | |
* | |
* @param incoming instance from which values are concatenated. | |
*/ | |
public function concat(incoming:ITextLayoutFormat):void | |
{ | |
mFormat.concat(incoming); | |
mRequiresRedraw = true; | |
} | |
/** | |
* Concatenates the values of properties in the <code>incoming</code> ITextLayoutFormat instance | |
* with the values of this text's TextLayoutFormat object. In this (the receiving) TextLayoutFormat object, properties whose values are <code>FormatValue.INHERIT</code>, | |
* and inheriting properties whose values are <code>undefined</code> will get new values from the <code>incoming</code> object. | |
* All other property values will remain unmodified. | |
* | |
* Contents are redrawn with the updated property changes on the next render. | |
* | |
* @param incoming instance from which values are concatenated. | |
*/ | |
public function concatInheritOnly(incoming:ITextLayoutFormat):void | |
{ | |
mFormat.concatInheritOnly(incoming); | |
mRequiresRedraw = true; | |
} | |
/** | |
* Copies TextLayoutFormat settings from the <code>values</code> ITextLayoutFormat instance into this text's TextLayoutFormat object. | |
* If <code>values</code> is <code>null</code>, this TextLayoutFormat object is initialized with undefined values for all properties. | |
* | |
* Contents are redrawn with the updated property changes on the next render. | |
* | |
* @param values optional instance from which to copy values. | |
*/ | |
public function copy(incoming:ITextLayoutFormat):void | |
{ | |
mFormat.copy(incoming); | |
mRequiresRedraw = true; | |
} | |
/** | |
* Sets properties in this text's TextLayoutFormat object to <code>undefined</code> if they do not match those in the | |
* <code>incoming</code> ITextLayoutFormat instance. | |
* | |
* Contents are redrawn with the updated property changes on the next render. | |
* | |
* @param incoming instance against which to compare this TextLayoutFormat object's property values. | |
*/ | |
public function removeClashing(incoming:ITextLayoutFormat):void | |
{ | |
mFormat.removeClashing(incoming); | |
mRequiresRedraw = true; | |
} | |
/** | |
* Sets properties in this text's TextLayoutFormat object to <code>undefined</code> if they match those in the <code>incoming</code> | |
* ITextLayoutFormat instance. | |
* | |
* Contents are redrawn with the updated property changes on the next render. | |
* | |
* @param incoming instance against which to compare this TextLayoutFormat object's property values. | |
*/ | |
public function removeMatching(incoming:ITextLayoutFormat):void | |
{ | |
mFormat.removeMatching(incoming); | |
mRequiresRedraw = true; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Flat list of sample calls to creating TLFSprite instances and adding to a parent DisplayObjectContainer | |
// default TextLayoutFormat settings using static factory creation | |
var tlfSprite:TLFSprite = TLFSprite.fromPlainText("Hello World"); | |
tlfSprite.border = true; | |
tlfSprite.x = 10; | |
tlfSprite.y = 10; | |
addChild(tlfSprite); | |
tlfSprite = TLFSprite.fromPlainText("This is some larger\nline broken text"); | |
tlfSprite.border = true; | |
// post specify individual TextLayoutFormat style properties individually | |
tlfSprite.setStyle("fontSize", 32); | |
tlfSprite.setStyle("color", Color.RED); | |
tlfSprite.x = 50; | |
tlfSprite.y = 25; | |
addChild(tlfSprite); | |
tlfSprite = TLFSprite.fromPlainText("This is some larger line flow text"); | |
tlfSprite.border = true; | |
tlfSprite.setStyle("fontSize", 24); | |
tlfSprite.setStyle("color", Color.RED); | |
// forces truncation showing ellipses as default truncation indicator | |
tlfSprite.compositionWidth = 170; | |
tlfSprite.compositionHeight = 60; | |
tlfSprite.x = 350; | |
tlfSprite.y = 25; | |
addChild(tlfSprite); | |
// text layout framework supports some very simple HTML style markup | |
tlfSprite = TLFSprite.fromHTML("<p>Some <b>preformatted</b> <font size=28 color=0x00ff00>text with</font><br> some <i>simple</i> HTML markup."); | |
tlfSprite.border = true; | |
tlfSprite.x = 10; | |
tlfSprite.y = 110; | |
addChild(tlfSprite); | |
tlfSprite = TLFSprite.fromPlainText("Here we might want to limit the width this text should display, auto flowing"); | |
tlfSprite.border = true; | |
// Force a limit on width to trigger line breaking | |
tlfSprite.compositionWidth = 150; | |
tlfSprite.x = 10; | |
tlfSprite.y = 180; | |
addChild(tlfSprite); | |
// You can also use an XML markup tagging system from the text layout framework itself | |
// that allows basic paragraph and span elements using named TextLayoutFormat properties as attributes | |
tlfSprite = TLFSprite.fromTextLayout("<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'>" + | |
"<p><span fontSize='16'>Hello, World.</span></p><p><span color='0x0000FF' fontSize='18'>Some simple TLF markup</span></p></TextFlow>"); | |
tlfSprite.border = true; | |
tlfSprite.x = 300; | |
tlfSprite.y = 100; | |
addChild(tlfSprite); | |
// explicitly set multiple TextLayoutFormat properties at beginning and pass with creation | |
var textLayoutFormat:TextLayoutFormat = new TextLayoutFormat(); | |
textLayoutFormat.paragraphStartIndent = 15; | |
textLayoutFormat.paragraphSpaceBefore = 15; | |
textLayoutFormat.paragraphEndIndent = 15; | |
textLayoutFormat.paragraphSpaceAfter = 15; | |
textLayoutFormat.textIndent = 20; | |
textLayoutFormat.color = 0x336633; | |
textLayoutFormat.fontFamily = "Arial, Helvetica, _sans"; | |
textLayoutFormat.fontSize = 16; | |
textLayoutFormat.kerning = Kerning.ON; | |
textLayoutFormat.lineHeight = "100%"; | |
tlfSprite = TLFSprite.fromPlainText("This example formats a paragraph with 15 pixel margins, a 20 pixel first " + | |
"line indent. It uses the " + | |
"Arial font (with alternate device fonts), sets the size to 16 pixels, the color to green, " + | |
" turns on kerning, \n \t and sets leading (lineHeight) to 100%.", textLayoutFormat); | |
tlfSprite.border = true; | |
tlfSprite.compositionWidth = 450; | |
tlfSprite.x = 230; | |
tlfSprite.y = 150; | |
addChild(tlfSprite); | |
// Define east asian ideographic layout and formatting | |
// along with enforced composition height limit | |
textLayoutFormat = new TextLayoutFormat(); | |
// define Japanese text in a string of Unicode characters | |
var jaText:String = String.fromCharCode( | |
0x30AF, 0x30ED, 0x30B9, 0x30D7, 0x30E9, 0x30C3, 0x30C8, 0x30D5, | |
0x30A9, 0x30FC, 0x30E0, 0x4E0A, 0x3067, 0x518D, 0x751F, 0x53EF, | |
0x80FD, 0x306A) + | |
"Flash Video" + | |
String.fromCharCode( | |
0x3092, 0x914D, 0x4FE1, 0x3001, 0x653F, 0x5E9C, 0x6700, 0x65B0, | |
0x60C5, 0x5831, 0x3092, 0x3088, 0x308A, 0x591A, 0x304F, 0x306E, | |
0x56FD, 0x6C11, 0x306B, 0x9AD8, 0x54C1, 0x8CEA, 0x306A, 0x753B, | |
0x50CF, 0x3067, 0x7C21, 0x5358, 0x304B, 0x3064, 0x30EA, 0x30A2, | |
0x30EB, 0x30BF, 0x30A4, 0x30E0, 0x306B, 0x63D0, 0x4F9B, 0x3059, | |
0x308B, 0x3053, 0x3068, 0x304C, 0x53EF, 0x80FD, 0x306B, 0x306A, | |
0x308A, 0x307e, 0x3057, 0x305F, 0x3002); | |
textLayoutFormat.locale = "ja"; | |
if (Capabilities.os.search("Mac OS") > -1) | |
textLayoutFormat.fontFamily = String.fromCharCode(0x5C0F, 0x585A, 0x660E, 0x671D) + " Pro R"; // "Kozuka Mincho Pro R" | |
else | |
textLayoutFormat.fontFamily = "Kozuka Mincho Pro R"; | |
// specify right-to-left block progression, east Asian justification, and top vertical alignment | |
textLayoutFormat.blockProgression = BlockProgression.RL; | |
textLayoutFormat.justificationRule = JustificationRule.EAST_ASIAN; | |
textLayoutFormat.verticalAlign = VerticalAlign.TOP; | |
textLayoutFormat.fontSize = 18; | |
tlfSprite = TLFSprite.fromPlainText(jaText, textLayoutFormat); | |
tlfSprite.border = true; | |
tlfSprite.compositionHeight = 250; | |
tlfSprite.x = 30; | |
tlfSprite.y = 250; | |
addChild(tlfSprite); | |
// Arabic right-to-left language support | |
textLayoutFormat = new TextLayoutFormat(); | |
textLayoutFormat.fontFamily = "Arial"; | |
textLayoutFormat.fontSize = 24; | |
textLayoutFormat.paragraphSpaceBefore = 2; | |
textLayoutFormat.paragraphSpaceAfter = 2; | |
textLayoutFormat.paddingBottom = textLayoutFormat.paddingTop = | |
textLayoutFormat.paddingLeft = textLayoutFormat.paddingRight = 5; | |
textLayoutFormat.direction = Direction.RTL; | |
textLayoutFormat.blockProgression = BlockProgression.TB; | |
tlfSprite = TLFSprite.fromPlainText("وثيقة إثبات صلة القرابة مصدقة من سفارة دولة الإمارات – إذا لم يكن اسم المكفول مدرجاً في جواز سفر", textLayoutFormat); | |
tlfSprite.border = true; | |
tlfSprite.compositionWidth = 350; | |
tlfSprite.x = 220; | |
tlfSprite.y = 250; | |
addChild(tlfSprite); | |
// If you feel like it, you can also just build up your text layout framework | |
// TextFlow elements by hand | |
// create TextFlow, ParagraphElement, and SpanElement objects | |
var textFlow:TextFlow = new TextFlow(); | |
var p:ParagraphElement = new ParagraphElement(); | |
var span1:SpanElement = new SpanElement(); | |
var span2:SpanElement = new SpanElement(); | |
textLayoutFormat = new TextLayoutFormat(); | |
textLayoutFormat.color = 0x333333; | |
textLayoutFormat.textAlpha = 0.9; | |
textLayoutFormat.fontSize = 20; | |
textLayoutFormat.fontFamily = "Times Roman"; | |
// add text to the span, the span to the paragraph, and the paragraph to the text flow. | |
textFlow.format = textLayoutFormat; | |
span1.text = "This content was built by combining raw text flow elements together." | |
p.addChild( span1); | |
span2.text = "This is a second span in the paragraph." | |
span2.backgroundColor = 0xFF0000; | |
span2.backgroundAlpha = 0.6; | |
p.addChild( span2); | |
textFlow.addChild(p); | |
tlfSprite = new TLFSprite(textFlow, textLayoutFormat); | |
tlfSprite.border = true; | |
tlfSprite.compositionWidth = 350; | |
tlfSprite.x = 220; | |
tlfSprite.y = 360; | |
addChild(tlfSprite); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very useful! thanks for sharing this!