<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>guy in the chair . com &#187; FTE</title>
	<atom:link href="http://guyinthechair.com/tag/fte/feed/" rel="self" type="application/rss+xml" />
	<link>http://guyinthechair.com</link>
	<description>//the blog of Paul Taylor</description>
	<lastBuildDate>Fri, 18 Nov 2011 01:22:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>FTE Layout Tricks with BreakOpportunity.ALL</title>
		<link>http://guyinthechair.com/2011/06/fte-layout-tricks-with-breakopportunity-all/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fte-layout-tricks-with-breakopportunity-all</link>
		<comments>http://guyinthechair.com/2011/06/fte-layout-tricks-with-breakopportunity-all/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 05:48:58 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[breakOpportunity]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[FTE]]></category>
		<category><![CDATA[text layout]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=703</guid>
		<description><![CDATA[This should be a relatively short post, since it&#8217;s late and I&#8217;ve been drinking. I&#8217;m going to focus on just one property from ElementFormat: breakOpportunity. Cunning Line Breaks BreakOpportunity is relatively straightforward. It directs the Flash Text Engine of when to break new TextLines. It&#8217;s different from the standard unicode line breaking control character, the [...]]]></description>
			<content:encoded><![CDATA[<p>This should be a relatively short post, since it&#8217;s late and I&#8217;ve been drinking. I&#8217;m going to focus on just one property from <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/ElementFormat.html">ElementFormat</a>: <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/ElementFormat.html#breakOpportunity">breakOpportunity</a>.</p>
<h2>Cunning Line Breaks</h2>
<p><a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/BreakOpportunity.html">BreakOpportunity</a> is relatively straightforward. It directs the Flash Text Engine of when to break new TextLines. It&#8217;s different from the standard <a href="http://en.wikipedia.org/wiki/Newline">unicode line breaking control character</a>, the break-if-you-wanna <a href="http://en.wikipedia.org/wiki/Zero-width_space">Zero-width space character</a>, and it isn&#8217;t the <a href="http://en.wikipedia.org/wiki/Soft_hyphen">soft hyphen</a> used in auto-hyphenation engines.</p>
<p>BreakOpportunity is subtler. It gives you control over line breaks without inserting control characters into your content.</p>
<h2>Documentation</h2>
<p>Here&#8217;s the documentation of <code>breakOpportunity</code>. I&#8217;m pasting it here to illustrate that this doesn&#8217;t tell the whole story.</p>
<table>
<tbody>
<tr>
<th>String value</th>
<th>Description</th>
</tr>
<tr>
<td><code>BreakOpportunity.ALL</code></td>
<td>All characters in the range are treated as line break opportunities, meaning that a line break will occur after each character. Useful for creating effects like text on a path.</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th>Subclass</th>
<th>Effect of setting property</th>
</tr>
<tr>
<td><code>GraphicElement</code></td>
<td>Has no effect.</td>
</tr>
<tr>
<td><code>GroupElement</code></td>
<td>Determines the break opportunity between adjacent text elements in the group. If the elementFormat of the group is <code>null</code>, the format of the first of the adjacent elements is used.</td>
</tr>
<tr>
<td><code>TextElement</code></td>
<td>Determines the break opportunity between the characters in the text element.</td>
</tr>
</tbody>
</table>
<p><br/></p>
<h2>Standard Line Breaking</h2>
<p>I&#8217;ve posted this before, but here&#8217;s a refresher. Breaking lines in the Flash Text Engine couldn&#8217;t be easier:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">content</span><span style="color: #000066; font-weight: bold;">:</span>ContentElement = <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;Some example text to be broken into TextLine objects by a TextBlock instance.&quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> tb<span style="color: #000066; font-weight: bold;">:</span>TextBlock = <span style="color: #0033ff; font-weight: bold;">new</span> TextBlock<span style="color: #000000;">&#40;</span><span style="color: #004993;">content</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line <span style="color: #000066; font-weight: bold;">!</span>= <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
    line = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_0" width="200" height="36">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo_simple.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo_simple.swf" width="200" height="36">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<br/></p>
<h2>Tricks</h2>
<p>But what happens if we modify the breakOpportunity of the ElementFormat?</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> ef<span style="color: #000066; font-weight: bold;">:</span>ElementFormat = <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
ef<span style="color: #000066; font-weight: bold;">.</span>breakOpportunity = BreakOpportunity<span style="color: #000066; font-weight: bold;">.</span>ALL<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">content</span><span style="color: #000066; font-weight: bold;">:</span>ContentElement = <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;Some example text to be broken into TextLine objects by a TextBlock instance.&quot;</span><span style="color: #000066; font-weight: bold;">,</span> ef<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> tb<span style="color: #000066; font-weight: bold;">:</span>TextBlock = <span style="color: #0033ff; font-weight: bold;">new</span> TextBlock<span style="color: #000000;">&#40;</span><span style="color: #004993;">content</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line <span style="color: #000066; font-weight: bold;">!</span>= <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
    line = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p><br/><br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_1" width="200" height="920">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo16.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo16.swf" width="200" height="920">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<br/><br />
As you can see, when the ElementFormat for a TextElement has its breakOpportunity set to <code>BreakOpportunity.ALL</code>, the TextBlock breaks a new TextLine instance after each character. Crazy right?</p>
<p>When I figured this out about 9 months ago, my next thought was to test how GroupElement responds to BreakOpportunity:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> ef<span style="color: #000066; font-weight: bold;">:</span>ElementFormat = <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
ef<span style="color: #000066; font-weight: bold;">.</span>breakOpportunity = BreakOpportunity<span style="color: #000066; font-weight: bold;">.</span>ALL<span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> group<span style="color: #000066; font-weight: bold;">:</span>GroupElement = <span style="color: #0033ff; font-weight: bold;">new</span> GroupElement<span style="color: #000000;">&#40;</span>
    <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">&lt;</span>ContentElement<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#91;</span>
    <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;Some example text &quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
    <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;to be broken into &quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
    <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;TextLine objects by &quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
    <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;a TextBlock instance.&quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
    <span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">,</span> ef<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> tb<span style="color: #000066; font-weight: bold;">:</span>TextBlock = <span style="color: #0033ff; font-weight: bold;">new</span> TextBlock<span style="color: #000000;">&#40;</span>group<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line <span style="color: #000066; font-weight: bold;">!</span>= <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
    line = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_2" width="100" height="46">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo17.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo17.swf" width="100" height="46">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<br/><br />
Sweet. So it does what the documentation says it&#8217;ll do, break between adjacent TextElements. But is it only TextElements? What about adjacent GraphicElements?</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> ef<span style="color: #000066; font-weight: bold;">:</span>ElementFormat = <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
ef<span style="color: #000066; font-weight: bold;">.</span>breakOpportunity = BreakOpportunity<span style="color: #000066; font-weight: bold;">.</span>ALL<span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> group<span style="color: #000066; font-weight: bold;">:</span>GroupElement = <span style="color: #0033ff; font-weight: bold;">new</span> GroupElement<span style="color: #000000;">&#40;</span>
    <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">&lt;</span>ContentElement<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#91;</span>
        <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;Some example text &quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
        <span style="color: #0033ff; font-weight: bold;">new</span> GraphicElement<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">new</span> GraphicRect<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">20</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">20</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
        <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;with GraphicElements &quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
        <span style="color: #0033ff; font-weight: bold;">new</span> GraphicElement<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">new</span> GraphicRect<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">20</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">20</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
        <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;to be broken into &quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
        <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;TextLine objects by &quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
        <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;a TextBlock instance.&quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span>
    <span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">,</span> ef<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> tb<span style="color: #000066; font-weight: bold;">:</span>TextBlock = <span style="color: #0033ff; font-weight: bold;">new</span> TextBlock<span style="color: #000000;">&#40;</span>group<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line <span style="color: #000066; font-weight: bold;">!</span>= <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span>totalHeight<span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    line = tb<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_3" width="102" height="100">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo18.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2011/06/FTEDemo18.swf" width="102" height="100">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<br/><br />
Ah ha! So it doesn&#8217;t only work for TextElements, it works for any siblings enclosed in a GroupElement. Good to know. Can you imagine the implications of this? (hint, this is important for rendering floats using the FTE!)</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2011/06/fte-layout-tricks-with-breakopportunity-all/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The FTE Part 4: Advanced Layout Techniques</title>
		<link>http://guyinthechair.com/2010/10/the-fte-part-4-advanced-layout-techniques/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-fte-part-4-advanced-layout-techniques</link>
		<comments>http://guyinthechair.com/2010/10/the-fte-part-4-advanced-layout-techniques/#comments</comments>
		<pubDate>Sun, 10 Oct 2010 11:07:51 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[misc]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[FTE]]></category>
		<category><![CDATA[text layout]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=583</guid>
		<description><![CDATA[This is part four in an ongoing series about the Flash Text Engine. You can see the previous entries here. You should know, this series isn&#8217;t about Adobe&#8217;s Text Layout Framework, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that TLF is built on. In Flash [...]]]></description>
			<content:encoded><![CDATA[<p>This is part four in an ongoing series about the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/package-detail.html" title="FTE" target="_blank">Flash Text Engine</a>. You can see the previous entries <a href="http://guyinthechair.com/tag/fte/" target="_blank">here</a>.</p>
<p style="padding-left: 15px; padding-right: 15px; color: #999999;">You should know, this series isn&#8217;t about <a href="http://labs.adobe.com/technologies/textlayout/">Adobe&#8217;s Text Layout Framework</a>, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that TLF is built on. In Flash Player 10, the FTE resides in the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/package-detail.html" target="_blank">flash.text.engine</a> package.</p>
<h2>Advanced Text Rendering</h2>
<p>The FTE may be low level, but that affords developers like you and me serious control over the presentation of our text fields. The FTE renders glyphs into a series of TextLines, but forces us to handle the sizing and layout of the lines. Today, I&#8217;ll cover how to efficiently create and position lines. For simplicity&#8217;s sake, I&#8217;ll assume the TextLines&#8217; widths extend to the edges of the Container they are rendered into.</p>
<p>In this post I&#8217;ll cover:</p>
<ul>
<li>text flow across containers</li>
<li>container resizing</li>
<li>TextLine positioning, invalidation, and reuse</li>
</ul>
<h3>Caveats</h3>
<p>In order to keep this post relatively short, I&#8217;ve simplified the algorithms here down to the basic principles. This is a general description of the layout algorithms in tinytlf, though they are getting more complex by the day.</p>
<h2>Example</h2>
<p>Here&#8217;s the final product of what I&#8217;m going to walk through. <strong>Click on the text to resize the columns</strong>:</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_4" width="600" height="600" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/10/FTE_Resizing.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/10/FTE_Resizing.swf" width="600" height="600" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<h3>Defining the Problem</h3>
<p>From a layout perspective, we have a number of paragraphs that need to be rendered into a list of DisplayObjectContainers. When we run out of DisplayObjectContainers, we&#8217;re going to call it quits. What if we run out of lines before we&#8217;re done rendering containers? Good! It&#8217;s easy to quit when you don&#8217;t have any content left to render.</p>
<p>So what we need is a layout algorithm that will break TextLines from a Vector of TextBlocks across a list of DisplayObjectContainers (DOCs).</p>
<h3>Text Layout</h3>
<p>In order to coordinate the layout between paragraphs and containers, I&#8217;ve defined a controller I call <a href="http://guyinthechair.com/wp-content/uploads/2010/10/srcview/source/org/tinytlf/layout/TextLayout.as.html" title="Simplified TextLayout">TextLayout</a>. TextLayout&#8217;s job is to run through the list of TextBlocks, rendering as many lines as possible into the available DOCs. When the DOC is full, TextLayout moves to the next container. If there is no next container, TextLayout breaks out of the rendering algorithm. Similarly with TextBlocks, if we run out paragraphs to render, TextLayout breaks out of the layout algorithm.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #3f5fbf;">/**
 * Renders as many lines from the list of TextBlocks into the specified
 * conatiners as possible.
 */</span>
<span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> <span style="color: #004993;">render</span><span style="color: #000000;">&#40;</span>blocks<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>TextBlock<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000066; font-weight: bold;">!</span>containers <span style="color: #000066; font-weight: bold;">||</span> <span style="color: #000066; font-weight: bold;">!</span>containers<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span> <span style="color: #000066; font-weight: bold;">||</span> <span style="color: #000066; font-weight: bold;">!</span>blocks <span style="color: #000066; font-weight: bold;">||</span> <span style="color: #000066; font-weight: bold;">!</span>blocks<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000000;">&#41;</span>
		<span style="color: #0033ff; font-weight: bold;">return</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	containers<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">forEach</span><span style="color: #000000;">&#40;</span><span style="color: #339966; font-weight: bold;">function</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">c</span><span style="color: #000066; font-weight: bold;">:</span>TextContainer<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000066; font-weight: bold;">...</span>args<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><span style="color: #000000;">&#123;</span>
		<span style="color: #004993;">c</span><span style="color: #000066; font-weight: bold;">.</span>preLayout<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #6699cc; font-weight: bold;">var</span> block<span style="color: #000066; font-weight: bold;">:</span>TextBlock = blocks<span style="color: #000000;">&#91;</span><span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> i<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> container<span style="color: #000066; font-weight: bold;">:</span>TextContainer = containers<span style="color: #000000;">&#91;</span><span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">while</span> <span style="color: #000000;">&#40;</span>block <span style="color: #000066; font-weight: bold;">&amp;&amp;</span> container<span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		container = renderBlockAcrossContainers<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">,</span> container<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
		block = <span style="color: #000066; font-weight: bold;">++</span>i <span style="color: #000066; font-weight: bold;">&lt;</span> blocks<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span> <span style="color: #000066; font-weight: bold;">?</span> blocks<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span> <span style="color: #000066; font-weight: bold;">:</span> <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<h3>TextContainer</h3>
<p><a href="http://guyinthechair.com/wp-content/uploads/2010/10/srcview/source/org/tinytlf/layout/TextContainer.as.html">TextContainer</a> is a single DOC that renders TextLines. It is a layout controller that determines the positions and sizes of the TextLines inside himself.</p>
<p>TextContainer maintains a very important relationship with TextLayout&#8217;s rendering algorithm. TextLayout repeatedly calls the <strong>TextContainer.layout()</strong> method, passing in a TextBlock to render lines from, and optionally, the previous line that was rendered from the block. It is TextContainer&#8217;s responsibility to render as many lines from the TextBlock into itself until either, 1. the TextBlock has no lines left to render, or 2. the TextContainer is full and has no more room for additional TextLines.</p>
<p><strong>TextContainer.layout()</strong> should return the last line rendered from the TextBlock. Null is a valid value to return. If a (non-null) TextLine was returned, TextLayout assumes the TextContainer is full, finished rendering lines, and moves to the next TextContainer, keeping the same TextBlock. If TextContainer returns <strong>null</strong>, TextLayout assumes there&#8217;s still room in the TextContainer for lines, and TextLayout passes the next TextBlock to the TextContainer.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> layout<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">:</span>TextBlock<span style="color: #000066; font-weight: bold;">,</span> previousLine<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span>TextLine
<span style="color: #000000;">&#123;</span>
	_y = measuredHeight<span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = createTextLine<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">,</span> previousLine<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
		lines<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">push</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
		<span style="color: #004993;">position</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
		<span style="color: #009900; font-style: italic;">//If there's no room, return the last line broken.</span>
		<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>checkConstraints<span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			<span style="color: #0033ff; font-weight: bold;">return</span> line<span style="color: #000066; font-weight: bold;">;</span>
		<span style="color: #000000;">&#125;</span>
&nbsp;
		line = createTextLine<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">,</span> line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #009900; font-style: italic;">//This will be null here.</span>
	<span style="color: #0033ff; font-weight: bold;">return</span> line<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Line layout is straightforward. I&#8217;m sure you know what the <strong>position()</strong> and <strong>checkConstraints()</strong> methods do, and if not, the source is available <a href="http://guyinthechair.com/wp-content/uploads/2010/10/srcview/source/org/tinytlf/layout/TextContainer.as.html">here</a>.</p>
<p>This is good enough to work for the first layout pass, but resizing introduces a bit more complexity.</p>
<h2>TextLineValidity</h2>
<p>We can take advantage of an FTE TextBlock and TextLine feature to get resizing.</p>
<p>When the ContentElement &#8220;model&#8221; is updated, the TextLine &#8220;views&#8221; should updated to reflect the changes. But we as FTE users have no concept of the data behind each individual TextLines, so if we updated the screen, we&#8217;d have to start from the first line and re-create each one. This is extremely inefficient, especially if the change only reflected in one actual line update.</p>
<p>Luckily, the TextBlock can track and resolve such changes for you. Whenever anything in the TextBlock&#8217;s <strong>content</strong> member changes, the TextBlock marks relevant lines &#8220;invalid&#8221; (<a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/TextLineValidity.html#INVALID">TextLineValidity.INVALID</a>). The TextBlock exposes a pretty handy property called <strong>firstInvalidLine</strong>, which points to the first line in the TextBlock that needs updating. Look mom, no searching!</p>
<p>You can check the status of individual lines simply by reading the <strong>TextLine.validity</strong> property. Luckily, validity is also writeable, and the TextBlock respects our decision if we choose to mark certain lines &#8220;invalid&#8221; ourselves. I guess we know best!</p>
<h2>Resizing</h2>
<p>When a TextContainer is resized, we need to know about it and invalidate our TextLine children.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #6699cc; font-weight: bold;">var</span> explicitWidth<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #004993;">NaN</span><span style="color: #000066; font-weight: bold;">;</span>
override <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> <span style="color: #0033ff; font-weight: bold;">get</span> <span style="color: #004993;">width</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">return</span> explicitWidth<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span>
override <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> <span style="color: #0033ff; font-weight: bold;">set</span> <span style="color: #004993;">width</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">value</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">value</span> == explicitWidth<span style="color: #000000;">&#41;</span> <span style="color: #0033ff; font-weight: bold;">return</span><span style="color: #000066; font-weight: bold;">;</span>
	explicitWidth = <span style="color: #004993;">value</span><span style="color: #000066; font-weight: bold;">;</span>
	invalidateLines<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> invalidateLines<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
	lines<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">forEach</span><span style="color: #000000;">&#40;</span><span style="color: #339966; font-weight: bold;">function</span><span style="color: #000000;">&#40;</span>l<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000066; font-weight: bold;">...</span>args<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><span style="color: #000000;">&#123;</span>
		l<span style="color: #000066; font-weight: bold;">.</span>validity = TextLineValidity<span style="color: #000066; font-weight: bold;">.</span>INVALID<span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<h3>Line Reuse</h3>
<p>During the first layout pass, we use the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/TextBlock.html#createTextLine()">TextBlock.createTextLine</a> method exclusively. But TextLines are expensive to create, so Flash Player 10.1 introduced the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/TextBlock.html#recreateTextLine()">TextBlock.recreateTextLine</a> method. Allowing us to recreate TextLines means that the Flash Player can re-jigger the TextLine&#8217;s contents internally, without the overhead of creating a new TextLine instance.</p>
<p>During a resize operation, lines will be either created or destroyed. If you set the width smaller, the TextField will be forced to render new TextLines. If you set the width wider, the TextField can remove TextLines at the end. In the first case, we&#8217;ll have to make extra calls to <strong>TextBlock.createTextLine</strong>. In the second case, we can remove the TextLines from the display list and remove all references. In this case, the lines have been <strong>orphaned</strong>.</p>
<p>But with the introduction of <strong>recreateTextLine</strong>, it&#8217;s optimal to cache orphaned lines, at least for a little while. It&#8217;s possible that we will resize the TextField smaller again, which will require the creation of new lines. But if we&#8217;ve previously created lines, why not reuse them instead of creating new ones? Good thinking you.</p>
<p>However, this changes the meaning of the <strong>line</strong> argument in the <strong>TextContainer.layout</strong> method. Now, the line can either be:</p>
<ul>
<li>A valid and successfully broken TextLine, which should be used as the <strong>previousLine</strong> argument to create or re-create a TextLine.</li>
<li>An invalid TextLine that needs to be re-created. This should only happen in the case that the line is the <strong>TextBlock.firstLine</strong> value, because there is no previously broken valid TextLine. Since we don&#8217;t want to wipe out our orphan cache looking for a line, we can detect this case and recreate the line.</li>
<ul>
<p>This introduces just a bit more complexity, but luckily we can encapsulate it in the <strong>TextContainer.createTextLine</strong> method.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #3f5fbf;">/**
 * Creates or recreates a given TextLine.
 */</span>
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> createTextLine<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">:</span>TextBlock<span style="color: #000066; font-weight: bold;">,</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span>TextLine
<span style="color: #000000;">&#123;</span>
	removeOrphanedLines<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">.</span>validity === TextLineValidity<span style="color: #000066; font-weight: bold;">.</span>INVALID<span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			<span style="color: #0033ff; font-weight: bold;">return</span> block<span style="color: #000066; font-weight: bold;">.</span>recreateTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">width</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">0.0</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">true</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
		<span style="color: #000000;">&#125;</span>
		<span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>orphans<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000000;">&#41;</span>
		<span style="color: #000000;">&#123;</span>
			<span style="color: #6699cc; font-weight: bold;">var</span> orphan<span style="color: #000066; font-weight: bold;">:</span>TextLine = getFirstOrphan<span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
			<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>orphan<span style="color: #000000;">&#41;</span>
			<span style="color: #000000;">&#123;</span>
				<span style="color: #0033ff; font-weight: bold;">return</span> block<span style="color: #000066; font-weight: bold;">.</span>recreateTextLine<span style="color: #000000;">&#40;</span>orphan<span style="color: #000066; font-weight: bold;">,</span> line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">width</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">0.0</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">true</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
			<span style="color: #000000;">&#125;</span>
		<span style="color: #000000;">&#125;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">return</span> block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">width</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">0.0</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">true</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> removeOrphanedLines<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #6699cc; font-weight: bold;">var</span> n<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = lines<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">for</span><span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> i<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span> i <span style="color: #000066; font-weight: bold;">&lt;</span> n<span style="color: #000066; font-weight: bold;">;</span> <span style="color: #000066; font-weight: bold;">++</span>i<span style="color: #000000;">&#41;</span>
	<span style="color: #000000;">&#123;</span>
		line = lines<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
		<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">.</span>validity === TextLineValidity<span style="color: #000066; font-weight: bold;">.</span>VALID<span style="color: #000000;">&#41;</span>
			<span style="color: #0033ff; font-weight: bold;">continue</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
		<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">contains</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
			<span style="color: #004993;">removeChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
		lines<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">splice</span><span style="color: #000000;">&#40;</span>i<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">1</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
		orphans<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">push</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
		n = lines<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000066; font-weight: bold;">;</span>
	<span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #009900; font-style: italic;">//Static so it's shared between instances of TextContainer</span>
<span style="color: #0033ff; font-weight: bold;">private</span> static const orphans<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>TextLine<span style="color: #000066; font-weight: bold;">&gt;</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">&lt;</span>TextLine<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #3f5fbf;">/**
 * Returns the first invalid orphan that also isn't the input line.
 */</span>
<span style="color: #0033ff; font-weight: bold;">private</span> static <span style="color: #339966; font-weight: bold;">function</span> getFirstOrphan<span style="color: #000000;">&#40;</span>exceptForMe<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span>TextLine
<span style="color: #000000;">&#123;</span>
	<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>orphans<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span> == <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000000;">&#41;</span>
		<span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #6699cc; font-weight: bold;">var</span> orphan<span style="color: #000066; font-weight: bold;">:</span>TextLine = orphans<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">pop</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>orphan == exceptForMe<span style="color: #000000;">&#41;</span>
		orphan = orphans<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">pop</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>orphan <span style="color: #000066; font-weight: bold;">&amp;&amp;</span> orphan<span style="color: #000066; font-weight: bold;">.</span>validity == TextLineValidity<span style="color: #000066; font-weight: bold;">.</span>VALID<span style="color: #000000;">&#41;</span>
		orphan = orphans<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">pop</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
	<span style="color: #0033ff; font-weight: bold;">return</span> orphan<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>Because we can possibly recreate TextLines without calling <strong>getFirstOrphan</strong>, sometimes a TextLine in the orphan list is recreated but not removed from the list of possible orphans. The two checks in this method ensure that we don&#8217;t hit this case.</p>
<p>And there you have it! That&#8217;s the basic gist of TextLine rendering, resizing, and reuse across multiple DisplayObjectContainers. You can see all the source for the demo <a href="http://guyinthechair.com/wp-content/uploads/2010/10/srcview/index.html">here</a>, and be sure to check out <a href="http://github.com/guyinthechair/tinytlf">tinytlf</a>, the small text layout framework I&#8217;m writing. I described the basic line rendering algorithm in tinytlf (with enhancements of course). Though I&#8217;m currently working on a more iterative version. If I&#8217;m successful, it&#8217;ll be the topic of a future blog post. Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/10/the-fte-part-4-advanced-layout-techniques/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The FTE Part 3: TextBlocks, TextLines, and Text Layout</title>
		<link>http://guyinthechair.com/2010/08/the-fte-part-3-textblocks-textlines-and-text-layout/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-fte-part-3-textblocks-textlines-and-text-layout</link>
		<comments>http://guyinthechair.com/2010/08/the-fte-part-3-textblocks-textlines-and-text-layout/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 01:25:42 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[FTE]]></category>
		<category><![CDATA[text layout]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=412</guid>
		<description><![CDATA[This is part 3 in an ongoing series about the Flash Text Engine. Here&#8217;s part 1 and part 2. By now you should know this series isn&#8217;t about Adobe&#8217;s Text Layout Framework, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that TLF is built on. In [...]]]></description>
			<content:encoded><![CDATA[<p>This is part 3 in an ongoing series about the Flash Text Engine. Here&#8217;s <a title="The Flash Text Engine, Part 1" href="http://guyinthechair.com/?p=250" target="_blank"> part 1</a> and <a title="The Flash Text Engine, Part 2: Interaction" href="http://guyinthechair.com/?p=312" target="_blank">part 2</a>.</p>
<p style="padding-left: 15px; padding-right: 15px; color: #999999;">By now you should know this series isn&#8217;t about <a href="http://labs.adobe.com/technologies/textlayout/">Adobe&#8217;s Text Layout Framework</a>, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that TLF is built on. In Flash Player 10, the FTE resides in the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/package-detail.html" target="_blank">flash.text.engine</a> package.</p>
<p>FP 10 has this great new font rendering library, the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/package-detail.html" target="_blank">Flash Text Engine</a>, but it only fashions characters into <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/TextLine.html" title="FTE's TextLine" target="_blank">TextLines</a> of a specific width. When you think about everything else a <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/TextField.html" title="Flash's TextField" target="_blank">TextField</a> does, you begin to understand that rendering the glyphs is only a small (but still important!) percentage of the total work that&#8217;s done.</p>
<h2>Text Layout</h2>
<p>If you recall from my previous <a title="The Flash Text Engine, Part 1" href="http://guyinthechair.com/?p=250" target="_blank">overview of the FTE</a>, the main &#8220;Controller&#8221; class is <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/TextBlock.html" target="_blank" title="FTE's TextBlock"><strong>TextBlock</strong></a>. TextBlock is a factory for TextLines. You supply a <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/ContentElement.html" target="_blank" title="FTE's ContentElement">ContentElement</a> to the TextBlock, it computes and creates the necessary TextLines to show that content. TextBlock&#8217;s rendering algorithms operate on a paragraph level; that is, one TextBlock per paragraph/one paragraph per TextBlock. For example, in the FTE, this paragraph should be represented as a single TextBlock, with multiple ContentElements that define formatting.</p>
<h3>Paradigms from a superior layout engine</h3>
<p>If you&#8217;re familiar with HTML styles, you know that HTML has two distinct layout paradigms: <a href="http://www.guistuff.com/css/images/boxmodel.png" target="_blank" title="block layout and styles"><strong>block layout</strong></a> and <a href="http://fredzlinkz.com/CSSimages/4.3%20Inline%20HTML%20%20Elements.png" target="_blank" title="inline elements"><strong>inline formatting</strong></a>. <strong>Block layout</strong> affects an entire <strong>block</strong> of text. Styles like  padding, indentation, and margins affect layout on the block level. <strong>Inline formatting</strong> affects how the characters are rendered within blocks, such as <span style="color: #66CC99;">color</span>, <span style="font-size:16px">size</span>, <em>posture</em>, <strong>weight</strong>, justification, etc.</p>
<p>TextBlock&#8217;s algorithms take care of the <strong>inline formatting</strong>, because inline formatting affects whether characters flow between TextLines. It&#8217;s left up to you to apply any block formatting. For example, when you call the TextBlock&#8217;s <code>createTextLine</code> method, you choose the width of the TextLine. This simple option allows us, with some fancy math-e-matics, to achieve many properties of block level layout.</p>
<h2>Layout Algorithms</h2>
<p>We want some generalized methods for accomplishing various layouts. Everything from simple, single paragraph layouts, to layouts with block formatting, to complex mutli-TextBlock and multi-column (newspaper style) layouts.</p>
<p>I&#8217;ve already demonstrated the absolute simplest way: render all the lines in a <code>while</code> loop, finishing once the TextBlock returns null from <code>createTextLine</code>. This is easy and straightforward, and you can apply any kind of block formatting you wish.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
    line = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_5" width="200" height="80" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo9.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo9.swf" width="200" height="80" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo9.as">Source</a></p>
<p>Even though all it seems I&#8217;ve done is render a TextField, I&#8217;ve accomplished two tasks here: I&#8217;ve rendered every TextLine that the TextBlock decides I need, and, by incrementing a counter for the Y dimension, I&#8217;ve calculated a rudimentary layout for the TextLines.</p>
<h3>Indentation</h3>
<p>Now, applying indentation is super easy. Make the first line a little smaller, and change his <code>x</code> position to compensate.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">185</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">x</span> = <span style="color: #000000; font-weight:bold;">15</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
    line = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_6" width="200" height="80" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo10.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo10.swf" width="200" height="80" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo10.as">Source</a></p>
<h3>Alignment</h3>
<p>Center:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">x</span> = <span style="color: #000000;">&#40;</span><span style="color: #000000; font-weight:bold;">200</span> <span style="color: #000066; font-weight: bold;">-</span> line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">width</span><span style="color: #000000;">&#41;</span> <span style="color: #000066; font-weight: bold;">*</span> <span style="color: #000000; font-weight:bold;">0.5</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
    line = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_7" width="200" height="135" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo11.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo11.swf" width="200" height="135" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo11.as">Source</a></p>
<p>Right alignment is the same, only don&#8217;t multiply the calculated <code>x</code> by 0.5.<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_8" width="200" height="95" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo12.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo12.swf" width="200" height="95" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo12.as">Source</a></p>
<p>See? Standard layout practices, ultimately the same math we use every day in component layouts. But, you say, &#8220;indentation and alignment are easy, it&#8217;s just calculating the <code>x</code> of the lines&#8221;. You&#8217;re right, it is easy. But so are the other block formatting properties like padding, margins, line spacing, etc. They&#8217;re all just calculating the correct <code>x</code> or <code>y</code> and conditionally applying them in the loop.</p>
<h2>Multi-TextBlock layout</h2>
<p>Ok, now we know how to layout lines from a single TextBlock. With a little code reuse, laying out multiple TextBlocks is a breeze:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> blocks<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>TextBlock<span style="color: #000066; font-weight: bold;">&gt;</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">&lt;</span>TextBlock<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#91;</span>block1<span style="color: #000066; font-weight: bold;">,</span> block2<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">for</span><span style="color: #000000;">&#40;</span><span style="color: #6699cc; font-weight: bold;">var</span> i<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span> i <span style="color: #000066; font-weight: bold;">&lt;</span> blocks<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000066; font-weight: bold;">;</span> <span style="color: #000066; font-weight: bold;">++</span>i<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">y</span> = layoutBlock<span style="color: #000000;">&#40;</span>blocks<span style="color: #000000;">&#91;</span>i<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">y</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= <span style="color: #000000; font-weight:bold;">5</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span>
<span style="color: #009900; font-style: italic;">// Returns the aggregate y after this layout operation</span>
<span style="color: #339966; font-weight: bold;">function</span> layoutBlock<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">:</span>TextBlock<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">185</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">x</span> = <span style="color: #000000; font-weight:bold;">15</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
        line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
        line = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #000000;">&#125;</span>
    <span style="color: #0033ff; font-weight: bold;">return</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_9" width="200" height="185" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo13.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo13.swf" width="200" height="185" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo13.as">Source</a></p>
<h2>Multi-Container layout</h2>
<p>Ah, now we&#8217;re getting to the good stuff. Multi-container layout is really cool, because it allows us to &#8220;overflow&#8221; text from one DisplayObjectContainer to another, which allows us, among other things, to achieve column layouts.</p>
<p>The general idea is to render as many TextLines into a DisplayObjectContainer (DOC) as possible. When we&#8217;ve hit his boundaries, switch to the next available DOC. We can accomplish this with a few modifications to the previous methods. The layout method needs to return the last TextLine that fit in the DOC. That way, we can re-enter the layout routine and pick up with the TextBlock where we left off.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = layoutBlock<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> container1<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
    line = layoutBlock<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">,</span> line<span style="color: #000066; font-weight: bold;">,</span> container2<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
<span style="color: #009900; font-style: italic;">// Returns the last line rendered out of the TextBlock</span>
<span style="color: #339966; font-weight: bold;">function</span> layoutBlock<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">:</span>TextBlock<span style="color: #000066; font-weight: bold;">,</span> previousLine<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000066; font-weight: bold;">,</span> 
                             container<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">DisplayObjectContainer</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span>TextLine
<span style="color: #000000;">&#123;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>previousLine<span style="color: #000066; font-weight: bold;">,</span> container<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">width</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        container<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
        line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #009900; font-style: italic;">//If we reached the height boundary, return the last line that fit.</span>
        <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span> line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">height</span> <span style="color: #000066; font-weight: bold;">&gt;</span> container<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">height</span><span style="color: #000000;">&#41;</span>
            <span style="color: #0033ff; font-weight: bold;">return</span> line<span style="color: #000066; font-weight: bold;">;</span>
        line = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> container<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">width</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #000000;">&#125;</span>
    <span style="color: #0033ff; font-weight: bold;">return</span> line<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_10" width="600" height="100" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo14.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo14.swf" width="600" height="100" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo14.as">Source</a></p>
<h2>Multi-TextBlock and Multi-Container layout</h2>
<p>Here&#8217;s the really good stuff! Now we&#8217;re going to render multiple TextBlocks into multiple DisplayObjectContainers by merging the two methods above. </p>
<p>To solve this problem, lets identify our list of knowns:</p>
<ol>
<li>We have a list of TextBlocks.</li>
<li>We have a list of DisplayObjectContainers to fit the TextBlocks into.</li>
<li>We wish to render as many lines into each DOC as possible.</li>
<li>When the DOC is full, switch to the next one and pick up where we left off.</li>
<li>We need to keep track of the last TextLine rendered, so we know where we left off.</lI>
</ol>
<p>From our previous experience with rendering multiple TextBlocks, we know that TextBlock will return <code>null</code> when he can render no more lines. And from our previous experience with rendering across DisplayObjectContainers, we know that when a Container is full, we should return the last line that fit. Therefore the logic plays out as such:</p>
<ul>
<li>Loop over each TextBlock.
</li>
<li>Render as many TextLines into the DOC as possible, returning the last line rendered.
<ol>
<li>If the TextLine is <code>null</code>, we know the TextBlock ran out of lines and there&#8217;s more space in the DOC. Keep the same DOC, but move to the next TextBlock.</li>
<li>If the TextLine is <strong>not</strong> <code>null</code>, there are still more lines in the TextBlock, but this DOC ran out of space. Keep the same TextBlock, but move to the next DOC.</li>
</ol>
</li>
<li>If we reach the end of either list, return.</li>
</ul>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> blocks<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>TextBlock<span style="color: #000066; font-weight: bold;">&gt;</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">&lt;</span>TextBlock<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#91;</span>block1<span style="color: #000066; font-weight: bold;">,</span> block2<span style="color: #000066; font-weight: bold;">,</span> block3<span style="color: #000066; font-weight: bold;">,</span> block4<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> containers<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>DisplayObjectContainer<span style="color: #000066; font-weight: bold;">&gt;</span> = 
    <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">&lt;</span>DisplayObjectContainer<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#91;</span>container1<span style="color: #000066; font-weight: bold;">,</span> container2<span style="color: #000066; font-weight: bold;">,</span> container3<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
layout<span style="color: #000000;">&#40;</span>blocks<span style="color: #000066; font-weight: bold;">,</span> containers<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
<span style="color: #339966; font-weight: bold;">function</span> layout<span style="color: #000000;">&#40;</span>blocks<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>TextBlock<span style="color: #000066; font-weight: bold;">&gt;,</span> containers<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>DisplayObjectContainer<span style="color: #000066; font-weight: bold;">&gt;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> blockIndex<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> containerIndex<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">int</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
    <span style="color: #6699cc; font-weight: bold;">var</span> block<span style="color: #000066; font-weight: bold;">:</span>TextBlock<span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> container<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">DisplayObjectContainer</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
    <span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>blockIndex <span style="color: #000066; font-weight: bold;">&lt;</span> blocks<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        block = blocks<span style="color: #000000;">&#91;</span>blockIndex<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
        container = containers<span style="color: #000000;">&#91;</span>containerIndex<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
        line = layoutInContainer<span style="color: #000000;">&#40;</span>container<span style="color: #000066; font-weight: bold;">,</span> block<span style="color: #000066; font-weight: bold;">,</span> line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
        <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>line <span style="color: #000066; font-weight: bold;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">++</span>containerIndex <span style="color: #000066; font-weight: bold;">&lt;</span> containers<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            container = containers<span style="color: #000000;">&#91;</span>containerIndex<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
            containerY = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #000000;">&#125;</span>
        <span style="color: #0033ff; font-weight: bold;">else</span> <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span><span style="color: #000066; font-weight: bold;">++</span>blockIndex <span style="color: #000066; font-weight: bold;">&lt;</span> blocks<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">length</span><span style="color: #000000;">&#41;</span>
            block = blocks<span style="color: #000000;">&#91;</span>blockIndex<span style="color: #000000;">&#93;</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #0033ff; font-weight: bold;">else</span>
            <span style="color: #0033ff; font-weight: bold;">return</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #6699cc; font-weight: bold;">var</span> containerY<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
<span style="color: #339966; font-weight: bold;">function</span> layoutInContainer<span style="color: #000000;">&#40;</span>container<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">DisplayObjectContainer</span><span style="color: #000066; font-weight: bold;">,</span> 
                                   block<span style="color: #000066; font-weight: bold;">:</span>TextBlock<span style="color: #000066; font-weight: bold;">,</span> previousLine<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span>TextLine
<span style="color: #000000;">&#123;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = createTextLine<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">,</span> previousLine<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        container<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
        containerY <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ascent</span><span style="color: #000066; font-weight: bold;">;</span>
        line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = containerY<span style="color: #000066; font-weight: bold;">;</span>
        containerY <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">descent</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
        <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>containerY <span style="color: #000066; font-weight: bold;">+</span> line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">height</span> <span style="color: #000066; font-weight: bold;">&gt;</span> container<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">height</span><span style="color: #000000;">&#41;</span>
            <span style="color: #0033ff; font-weight: bold;">return</span> line<span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
        line = createTextLine<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">,</span> line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #009900; font-style: italic;">//This will be null.</span>
    <span style="color: #0033ff; font-weight: bold;">return</span> line<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #339966; font-weight: bold;">function</span> createTextLine<span style="color: #000000;">&#40;</span>block<span style="color: #000066; font-weight: bold;">:</span>TextBlock<span style="color: #000066; font-weight: bold;">,</span> previousLine<span style="color: #000066; font-weight: bold;">:</span>TextLine<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span>TextLine
<span style="color: #000000;">&#123;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> w<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">190</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">x</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #009900; font-style: italic;">//Apply indention properties here.</span>
    <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>previousLine == <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        w <span style="color: #000066; font-weight: bold;">-</span>= <span style="color: #000000; font-weight:bold;">15</span><span style="color: #000066; font-weight: bold;">;</span>
        <span style="color: #004993;">x</span> <span style="color: #000066; font-weight: bold;">+</span>= <span style="color: #000000; font-weight:bold;">15</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #000000;">&#125;</span>
    <span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>previousLine<span style="color: #000066; font-weight: bold;">,</span> w<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">0.0</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">true</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #0033ff; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
        line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">x</span> = <span style="color: #004993;">x</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #0033ff; font-weight: bold;">return</span> line<span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_11" width="600" height="200" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo15.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo15.swf" width="600" height="200" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/08/FTEDemo14.as">Source</a><br />
<a href="http://en.wikipedia.org/wiki/Kaldi">Text Source</a></p>
<h2>Woah! Take a breather</h2>
<p>It&#8217;s a lot to digest, I know. But now you can see that TextLayout isn&#8217;t black-magic voodoo, and is entirely achievable in the new Flash Text Engine. If you have any questions, feel free to comment or <a href="mailto:guyinthechair@gmail.com">email me</a>. If you have any techniques for text layout, or have any comments on my techniques, I&#8217;d love to hear those too. I took some shortcuts with these demos, but I&#8217;ve built out more complete and performance-tuned layouts into <a href="http://github.com/guyinthechair/tinytlf" >tinytlf</a>, the small text layout framework I&#8217;ve been working on clandestinely for a few months.</p>
<h2>Aside: Text Layout vs. Component Layout</h2>
<p>In typical component based layout engines (such as Flex&#8217;s), child creation is separate from layout. Usually all the children are added to the display list first, then laid out at some other time. Children aren&#8217;t created or destroyed based on their positions or sizes on the screen, and layout doesn&#8217;t affect the creation of future children (this is assuming we&#8217;re not talking about <a href="http://guyinthechair.com/wp-content/flex/ptlib_demo/DataGridDemo.html" target="_blank" title="I wrote a DataGrid...">virtualized layout</a>, which is a special case).</p>
<p>Working with the sizing and layout of TextLines, the block-level layout properties (like padding, indentation, etc.) dictate how each TextLine is created and laid out. This in turn affects how the TextBlock renders the <em>next</em> TextLine, and so on and so forth. I haven&#8217;t been able to separate block-level layout properties from the TextLine creation process. This isn&#8217;t so bad in practice, but sometimes it rubs me the wrong way, I feel like there should be a better way and I just haven&#8217;t found it yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/08/the-fte-part-3-textblocks-textlines-and-text-layout/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Flash Text Engine, Part 2: Interaction</title>
		<link>http://guyinthechair.com/2010/06/the-flash-text-engine-part-2-interaction/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-flash-text-engine-part-2-interaction</link>
		<comments>http://guyinthechair.com/2010/06/the-flash-text-engine-part-2-interaction/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 06:16:57 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[FTE]]></category>
		<category><![CDATA[fte interaction]]></category>
		<category><![CDATA[tiny tlf]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=312</guid>
		<description><![CDATA[This is part 2 in an ongoing series about the Flash Text Engine. You can read part 1 here. To clarify, this series isn&#8217;t about Adobe&#8217;s Text Layout Framework, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that TLF is built on. In Flash Player 10, [...]]]></description>
			<content:encoded><![CDATA[<p>This is part 2 in an ongoing series about the Flash Text Engine. <a href="http://guyinthechair.com/?p=250" target="_blank" title="The Flash Text Engine, Part 1">You can read part 1 here</a>. </p>
<p style="padding-left:15px;padding-right:15px;color:#999999">To clarify, this series isn&#8217;t about <a href="http://labs.adobe.com/technologies/textlayout/">Adobe&#8217;s Text Layout Framework</a>, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that TLF is built on. In Flash Player 10, the FTE resides in the <a href="http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/text/engine/package-detail.html">flash.text.engine</a> package.</p>
<h2>Interaction in the Flash Text Engine</h2>
<p>In my previous post on the Flash Text Engine, I ran through the basics of what you need to get the FTE to render TextLines. While rendering lines on the screen is nice, this post is about how to add interaction to the TextLines that are produced. </p>
<p>TextLines are <a href="http://livedocs.adobe.com/flex/3/langref/flash/display/InteractiveObject.html" title="InteractiveObject" target="_blank">InteractiveObjects</a>. You can add event listeners directly to them and listen for interaction events. The FTE also gives you the option to associate an individual EventDispatcher instance with a single ContentElement, so that when the user interacts with the data of the ContentElement, the events are cloned to the EventDispatcher instance you specified. As I discuss the details, you&#8217;ll see that each approach has its own strengths and weaknesses.</p>
<h3>Approach 1: TextLines as InteractiveObjects</h3>
<p>Since TextLine is an InteractiveObject, you can simply listen for Mouse and Keyboard events on each TextLine instance. With this approach, you know the TextLine that was interacted with. The main drawback here is that TextLine knows almost nothing about the ContentElement which it is rendering. Multiple ContentElements can be rendered into the same TextLine, and multiple TextLines can render the same (really long) ContentElement.</p>
<p>Interact with the lines in this demo:<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_12" width="235" height="100">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo2.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo2.swf" width="235" height="100">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo2.as">Source</a></p>
<p>The fact that you don&#8217;t know about the content of the TextLines is ok though, for some problems that isn&#8217;t necessary. For example, you don&#8217;t really need to know about the contents of the TextLines to draw decorations, such as underline, strikethrough, or selection.</p>
<p>Select this text:<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_13" width="400" height="125">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo7.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo7.swf" width="400" height="125">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo7.as">Source</a></p>
<h3>Approach 2: Working with TextLineMirrorRegions (TLMRs)</h3>
<p>The preferred method of managing interaction in the Flash Text Engine is with <a title="TextLineMIrrorRegion" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextLineMirrorRegion.html" target="_blank">TextLineMirrorRegions</a>.</p>
<p>If you read my <a href="http://guyinthechair.com/?p=250" target="_blank" title="The Flash Text Engine, Part 1">previous post</a>, you&#8217;ll remember that to render any text, you have to create instances of any of the Flash Text Engine&#8217;s model classes: <a title="TextElement" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextElement.html" target="_blank">TextElement</a>, <a title="GraphicElement" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/GraphicElement.html" target="_blank">GraphicElement</a>, or <a title="GroupElement" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/GroupElement.html" target="_blank">GroupElement</a>. When you create an instance of these classes, you can specify an EventDispatcher as the <code>eventMirror</code> for the ContentElement. When the user interacts with the visual representation of this ContentElement via TextLines, the events are re-dispatched to the <code>eventMirror</code> you specified. This allows you to know when a user interacts only with a particular ContentElement.</p>
<p>In this code sample, I create an EventDispatcher to pass in as the <code>eventMirror</code> for the TextElement. Then I add a listener for mouseMove on the <code>eventMirror</code> instance. This will trace out every time you mouse over the TextElement.</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> dispatcher<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">EventDispatcher</span> = <span style="color: #0033ff; font-weight: bold;">new</span> <span style="color: #004993;">EventDispatcher</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">'Inspiring quote here.'</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span>
                                         <span style="color: #0033ff; font-weight: bold;">new</span> FontDescription<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span> 
                                         dispatcher<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> onMouseMove<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Function</span> = <span style="color: #339966; font-weight: bold;">function</span><span style="color: #000000;">&#40;</span>e<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">MouseEvent</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">trace</span><span style="color: #000000;">&#40;</span><span style="color: #990000;">'Mouse move on '</span> <span style="color: #000066; font-weight: bold;">+</span> e<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">target</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">toString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span>
dispatcher<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">addEventListener</span><span style="color: #000000;">&#40;</span><span style="color: #004993;">MouseEvent</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">MOUSE_MOVE</span><span style="color: #000066; font-weight: bold;">,</span> onMouseMove<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>These two lines are part of the same TextElement:<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_14" width="190" height="40">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo3.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo3.swf" width="190" height="40">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo3.as">Source</a></p>
<p>How is this different from the previous demo? TextLine has a property called <code>mirrorRegions</code>, a Vector of TextLineMirrorRegion instances. Since multiple ContentElements can be rendered by a single TextLine, TextLine creates TLMR instances for each ContentElement with an <code>eventMirror</code>, then associates the TLMRs with the <code>eventMirror</code>s respectively.</p>
<p>TextLine listens on itself for interaction events. When the events overlap with any of the TLMRs, TextLine notifies the appropriate TLMR of the event. <strong>After all normal event processing for the TextLine is done</strong>, each TLMR  re-dispatches the events it was notified of to its <code>eventMirror</code> instance.</p>
<p>In this example, I added a listener for the &#8220;mouseDown&#8221; event on both the TextLine and the ContentElement&#8217;s <code>eventMirror</code>. Notice that the event dispatched on the <code>eventMirror</code> happens second.<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_15" width="285" height="55">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo4.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo4.swf" width="285" height="55">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo4.as">Source</a></p>
<p>Here&#8217;s what the TLMRs look like (I&#8217;ve drawn boxes for each boundary of a TextLineMirrorRegion).<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_16" width="250" height="110">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo5.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo5.swf" width="250" height="110">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo5.as">Source</a></p>
<h3>Caveats</h3>
<p>Of course, this wouldn&#8217;t be a Flash Player feature if it didn&#8217;t come with caveats ;). </p>
<p>TextLineMirrorRegion <em>simulates</em> the events, it doesn&#8217;t re-dispatch the exact instance it received from the TextLine. This is because TLMR isn&#8217;t an InteractiveObject itself. If you utilize the <code>eventMirror</code> to listen for MouseEvents, just realize they&#8217;re all faked &#8212; even though TextLine is the target, they didn&#8217;t originate from TextLine, and they don&#8217;t have feelings like real player-native events do.</p>
<h3>rollOver/rollOut events</h3>
<p>This event simulation means that we&#8217;re at the mercy of what Adobe chooses to simulate. They didn&#8217;t feel the need to simulate the roll events (rollOver/rollOut), so if you try to listen for them on the <code>eventMirror</code>, you won&#8217;t get them. Presumably this is because the roll events aren&#8217;t needed; since ContentElements don&#8217;t have display-list children, the roll events would be exactly the same as mouseOver/mouseOut.</p>
<p><strong>Except the roll events are still very relevent.</strong></p>
<p>It&#8217;s true, we&#8217;ve shifted from a display-list hierarchical structure (DisplayObjectContainers, etc.) to a ContentElement hierarchical structure. And it&#8217;s true, ContentElements don&#8217;t have display-list children. But they can have other ContentElement children, which means the roll events are still very relevant.</p>
<p>For example, if you had this XML model to render:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  Outside the group. 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;text</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#44AA00&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      First group child.
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;text</span> <span style="color: #000066;">color</span>=<span style="color: #ff0000;">&quot;#AA0044&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      Second group child.
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/text<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/group<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  Outside the group.
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>You might want to know only when the entire <code>group</code> node is interacted with (just like when you have a DisplayObjectContainer with children).</p>
<p>Here&#8217;s the demo of this model. Mouse between the boundary of the first child and the second child, and notice how you get a &#8220;mouseOut&#8221; and then another &#8220;mouseOver&#8221; <strong>from the group</strong>. If this were the roll events, you would only get the &#8220;mouseOut&#8221; and &#8220;mouseOver&#8221; from the children, but <strong>hear nothing from the group</strong>. FYI, &#8220;mouseDown&#8221; clears the debug lines. 
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_17" width="400" height="110">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo6.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo6.swf" width="400" height="110">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />
<a href="http://guyinthechair.com/wp-content/uploads/2010/06/FTEDemo6.as">Source</a></p>
<h3>Comparison</h3>
<p>So, how do the two techniques match up? The short answer is that each one accomplishes a different task. If you need the very base of interaction capabilities without the context of what you&#8217;re messing with (e.g. text selection), adding listeners straight on your TextLines is the way to go. However, if you need the context of which ContentElement the user interacts with (e.g. to mimic an HTML anchor tag), there&#8217;s no way around it, you have to use the event mirroring approach.</p>
<p><strong>P.S.</strong> Isn&#8217;t it freaky interacting with text that you can&#8217;t select? Maybe I&#8217;m just OCD, but I feel a strong desire to see an I-Beam mouse cursor every time I hover over FTE text. My favorite demo to write was the second one, because not only did I get to come up with a quick selection-drawing method, I added the freakin&#8217; I-Beam cursor. Anyway, hope you enjoyed this and good luck :).</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/06/the-flash-text-engine-part-2-interaction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Flash Text Engine, Part 1: Overview</title>
		<link>http://guyinthechair.com/2010/06/the-flash-text-engine-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-flash-text-engine-part-1</link>
		<comments>http://guyinthechair.com/2010/06/the-flash-text-engine-part-1/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 10:18:20 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[advanced text rendering]]></category>
		<category><![CDATA[cff]]></category>
		<category><![CDATA[compact font format]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[FTE]]></category>
		<category><![CDATA[text layout]]></category>
		<category><![CDATA[Text Layout Framework]]></category>
		<category><![CDATA[TextField]]></category>
		<category><![CDATA[tiny tlf]]></category>
		<category><![CDATA[tinytlf]]></category>
		<category><![CDATA[TLF]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=250</guid>
		<description><![CDATA[This is the first post in what will be a multi-part series about the Flash Text Engine, a new low level text API in Flash Player 10. To clarify, this series isn&#8217;t about Adobe&#8217;s Text Layout Framework, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first post in what will be a multi-part series about the Flash Text Engine, a new low level text API in Flash Player 10.</p>
<p style="padding-left:15px;padding-right:15px;color:#999999">To clarify, this series isn&#8217;t about <a href="http://labs.adobe.com/technologies/textlayout/">Adobe&#8217;s Text Layout Framework</a>, which is an advanced typography and text layout framework. The Flash Text Engine is the low-level API that TLF is built on. In Flash Player 10, the FTE resides in the <a href="http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/text/engine/package-detail.html">flash.text.engine</a> package.</p>
<p>The FTE is designed to render text &#8220;document style&#8221;. It&#8217;s primarily meant to replace the TextField for advanced uses, not provide a whole framework for text layout on the scale of an HTML rendering engine.</p>
<p>The FTE handles what I call <strong>flow</strong>: formatting that causes text to be pushed to the next line in a paragraph. I don&#8217;t know if that&#8217;s the official term, but it seems to fit. It does not do <strong>layout</strong>, which is things like bullet points, indentation, wrapping around images, padding, etc., nor does it handle <strong>decoration</strong>, things like underline, strikethrough, background color, selection, etc. I believe the FTE leaves these out because 1.) layout is a much more complicated and nuanced problem than flow, one that you wouldn&#8217;t necessarily want in the FP core, and 2.) decorations don&#8217;t cause <strong>reflow</strong>, or affect whether and how text is wrapped to the next line.</p>
<p>The FTE conforms to a small MVC architecture, there are about 10 core classes that provide most of the functionality, with the rest of them encapsulating constants. Something to note, every class in the FTE is final :( more on that later.</p>
<h2>The FTE Model</h2>
<p>The basis of the Flash Text Engine model is something called <a title="flash.text.engine.ContentElement" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/ContentElement.html" target="_blank">ContentElement</a>. ContentElement is an abstract base class. You never call <code>new ContentElement()</code> (it&#8217;s similar to DisplayObject in this regard), instead you instantiate one of its 3 subclasses: <a title="flash.text.engine.TextElement" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextElement.html" target="_blank">TextElement</a>, <a title="flash.text.engine.GraphicElement" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/GraphicElement.html" target="_blank">GraphicElement</a>, or <a title="flash.text.engine.GroupElement" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/GroupElement.html" target="_blank">GroupElement</a>. Collectively these classes describe a Tree hierarchy for text, but I want to talk a bit more about ContentElement before we get too deep into that.</p>
<h3>ContentElement</h3>
<p>Take a look at the constructor of ContentElement:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">ContentElement<span style="color: #000000;">&#40;</span>elementFormat<span style="color: #000066; font-weight: bold;">:</span>ElementFormat = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> eventMirror<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">EventDispatcher</span> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> textRotation<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;rotate0&quot;</span><span style="color: #000000;">&#41;</span></pre></div></div>

<p>It has two important arguments, <strong>elementFormat</strong> and <strong>eventMirror</strong> (as well as a third less important argument, unless you&#8217;re one of the crazy types who likes to rotate text). I will come back to the eventMirror later, but for now lets just talk about <a title="flash.text.engine.ElementFormat" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/ElementFormat.html" target="_blank">ElementFormat</a>.</p>
<p>The ElementFormat class describes most of the properties that handle text flow. It has a fontDescription member, which is exactly what it sounds like. In <a title="flash.text.engine.FontDescription" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/FontDescription.html" target="_blank">FontDescription</a> you&#8217;ve got your standard <code>fontFamily</code>, <code>fontWeight</code>, <code>fontPosture</code> (which is traditionally the fontStyle in Flash), along with how the font is supposed to be retrieved from the depths of the Flash Player (as Compact Font Format or a device font).</p>
<p>ElementFormat has properties like <code>alpha</code>, <code>color</code>, <code>baselineShift</code>, <code>kerning</code>, etc. Basically anything that can affect <strong>reflow</strong>.</p>
<p>Ok, so that describes all you need to know for now about the ElementFormat and FontDescription objects. Now onto the implementation class you&#8217;ll use.</p>
<h3>TextElement</h3>
<p>Out of the three, TextElement is the most straightforward. It simply accepts a string of text to take care of:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">TextElement<span style="color: #000000;">&#40;</span><span style="color: #004993;">text</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">String</span> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> elementFormat<span style="color: #000066; font-weight: bold;">:</span>ElementFormat = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> eventMirror<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">EventDispatcher</span> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> textRotation<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;rotate0&quot;</span><span style="color: #000000;">&#41;</span></pre></div></div>

<p>The ElementFormat you pass in is applied to the entire string of text that this TextElement owns. So if you specify an ElementFormat with a color of <span style="color: #ff0000;">red</span>, the entire string of text will render <span style="color: #ff0000;">red</span>.</p>
<h3>GraphicElement</h3>
<p>The next one to worry about is GraphicElement. He accepts <strong>any DisplayObject instance</strong> (<strong>instance!</strong>), as well as the width and height that you wish to allocate for the Graphic in the text:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">GraphicElement<span style="color: #000000;">&#40;</span>graphic<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">DisplayObject</span> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> elementWidth<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">15.0</span><span style="color: #000066; font-weight: bold;">,</span> elementHeight<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">15.0</span><span style="color: #000066; font-weight: bold;">,</span> elementFormat<span style="color: #000066; font-weight: bold;">:</span>ElementFormat = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> eventMirror<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">EventDispatcher</span> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> textRotation<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;rotate0&quot;</span><span style="color: #000000;">&#41;</span></pre></div></div>

<p>Some of the properties of the ElementFormat will apply to the GraphicElement, such as <code>alpha</code>, <code>baselineShift</code>, etc. Obviously the GraphicElement doesn&#8217;t respect font-specific settings from the ElementFormat and FontDescription objects.</p>
<h3>GroupElement</h3>
<p>Lastly there&#8217;s the GroupElement:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">GroupElement<span style="color: #000000;">&#40;</span><span style="color: #004993;">elements</span><span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.&lt;</span>ContentElement<span style="color: #000066; font-weight: bold;">&gt;</span> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> elementFormat<span style="color: #000066; font-weight: bold;">:</span>ElementFormat = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> eventMirror<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">EventDispatcher</span> = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> textRotation<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">String</span> = <span style="color: #990000;">&quot;rotate0&quot;</span><span style="color: #000000;">&#41;</span></pre></div></div>

<p>GroupElement is <strong>critical</strong>. GroupElement is a collection of any combination of TextElements, GraphicElements, or other GroupElements. GroupElement is the Tree functionality of FTE&#8217;s model. TextElement can&#8217;t have children, it controls a single String. Likewise, GraphicElement only describes a single DisplayObject instance. GroupElements tie it all together.</p>
<p>GroupElements provide an API for doing standard Tree functions; you can retrieve, split, merge, and group children using various methods. I speak from experience when I say you won&#8217;t often mess with this unless you&#8217;re writing an editable text field. And if you are writing an editable text field, God help you (just kidding, it is hella fun).</p>
<p>OK, enough Model talk. Onwards to&#8230;</p>
<h2>The FTE View</h2>
<p>There are two (<strong>2!</strong>) classes that make up the entirety of the Flash Text Engine&#8217;s <strong><em>View</em></strong> division: <a target="_blank" title="flash.text.engine.TextLine" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextLine.html">TextLine</a> and <a target="_blank" title="flash.text.engine.TextLineMirrorRegion" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextLineMirrorRegion.html">TextLineMirrorRegion</a>. Right now you can forget about TextLineMirrorRegion, as that has to do with interaction, which is a complicated topic and one which I will cover in detail later. So for now, only focus on TextLine.</p>
<h3>TextLine</h3>
<p>TextLine is a DisplayObjectContainer. Yes, that means it has the <code>get/add/removeChild</code> methods (<strong>they still work!</strong>), and is also an InteractiveObject. You can listen for all the normal interaction events. However, even though it inherits from InteractiveObject, there are a few properties that you can only read, not write. Those are detailed in the <a href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextLine.html">documentation for TextLine</a>.</p>
<p>TextLine adds the concept of <em>atoms</em>, which are indivisible characters in a TextLine. Individual characters are atoms, as well as any graphics you have. The important thing to know here is that atoms can never be split between lines. The FTE will measure only to the atom level, no lower. </p>
<p>Atom information can be expensive to keep around&#8230; At first the TextLine only renders its text, it doesn&#8217;t know anything about the atoms it contains. However calling various methods will cause the TextLine to create its atom data. For example, if you call <code>getAtomIndexAtPoint()</code>, the TextLine must create the info about each atom so it can then calculate which atom occurs at the point you specify. This is all well and good, but be sure to call <code>flushAtomData()</code> once you&#8217;re done so the atom data will be GC&#8217;d.</p>
<p>TextLine has a reference to the previous and next lines, because TextLine is also a <a href="http://en.wikipedia.org/wiki/Doubly-linked_list">doubly-linked list</a>! How convenient! Of course, if there is no previous or next, you know you&#8217;re the first or last lines, respectively.</p>
<p>TextLine also has a <code>validity</code> status, which is whether the ContentElement that the line represents has changed since the line was rendered. Values are described in the <a href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextLineValidity.html">TextLineValidity</a> class.</p>
<p>One thing that TextLine definitely <strong>is not</strong>: a Sprite. No, TextLine is a DisplayObjectContainer. The most important implication from this is that TextLine has no <strong>graphics context</strong>. This means you can&#8217;t call textLine.graphics.draw. :( Oh well.</p>
<p>TextLine is a concrete class, you use it directly, but you cannot instantiate one by calling its constructor. To do that you need&#8230;</p>
<h2>The FTE Controller</h2>
<p>There is arguably <strong>one class</strong> in the FTE&#8217;s <strong><em>Controller</em></strong> division: <a target="_blank" title="flash.text.engine.TextBlock" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextBlock.html">TextBlock</a>. I say <em>arguably</em> because yeah, <a target="_blank" title="flash.text.engine.TextJustifier" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TextJustifier.html">TextJustifier</a> and <a target="_blank" title="flash.text.engine.TabStop" href="http://livedocs.adobe.com/flex/3/langref/flash/text/engine/TabStop.html">TabStop</a> exist, but they just affect how TextBlock does its rendering, not&#8230; hm. Ok, I&#8217;ve convinced myself that they count as Controller classes too, but only <em>barely</em>.</p>
<p>But believe me, you will come to think of TextBlock as the only Controller class too.</p>
<p>The TextBlock is a fairly standard Factory pattern implementation: TextBlock&#8217;s primary job is to accept a ContentElement as input and output as many TextLines as you want, given a width. <strong>ContentElement</strong> -> <strong>TextBlock</strong> -> <strong>TextLines</strong>. Got it? Me neither.</p>
<p>Ok, so TextBlock has this method called <code>createTextLine()</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">createTextLine<span style="color: #000000;">&#40;</span>previousLine<span style="color: #000066; font-weight: bold;">:</span>TextLine = <span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">width</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">1000000</span><span style="color: #000066; font-weight: bold;">,</span> lineOffset<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0.0</span><span style="color: #000066; font-weight: bold;">,</span> fitSomething<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Boolean</span> = <span style="color: #0033ff; font-weight: bold;">false</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span>TextLine</pre></div></div>

<p>Ok so what you do is you pass in the <strong><em>previous</em></strong> line that you created, plus the width that you want the <strong><em>current</em></strong> line to be, and TextBlock will measure out a TextLine for you. Are you seeing the doubly-linked list yet?</p>
<p>If you want to create the first line from a TextBlock, you should just pass in <code>null</code> to the <code>createTextLine()</code> method; assuming the TextBlock has content in his <code>content</code> property, and that content has at least one atom (characters or graphics), passing in <code>null</code> will <em>always</em> return a TextLine. If there are no more lines to be created, TextBlock will return <code>null</code> from the call to <code>createTextLine()</code>.</p>
<p>So from this it is simple to render the lines for a TextBlock with width 200:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #6699cc; font-weight: bold;">var</span> <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
    <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
    <span style="color: #004993;">y</span> <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">height</span><span style="color: #000066; font-weight: bold;">;</span>
    line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">height</span> = <span style="color: #004993;">y</span><span style="color: #000066; font-weight: bold;">;</span>
    line = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">200</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<h3>Ok, I&#8217;ve detailed a lot so far, now it&#8217;s time to get to at an example.</h3>
<h3>Flash:</h3>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_18" width="450" height="32">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo1.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/06/SimpleDemo1.swf" width="450" height="32">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<p>Here&#8217;s the code for the above simple line rendering:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;"><span style="color: #9900cc; font-weight: bold;">package</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.display</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">Sprite</span><span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>ContentElement<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>ElementFormat<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>FontDescription<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>FontPosture<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>FontWeight<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>GroupElement<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>TextBlock<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>TextElement<span style="color: #000066; font-weight: bold;">;</span>
  <span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.text</span><span style="color: #000066; font-weight: bold;">.</span>engine<span style="color: #000066; font-weight: bold;">.</span>TextLine<span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
  <span style="color: #000000;">&#91;</span>SWF<span style="color: #000000;">&#40;</span><span style="color: #004993;">width</span>=<span style="color: #990000;">&quot;450&quot;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">height</span>=<span style="color: #990000;">&quot;32&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
  <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #9900cc; font-weight: bold;">class</span> SimpleDemo1 <span style="color: #0033ff; font-weight: bold;">extends</span> <span style="color: #004993;">Sprite</span>
  <span style="color: #000000;">&#123;</span>
    <span style="color: #0033ff; font-weight: bold;">public</span> <span style="color: #339966; font-weight: bold;">function</span> SimpleDemo1<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
      <span style="color: #0033ff; font-weight: bold;">super</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
      <span style="color: #6699cc; font-weight: bold;">var</span> e1<span style="color: #000066; font-weight: bold;">:</span>TextElement = <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">'Consider, what makes a text line a '</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">new</span> FontDescription<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">24</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
      <span style="color: #6699cc; font-weight: bold;">var</span> e2<span style="color: #000066; font-weight: bold;">:</span>TextElement = <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">'text line'</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">new</span> FontDescription<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;_serif&quot;</span><span style="color: #000066; font-weight: bold;">,</span> FontWeight<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">NORMAL</span><span style="color: #000066; font-weight: bold;">,</span> FontPosture<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">ITALIC</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">24</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
      <span style="color: #6699cc; font-weight: bold;">var</span> e3<span style="color: #000066; font-weight: bold;">:</span>TextElement = <span style="color: #0033ff; font-weight: bold;">new</span> TextElement<span style="color: #000000;">&#40;</span><span style="color: #990000;">'?'</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #0033ff; font-weight: bold;">new</span> ElementFormat<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">new</span> FontDescription<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">24</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
      <span style="color: #6699cc; font-weight: bold;">var</span> e<span style="color: #000066; font-weight: bold;">:</span>Vector<span style="color: #000066; font-weight: bold;">.</span> = <span style="color: #0033ff; font-weight: bold;">new</span> Vector<span style="color: #000066; font-weight: bold;">.</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
      e<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">push</span><span style="color: #000000;">&#40;</span>e1<span style="color: #000066; font-weight: bold;">,</span> e2<span style="color: #000066; font-weight: bold;">,</span> e3<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
      <span style="color: #6699cc; font-weight: bold;">var</span> block<span style="color: #000066; font-weight: bold;">:</span>TextBlock = <span style="color: #0033ff; font-weight: bold;">new</span> TextBlock<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">new</span> GroupElement<span style="color: #000000;">&#40;</span>e<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
      <span style="color: #6699cc; font-weight: bold;">var</span> line<span style="color: #000066; font-weight: bold;">:</span>TextLine = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span><span style="color: #0033ff; font-weight: bold;">null</span><span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">stage</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">stageWidth</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
&nbsp;
      <span style="color: #6699cc; font-weight: bold;">var</span> _y<span style="color: #000066; font-weight: bold;">:</span><span style="color: #004993;">Number</span> = <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">;</span>
      <span style="color: #0033ff; font-weight: bold;">while</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span>
      <span style="color: #000000;">&#123;</span>
        <span style="color: #004993;">addChild</span><span style="color: #000000;">&#40;</span>line<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
        _y <span style="color: #000066; font-weight: bold;">+</span>= line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">height</span><span style="color: #000066; font-weight: bold;">;</span>
        line<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">y</span> = _y<span style="color: #000066; font-weight: bold;">;</span>
        line = block<span style="color: #000066; font-weight: bold;">.</span>createTextLine<span style="color: #000000;">&#40;</span>line<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #004993;">stage</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">stageWidth</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
      <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p style="font-size: 14px;"><strong>Holy crap Batman!</strong><br />
As you can see, it required <em>3 different TextElements <strong>and</strong> a GroupElement</em> to render some freakin&#8217; italic text in the middle of a sentence. Yeah. Par for the frickin&#8217; course.</p>
<p>In part 2 I&#8217;ll get into more details about interaction, TextBlock manipulation, all of it.<br />
Till then watch this project on github: <a target="_blank" title="tinytlf on github" href="http://github.com/guyinthechair/tinytlf">tinytlf</a>. It&#8217;s due for some major updates but it&#8217;s what I&#8217;m going to start talking about soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/06/the-flash-text-engine-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

