<?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; tinytlf</title>
	<atom:link href="http://guyinthechair.com/tag/tinytlf/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>tinytlf Explorer App</title>
		<link>http://guyinthechair.com/2011/10/tinytlf-explorer-app/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tinytlf-explorer-app</link>
		<comments>http://guyinthechair.com/2011/10/tinytlf-explorer-app/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 07:33:18 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[tinytlf]]></category>
		<category><![CDATA[tinytlf demo app]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=781</guid>
		<description><![CDATA[I&#8217;ve written a little feature explorer app to showcase some of tinytlf&#8217;s latest features. You can play around with it below, or you can launch the demo app into a new window. You can manipulate the renderer by editing CSS or switching which HTML document is rendered. I threw in a circular paragraph renderer just [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve written a little feature explorer app to showcase some of tinytlf&#8217;s latest features. You can play around with it below, or you can <a href="http://guyinthechair.com/flash/tinytlf/2.0/explorer/TinyTLFDemo.html" target="_blank">launch the demo app into a new window.</a></p>
<p>You can manipulate the renderer by editing CSS or switching which HTML document is rendered. I threw in a circular paragraph renderer just for fun. I also included a time indicator to show how long Flash takes to parse each HTML source. Even though Flash takes forever to serialize Strings to XML, this shows that tinytlf renders it almost instantaneously every time. I&#8217;ll talk about this more in my next post.</p>
<p>This is now the official tinytlf demo, so I&#8217;ll be updating it as I add features in the future. To demonstrate tinytlf&#8217;s capabilities beyond sanitized HTML input, I&#8217;ve included examples from <a href="http://idlewords.com/" target="_blank">Idle Words</a> and the HTML version of <a href="https://plus.google.com/u/0/113556260101951952093/about" target="_blank">Christian Cantrell&#8217;s</a> eBook, <a href="http://www.livingdigitally.net/books/farmer_one/farmer_one.html" target="_blank">Farmer One</a>.</p>
<p><a href="https://github.com/guyinthechair/tinytlf" target="_blank">Watch or fork the project on Github.</a></p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_0" width="600" height="500">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/2.0/explorer/TinyTLFDemo.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/2.0/explorer/TinyTLFDemo.swf" width="600" height="500">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2011/10/tinytlf-explorer-app/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hello tinytlf 2.0 (beta)</title>
		<link>http://guyinthechair.com/2011/09/hello-tinytlf-2-0-beta/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hello-tinytlf-2-0-beta</link>
		<comments>http://guyinthechair.com/2011/09/hello-tinytlf-2-0-beta/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 19:32:29 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=765</guid>
		<description><![CDATA[I recently embarked on the journey towards tinytlf v2.0, a shiny new version replete with glossy sheen, twinkling diamond star, and cash-machine *jing* sound effect. First, I gotta apologize for pushing v1 out into the world. It was crap. I&#8217;ve changed almost everything in v2, making it smaller, faster, and more feature rich. Crazy you [...]]]></description>
			<content:encoded><![CDATA[<p>I recently embarked on the journey towards <a href="https://github.com/guyinthechair/tinytlf" title="tinytlf 2.0" target="_blank">tinytlf v2.0</a>, a shiny new version replete with glossy sheen, twinkling diamond star, and cash-machine *jing* sound effect.</p>
<p>First, I gotta apologize for pushing v1 out into the world. It was crap. I&#8217;ve changed almost everything in v2, making it smaller, faster, and more feature rich. Crazy you say? Here&#8217;s a few of the additions and changes that make version 2 smarter than version 1:</p>
<ul>
<li>Using <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/TextEngineInjector.as" title="TextEngineInjector.as" target="_blank">Dependency Injection</a> instead of the Facade pattern</li>
<li>Consolidating all the maps into a <a href="https://github.com/guyinthechair/tinytlf/blob/6ada64138f3414c88dc1f09fa5628b0e479e9e09/framework/core/src/org/tinytlf/FactoryMap.as#L11" title="FactoryMap.as" target="_blank">single implementation</a></li>
<li>Integrating <a href="https://github.com/guyinthechair/tinytlf/blob/6ada64138f3414c88dc1f09fa5628b0e479e9e09/framework/core/src/org/tinytlf/html/DOMNode.as" title="DOMNode.as" target="_blank">HTML</a> and <a href="https://github.com/guyinthechair/tinytlf/blob/6ada64138f3414c88dc1f09fa5628b0e479e9e09/framework/core/src/org/tinytlf/html/CSS.as" title="CSS.as" target="_blank">CSS</a> into the core</li>
<li>Rewriting the <a href="https://github.com/guyinthechair/tinytlf/blob/0aef6b275c128b8aabfaca037bf79e62011344d4/framework/core/src/org/tinytlf/layout/sector/TextPane.as" title="TextPane.as" target="_blank">paragraph</a> and <a href="https://github.com/guyinthechair/tinytlf/blob/0aef6b275c128b8aabfaca037bf79e62011344d4/framework/core/src/org/tinytlf/layout/sector/TextSector.as" title="TextSector.as" target="_blank">line</a> renderer that handles all <a href="http://unicode.org/notes/tn22/RobustVerticalLayout.pdf" title="Robust Vertical Layout" target="_blank">variations of layout [PDF]</a>, floats, and virtualization (I&#8217;m proud of my work in this area)</li>
<li>Alongside the renderer, adding a <a href="https://github.com/guyinthechair/tinytlf/blob/e25f650e4974bcb492e011b325510c4e4e03706b/framework/core/src/org/tinytlf/html/ParagraphTSF.as" title="ParagraphTSF.as" target="_blank">parser for content blocks</a>, which is a better abstraction for implementing percent sizing, margins, padding, lists, tables, and floats than the way I did it in v1</li>
<li>A rewrite of the interaction model, implementing gestures using <a href="https://github.com/guyinthechair/raix" title="Reactive And Interactive eXtensions" target="_blank">raix</a>, a port of Microsoft&#8217;s incredible <a href="http://msdn.microsoft.com/en-us/data/gg577609" title="Reactive eXtensions" target="_blank">Rx.NET</a> framework. (events are fun again!)</li>
<li>Because of the addition of raix, I can do away with the Flash Text Engine&#8217;s <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/TextLineMirrorRegion.html" title="TextLineMirrorRegion" target="_blank">EventMirrors</a>. I&#8217;ve implemented a (faster, smaller) <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/EventMirror.as" title="EventMirror.as" target="_blank">replacement</a>. You can see this action in <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/AnchorMirror.as" title="AnchorMirror.as" target="_blank">AnchorMirror.as</a></li>
</ul>
<h2>Dependency Injection</h2>
<p>Instead of wiring everything up through the combination of a Facade and maps, I&#8217;ve switched to <a href="https://github.com/tschneidereit/SwiftSuspenders" title="SwiftSuspenders" target="_blank">SwiftSuspenders</a> for Dependency Injection. Using a formal IoC framework makes tinytlf infinitely more extensible, rids the framework of ceremony for the sake of it, and gives us sweet [Inject] syntax to boot. And SwiftSuspenders is only 15K; fucking awesome.</p>
<h2>Maps maps maps</h2>
<p>I&#8217;ve written a generic mapping class, implemented a few interfaces for the sake of IoC mappings (and to reduce map collisions), and stuck them all in the IoC container. This reduces file size and cyclomatic complexity, as each map implementation is the same. That&#8217;s not to say you can&#8217;t extend it; feel free to <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/EventMirrorMap.as#L6" title="EventMirrorMap.as" target="_blank">extend the map</a> and <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/TextEngineInjector.as#L31" title="TextEngineInjector.as" target="_blank">replace it in the IoC container</a> if required.</p>
<h2>HTML and CSS</h2>
<p>The only way anybody is going to work with text is with markup and CSS. So I wrote a small CSS parser to inject and lookup styles, and the model is a DOM built from XML.</p>
<h2>New Rendering Algorithm</h2>
<p>I completely rewrote the render and layout algorithms. The new algorithm is referentially transparent, with zero side effects (aside from a bit of TextLine caching for performance&#8217; sake).</p>
<p>What does that mean to you? There should be no weird bugs or race conditions caused by variables you can&#8217;t replicate in testing.</p>
<p>The previous rendering algorithm was shit. It&#8217;s the primary reason I never implemented editing. Virtualization was hacked in. It suffered from race conditions and required property synchronization, due to an architecture that maintained state and only worked if started in the correct configuration.</p>
<p>I&#8217;ve rewritten the layout algorithm from the ground up, solved all these problems, and exposed more points of extension.</p>
<p>If you want to see the speed of the new layout algorithm, <a href="http://guyinthechair.com/flash/tinytlf/2.0/hello_post/lipsum.html" title="Lipsum demo" target="_blank">scroll through this</a> as fast as you can (looks cool with OS X Lion&#8217;s inertial scrolling). I already know of many places it should be improved, but it&#8217;s a hell of a lot better than what it was!</p>
<h2>New interactions via Reactive eXtensions</h2>
<p>Reactive Programming is already a wave breaking over the .NET (and maybe JS?) world, but unfortunately ActionScript developers have been largely left behind by this revolution in interactive programming, and have suffered for it.</p>
<p>Big thanks to <a href="http://blog.richardszalay.com/" title="Richard Szalay" target="_blank">Richard Szalay</a> for <a href="https://github.com/richardszalay/raix/wiki/" title="raix" target="_blank">raix</a>, his port of Rx.NET to AS3.</p>
<p>I wrote a class called <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/Observables.as" title="Observables.as" target="_blank">Observables</a> which creates and manages IObservable streams for various interaction<br />
events, some of which (like <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/Observables.as#L279" title="drag gesture" target="_blank">drag</a>, <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/Observables.as#L217" title="double down gesture" target="_blank">doubleDown</a>, <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/Observables.as#L289" title="double drag gesture" target="_blank">doubleDrag</a>, <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/Observables.as#L238" title="triple down gesture" target="_blank">tripleDown</a>, and <a href="https://github.com/guyinthechair/tinytlf/blob/2e5e8e0a2f1c52340b7ef045a1bd74c124d55886/framework/core/src/org/tinytlf/interaction/Observables.as#L299" title="triple drag gesture" target="_blank">tripleDrag</a>) are compositions of event streams.</p>
<p>Observables.as also allows you to register IEventDispatchers to be included in master IObservable streams. A developer can subscribe to the master streams if he&#8217;s interested in receiving events from all IEventDispatchers registered with Observables.</p>
<h2>HTML Demo</h2>
<p>For my demos, I&#8217;ve chosen to work with the unaltered HTML from a few posts on <a href="http://idlewords.com/" title="Idle Words" target="_blank">idlewords.com</a>, specifically <a href="http://idlewords.com/2011/08/why_arabic_is_terrific.htm" title="Why Arabic is Terrific" target="_blank">Why Arabic is Terrific</a>, and the <a href="http://idlewords.com/2010/07/" title="Idle Words July 2010" target="_blank">July 2010 index page</a>. The text has many features I wish to support: malformed XHTML, CSS, inline styles, tables, lists, anchors, bidirectional text, and floats. Here&#8217;s the demo <a href="http://guyinthechair.com/flash/tinytlf/2.0/hello_post/srcview/index.html" title="demo source" target="_blank">source</a>, <a href="http://guyinthechair.com/flash/tinytlf/2.0/hello_post/assets/html/idlewords.txt" title="idlewords.txt" target="_blank">HTML</a>, and <a href="http://guyinthechair.com/flash/tinytlf/2.0/hello_post/assets/css/arabic.css" title="arabic.css" target="_blank">CSS</a>. <a href="http://guyinthechair.com/flash/tinytlf/2.0/hello_post/Main.html" title="Main.html" target="_blank">Click here</a> to open the SWF in a fullscreen window.</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_1" width="600" height="500">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/2.0/hello_post/Main.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/2.0/hello_post/Main.swf" width="600" height="500">
      <!--<![endif]-->
        Main.swf
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<h2>Where does that leave things?</h2>
<p>I wrote this post to show people that the framework is back in active development. There are already many places I know where performance can be improved. I don&#8217;t have a TextField component yet, decorations aren&#8217;t done, and most HTML tags (and their layout configurations) haven&#8217;t been implemented. Editing is back on the roadmap, but not done either.</p>
<p>Like always, feel free to <a href="mailto:guyinthechair@gmail.com">email me</a> with questions or feature requests, and I&#8217;m always monitoring <a href="https://github.com/guyinthechair/tinytlf" title="guyinthechair's tinytlf" target="_blank">github</a> for forks and pull requests. Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2011/09/hello-tinytlf-2-0-beta/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Tinytlf Updates and new Experiments</title>
		<link>http://guyinthechair.com/2010/11/tinytlf-updates-and-new-experiments/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tinytlf-updates-and-new-experiments</link>
		<comments>http://guyinthechair.com/2010/11/tinytlf-updates-and-new-experiments/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 17:50:15 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=601</guid>
		<description><![CDATA[Sorry for the dearth of tinytlf posts lately, I&#8217;ve been head-down coding tons of new stuff. If you don&#8217;t believe me, check out the git repository history. I&#8217;m working on an official tinytlf demo explorer app, ala minimalcomps but it&#8217;s going to let you do lots of cool stuff. In the meantime, I&#8217;ll post a [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry for the dearth of tinytlf posts lately, I&#8217;ve been head-down coding tons of new stuff. If you don&#8217;t believe me, check out the <a href="https://github.com/guyinthechair/tinytlf/commits/master">git repository history</a>.</p>
<p>I&#8217;m working on an official tinytlf demo explorer app, ala <a href="http://minimalcomps.com/">minimalcomps</a> but it&#8217;s going to let you do lots of cool stuff. In the meantime, I&#8217;ll post a few choice demos to this post, kind of show off what I&#8217;ve been working on.</p>
<h2>Mobile TextField</h2>
<p>First up, huge updates to gestures, behaviors, and decorations. So much that I&#8217;ve been able to come up with this demo, primarily meant for Android devices, but still usable on the desktop. Highlight in this TextField:<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_2" width="480`" height="854">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/demos/Android.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/demos/Android.swf" width="480`" height="854">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
 </p>
<h2>Better HTML support</h2>
<p>Here&#8217;s some awesome HTML demos that <a href="http://twitter.com/tanya">Tanya Gray</a> has put together&#8230;<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_3" width="600" height="600">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/demos/KittehFlow.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/demos/KittehFlow.swf" width="600" height="600">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_4" width="600" height="600">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/demos/KittehHistoryFlow.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/demos/KittehHistoryFlow.swf" width="600" height="600">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
 </p>
<p>and&#8230; maybe Divs and Tables?<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_5" width="600" height="600">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/demos/TinyTLFDemo.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/demos/TinyTLFDemo.swf" width="600" height="600">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
 </p>
<h2>Advanced Constraint Layouts</h2>
<p>Floats aren&#8217;t just for HTML. Floats take advantage of a more generalized layout algorithm, which flows text around <em>constraints</em>. Floats are just a simple (Rectangle) constraint. You can implement the <em>ITextConstraint</em> interface with your own constraint implementation.</p>
<p>Here&#8217;s a few demos that show off the layout algorithm. Special thanks to <a href="http://algorithmist.wordpress.com/" target="_blank" title="The Algorithmist">Jim Armstrong (the Algorithmist)</a> for the spline math.<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_6" width="600" height="600">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/demos/Spline.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/demos/Spline.swf" width="600" height="600">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_7" width="600" height="600">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/demos/SplineScrollerDemo.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/demos/SplineScrollerDemo.swf" width="600" height="600">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
 </p>
<h2>Experimental, Just for Fun</h2>
<p>A gmail-style link editing behavior!<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_8" width="600" height="400">
      <param name="movie" value="http://guyinthechair.com/flash/tinytlf/demos/Ticonderoga.swf" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/flash/tinytlf/demos/Ticonderoga.swf" width="600" height="400">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
 </p>
<p>So you can see I haven&#8217;t been idle! It&#8217;s just a lot of work. All the code for these demos is <a href="http://guyinthechair.com/flash/tinytlf/demos/srcview/source/">here</a>. Fork the framework at <a href="https://github.com/guyinthechair/tinytlf">github</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/11/tinytlf-updates-and-new-experiments/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Dual Image Flow Example</title>
		<link>http://guyinthechair.com/2010/08/dual-image-flow-example/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dual-image-flow-example</link>
		<comments>http://guyinthechair.com/2010/08/dual-image-flow-example/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 12:30:29 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[text layout]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=566</guid>
		<description><![CDATA[Expounding on last week&#8217;s image flow algorithm, I present to you a generalized algorithm for text flow around inline graphics. You can see it here: ImageFlowContainer, and fork the repo here: tinytlf. This algorithm only works for left-aligned paragraphs, if you try it with any other alignment I can&#8217;t guarantee it&#8217;ll look good. These images [...]]]></description>
			<content:encoded><![CDATA[<p>Expounding on last week&#8217;s image flow algorithm, I present to you a generalized algorithm for text flow around inline graphics. You can see it here: <a href="http://github.com/guyinthechair/tinytlf/blob/d1a02a87fd492a81a04edf10695a83df153ce63d/tinytlf-extensions/src/org/tinytlf/layout/ImageFlowContainer.as">ImageFlowContainer</a>, and fork the repo here: <a href="http://github.com/guyinthechair/tinytlf">tinytlf</a>.</p>
<p>This algorithm only works for left-aligned paragraphs, if you try it with any other alignment I can&#8217;t guarantee it&#8217;ll look good. These images don&#8217;t respect float, they&#8217;re just placed at fortuitous positions in the content. They respect box-model padding properties (padding-left, etc.). Also, I changed the default selection colors to be as close to Aqua Blue as possible.</p>
<p>Here&#8217;s the <a href="http://en.wikipedia.org/wiki/Crimson_Rose" target="_blank" title="Atrophaneura hector - Wikipedia, the free encyclopedia">original Wikipedia article</a> for comparison. As always, here&#8217;s the <a href="http://guyinthechair.com/flash/tinytlf/demos/srcview/source/DualImageFlow.as.html">source</a> for this demo. Just <a href="http://guyinthechair.com/flash/tinytlf/demos/srcview/source/assets/crimson_rose_dual_flow.xml.txt">XHTML</a> and <a href="http://guyinthechair.com/flash/tinytlf/demos/srcview/source/assets/wikipedia.css.html">CSS</a>.</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_9" width="600" height="1000" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/DualImageFlow.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/DualImageFlow.swf" width="600" height="1000" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<h2>Selection</h2>
<p>Tinytlf&#8217;s selection algorithms are character and line level algorithms, not block level algorithms like most web browsers. That means that even if you select an entire paragraph, tinytlf only knows you&#8217;re selecting from the paragraph begin index to the paragraph end index.</p>
<p>This leads to some interesting consequences, like an image on the first atomIndex in a line causing the entire line height to be as tall as him. You see some overlap, because tinytlf&#8217;s default <code>selectionAlpha</code> is 0.28.</p>
<p>In addition, all the decorations in tinytlf only draw <strong>underneath</strong> the TextLines. Therefore you don&#8217;t see selection over images, like you would in a web browser. Later I might allow the option for decorating on top of the Lines layer, but I&#8217;ve left it out for 1.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/08/dual-image-flow-example/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Advanced Text Layout in Tinytlf</title>
		<link>http://guyinthechair.com/2010/08/advanced-text-layout-in-tinytlf/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=advanced-text-layout-in-tinytlf</link>
		<comments>http://guyinthechair.com/2010/08/advanced-text-layout-in-tinytlf/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 16:54:58 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[text layout]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=551</guid>
		<description><![CDATA[Since last week, pretty much the most requested feature has been text flow around inline graphics. Yes, even more than editability. I&#8217;ve had cleaning up and adding advanced features to the TextLayout and TextContainer on the tinytlf 1.0 roadmap for a while, but last night I finally got to work on it. These classes are [...]]]></description>
			<content:encoded><![CDATA[<p>Since last week, pretty much the most requested feature has been text flow around inline graphics. Yes, even more than editability. I&#8217;ve had <a href="https://gist.github.com/669e6c56f3a1a7e743c9" target="_blank" title="Happy Refactoring">cleaning up</a> and adding advanced features to the TextLayout and TextContainer on the tinytlf 1.0 roadmap for a while, but last night I finally got to work on it. These classes are only preliminary, but I hope they demo just how powerful tinytlf&#8217;s layout architecture can be.</p>
<p>As always, the source is available here: <a href="http://guyinthechair.com/flash/tinytlf/demos/srcview/source/" target="_blank">source for these demos</a>.</p>
<h2>Text Layout</h2>
<p>Ok, so say we have this <a href="http://en.wikipedia.org/wiki/Atrophaneura_hector" target="_blank">wikipedia entry</a> about the fascinating <strong><i>Atrophaneura hector</i> (Crimson Rose)</strong> butterfly. It&#8217;s a nice article, and tinytlf formats it well (except for the TLMR bug):</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_10" width="600" height="280" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowNoImage.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowNoImage.swf" width="600" height="280" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<h2>Don&#8217;t encyclopedia entries come with an image?</h2>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_11" width="600" height="280" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowLeft.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowLeft.swf" width="600" height="280" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<h3>Much better!</h3>
<h2>Put that image where you want it</h2>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_12" width="600" height="280" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowRight.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowRight.swf" width="600" height="280" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<h3>Alright, now we&#8217;re rockin&#8217;</h3>
<p>Ok, I know this is ugly, but I thought I&#8217;d show off a little bit. You aren&#8217;t constricted to docking on the left or the right, the new layout algorithm will wrap text around images no matter where they are in the markup.</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_13" width="600" height="280" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowCenter.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/ImageFlowCenter.swf" width="600" height="280" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<p><br/></p>
<h2>Features</h2>
<p>This shows off some features I&#8217;ve never talked about before. Of course there&#8217;s flow around the image, but that&#8217;s really just some fancy layout math, it&#8217;s not too complicated. I&#8217;m probably most proud of the fact that <strong>tinytlf intelligently renders only the invalid TextLines</strong>.</p>
<h3>Invalidation</h3>
<p>This is a Flash Text Engine feature, but it&#8217;s one that I love: when members of the FTE ContentElement model change (text, ElementFormat, etc.), the TextBlock will tag the TextLines which render the content &#8220;invalid.&#8221; The FTE can&#8217;t automatically update the TextLines; whomever renders the TextLines (tinytlf, in this case), is responsible for surgically removing and re-rendering the invalid lines.</p>
<p>It&#8217;s a delicate procedure, but tinytlf handles it like a champ. You see the result of this in the examples whenever you roll over an anchor tag and it changes <em>fontPosture</em> or color.</p>
<h3>Layout</h3>
<p>The second part of this is the little bit of fancy math I did to break and layout the lines in the proper order. If you want to see the algorithm, check out the newest <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-extensions/src/org/tinytlf/layout/ImageFlowContainer.as#L9" target="_blank">ImageFlowContainer here</a>.</p>
<p>It&#8217;s not too difficult. Basically, as I lay out the lines, I calculate the (x, y) position for the next TextLine. Because I can change the <code>x</code> and <code>y</code> independently of each other, I can break TextLines across the plane of the graphic.</p>
<p>Where can it go from here? My next feature will be to respect padding set on the <code>&lt;img/&gt;</code> tag. After that will be allowing a way for the <code>&lt;img/&gt;</code> to specify whether it renders inline, causes line/paragraph breaking, etc. There&#8217;s a lot that can be done.</p>
<h3>Caveats</h3>
<p>I haven&#8217;t tested this with more than one image. In theory it should work, but I&#8217;ve been awake for longer than 24 hours, so I can&#8217;t trust I&#8217;m actually thinking as clearly as I think I am o.O.</p>
<p>And yes, there&#8217;s a bug with the links. It&#8217;s especially prominent here, but basically when you move the mouse very quickly, the FTE TextLineMirrorRegions dispatch a &#8220;mouseOver&#8221; but never its corresponding &#8220;mouseOut.&#8221; If anybody on Adobe&#8217;s TLF or FTE team can shed some light on this situation, I&#8217;d be very grateful.</p>
<p>That&#8217;s it, happy coding. <a href="http://github.com/guyinthechair/tinytlf/" target="_blank" title="tinytlf on github">Fork it on github!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/08/advanced-text-layout-in-tinytlf/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Tinytlf Overview</title>
		<link>http://guyinthechair.com/2010/08/tinytlf-overview/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tinytlf-overview</link>
		<comments>http://guyinthechair.com/2010/08/tinytlf-overview/#comments</comments>
		<pubDate>Mon, 23 Aug 2010 07:53:41 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=537</guid>
		<description><![CDATA[Last week I formally introduced tinytlf to the world, just in time for FITC. I was blown away at its reception, the outpouring of feedback and support was amazing, way more than I thought there would be. Thanks a ton if you were a part of that! Part of that feedback was a request for [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I <a href="http://guyinthechair.com/?p=515" target="_blank">formally introduced</a> <a href="http://github.com/guyinthechair/tinytlf/" target="_blank">tinytlf</a> to the world, just in time for <a href="http://www.fitc.ca/">FITC</a>. I was blown away at its reception, the outpouring of feedback and support was amazing, way more than I thought there would be. Thanks a ton if you were a part of that!</p>
<p>Part of that feedback was a request for more information. What makes tinytlf different? What are the features/goals of the project? And (truly) my favorite inquiries, &#8220;does tinytlf have feature X?&#8221; So I thought I&#8217;d write a followup, explaining a bit about my motivations for writing it, my goals for the framework, and a high level overview of some of its key processes.</p>
<p><strong>Note: When I say TextField, I&#8217;m talking about Flash&#8217;s legacy TextField, flash.text.TextField.</strong></p>
<h2>Goals</h2>
<p>Tinytlf has ambitious goals. With tinytlf, I want to create a small, extensible library for developers to write advanced text controls. I want to give developers full control over every facet of the TextField; nothing is sacred, and every piece replaceable with a more suitable implementation. I want a TextField that finally parses real HTML, and applies real CSS stylesheets. I want a TextField that, while still visually consistent, finally provides interactive capabilities on par with the OS native text controls.</p>
<h3>Native</h3>
<p>Flash&#8217;s TextField has never been as good as the native OS offering. Like it or not, text is a place where [the dreaded] HTML5 has a clear advantage over Flash. I&#8217;d be willing to go as far as to say that it&#8217;s one of the main reasons many web developers, &#8220;technologists&#8221; (yes I&#8217;ve seen that job description), and web-savvy users hate on Flash content. They expect their text to be selectable across TextField instances. They expect the mouse and keyboard interactions to be the same as their OS of choice. They expect the text decorations to be just as eye-popping as the rest of Flash&#8217;s visuals. And it&#8217;s sad to say they aren&#8217;t.</p>
<h3>HTML and CSS</h3>
<p>It&#8217;s never been very easy for Flash developers either. The most common representation of rich text on the web is HTML. The TextField does support a subset of HTML tags; <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/TextField.html#htmlText" target="_blank">11 of them</a> to be exact. But you are stuck with those 11, and you have virtually no control over the styling or rendering of the content. Want stars for list items instead of bullets? Too bad. Don&#8217;t want your links underlined? Tough luck.</p>
<p>The CSS support is pitiful too. You can import CSS into a StyleSheet object, then apply the StyleSheet to the TextField, but it too only supports a subset of styles. On top of that, the TextField is no longer editable. So bon voyage to a Rich Text Editor that respects CSS! For that, you have to use the alternate and incompatible TextFormat class, but that requires management by developers and doesn&#8217;t offer any more styling options than StyleSheet!</p>
<h3>Modularity</h3>
<p>These days, modularity is a buzz word thrown around for good measure. Writing modular systems is the goal of every developer and framework, but it&#8217;s a promise that is seldom kept. Tinytlf ensures modularity by keeping strict separation of concern and delegating the bulk of the functionality to small, externally defined controller classes. Tinytlf has four actor maps, which allows for controllers to be defined or replaced from the outside.</p>
<p>For example, every text decoration in tinytlf is written externally and mapped into the framework at startup. There&#8217;s nothing inherently special about the word &#8220;underline&#8221;, or the class that draws underline decorations. It&#8217;s only what was defined and mapped in at runtime. So if you want to write your own class that draws underlines, you can, and externally map it in and replace tinytlf&#8217;s default implementation.</p>
<p>This same pattern is used over and over throughout the system, and gives you a new level of control over the TextField like you&#8217;ve never had before. If you want to support a new HTML tag, you can write a controller which parses that HTML tag. If you want a new decoration, write the implementation and map it in! If you need to fix a bug in one of tinytlf&#8217;s controllers, write the fix and replace the default controller. (Then contribute it back!)</p>
<h2>A Text Layout Framework</h2>
<p>Allow me to define the general problems a TLF has to solve:</p>
<ul>
<li>Model definition and resolution/parsing</li>
<li>Text decorations (<span style='text-decoration:underline;'>underline</span>, <span style='text-decoration:line-through;'>strikethrough</span>, etc).</li>
<li>Text interaction (both generic and <a href="#" title="Example of context-sensitive text interaction">context-sensitive</a>)
<li>Styles/formatting (notably inline and cascading styles)</li>
<li>Rendering algorithms for the font glyphs that respects styles and formatting</li>
<li>Layout algorithms that respect the model, decorations, and styles of the text</li>
</ul>
<p>Luckily, tinytlf doesn&#8217;t have to solve all these problems alone. Tinytlf gets a tremendous amount of help from the Flash Player, through the Flash Text Engine API.</p>
<table width="100%">
<tr>
<td width="50%"><strong>Flash Text Engine&#8217;s responsibilities</strong></td>
<td width="50%"><strong>Tinytlf&#8217;s  responsibilities</strong></td>
</tr>
<tr>
<td width="50%">
<ul>
<li>Model definition</li>
<li>Contextual text interactions</li>
<li>Inline styles</li>
<li>Glyph rendering algorithms</li>
</ul>
</td>
<td width="50%">
<ul>
<li>Model resolution and parsing</li>
<li>Generic text interactions</li>
<li>Cascading and inline style application</li>
<li>Layout algorithms, including text flow around images and flow between containers</li>
<li>Text decorations</li>
<li>The default definition of a TextField component</li>
</ul>
</td>
</tr>
</table>
<h2>Architecture Overview</h2>
<p>Tinytlf&#8217;s architecture allows all these pieces to come together, ensuring tinytlf is more than the sum of its parts.</p>
<p>Tinytlf is broken into five separate projects: <strong>utils</strong>, <strong>core</strong>, <strong>gestures</strong>, <strong>extensions</strong>, and <strong>components</strong>, respectively. Each project builds on the features of the previous project. You &#8220;pay as you go,&#8221; deciding for yourself what features you need and at what cost. For ease of use, you can use the components library, which is the default TextField, and depends on every project.</p>
<p>If you want, you can start over from <strong>core</strong>. Tinytlf is 100% interfaces, so, much like robotlegs, the default classes are just the reference implementation.</p>
<h3>A Text Engine</h3>
<p>The core of tinytlf is the <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/ITextEngine.as#L18" target="_blank"><code>TextEngine</code></a> actor, responsible for invalidation, selection, and tracking the <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/TextBlock.html" target="_blank">TextBlocks</a> in the TextField. <code>TextEngine</code> is also a <code>facade</code> pattern, which unifies tinytlf&#8217;s four unique subsystems: <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/layout/ITextLayout.as#L16" target="_blank"><code>TextLayout</code></a>, <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/decor/ITextDecor.as#L12" target="_blank"><code>TextDecor</code></a>, <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/styles/ITextStyler.as#L13" target="_blank"><code>TextStyler</code></a>, and <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/interaction/ITextInteractor.as#L14" target="_blank"><code>TextInteractor</code></a>.</p>
<p>Every tinytlf actor or controller class receives a reference to the central <code>TextEngine</code> actor. Because <code>TextEngine</code> is a <code>facade</code>, any subsystem can call into any other subsystem. For example, the interaction controllers can add or remove text decorations by accessing the <code>TextDecor</code> actor from the <code>TextEngine</code> (e.g. when you mouse over, the controller can add an underline, then when you mouse out, remove it).</p>
<h3>Engine Configuration</h3>
<p>In tinytlf, every actor and controller class is externally defined. So tinytlf&#8217;s <code>TextEngine</code> accepts an <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/ITextEngineConfiguration.as#L3" target="_blank"><code>ITextEngineConfiguration</code></a> implementation to set up the default actors and mappings. For example, see the tinytlf TextField&#8217;s <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-components/src/org/tinytlf/components/flash/TextFieldEngineConfiguration.as#L32" target="_blank"><code>TextFieldEngineConfiguration</code></a>.</p>
<h3>Model Agnosticism</h3>
<p>Tinytlf is model agnostic. It doesn&#8217;t care what format your data originally comes in, only if you can convert it into a tree of FTE <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/text/engine/ContentElement.html" target="_blank"><code>ContentElements</code></a>. The FTE already defined the model, it&#8217;s tinytlf&#8217;s job to resolve the differences between your model and FTE&#8217;s.</p>
<p>The default tinytlf TextField parses XHTML. There&#8217;s nothing inherently special about XHTML; XHTML is ubiquitous and easily converted into a tree of <code>ContentElements</code>. But if your model is not XHTML, you can write an implementation of <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/layout/model/factories/ILayoutFactoryMap.as#L13" target="_blank"><code>ILayoutFactoryMap</code></a>, then replace <code>ITextLayout's</code> <code>textBlockFactory</code> instance with your own.</p>
<h3>Maps Maps Maps</h3>
<p>Tinytlf exposes four maps, which allows for controllers to be externally defined. Tinytlf&#8217;s actors rely on definitions in their maps, then delegate functionality to the controllers. For example, tinytlf&#8217;s <code>TextDecor</code> exposes a map to define the classes which draw different text decorations. Then, when <code>TextDecor</code> receives instructions to decorate, it checks its map for the decoration definitions:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript3" style="font-family:monospace;">decor<span style="color: #000066; font-weight: bold;">.</span>mapDecoration<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;bgColor&quot;</span><span style="color: #000066; font-weight: bold;">,</span> BackgroundColorDecoration<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
decor<span style="color: #000066; font-weight: bold;">.</span>mapDecoration<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;strike&quot;</span><span style="color: #000066; font-weight: bold;">,</span> StrikeThroughDecoration<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span>
decor<span style="color: #000066; font-weight: bold;">.</span>decorate<span style="color: #000000;">&#40;</span>someObj<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000;">&#123;</span>bgColor<span style="color: #000066; font-weight: bold;">:</span> 0xFF0000<span style="color: #000066; font-weight: bold;">,</span> bgAlpha<span style="color: #000066; font-weight: bold;">:</span> <span style="color: #000000; font-weight:bold;">0.7</span><span style="color: #000066; font-weight: bold;">,</span> strike<span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">true</span><span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></pre></div></div>

<p>In this example, <code>TextDecor</code> will instantiate two decorations, one for &#8220;bgColor&#8221; and one for &#8220;strike.&#8221; There&#8217;s nothing inherently special about those two strings, only that they exist in the map. Because of this, the <code>TextDecor</code> uses the mapped classes.</p>
<p>This is the pattern in three other areas as well: <code>ILayoutFactoryMap</code>, <code>ITextInteractor</code>, and <code>ITextStyler</code>.</p>
<h3>Gestures</h3>
<p>For <strong>context-insensitive</strong> text interaction, tinytlf includes a gestures library. A gesture is similar in spirit to iPhone and Android gestures; a sequence of events that occur in a certain order, so that when the last event occurs, the gesture is &#8220;unlocked,&#8221; and activates its behaviors. Behaviors are tiny command classes that are meant to control one facet of interaction. A great example is the <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-gestures/src/org/tinytlf/interaction/behaviors/mouse/IBeamBehavior.as#L14" target="_blank">IBeamBehavior</a>, which controls whether the cursor is an IBeam or an arrow. Gestures can have multiple behaviors, and the same behavior can be mapped to multiple gestures.</p>
<p>The potential here is for interactivity on par with native text controls, but also allows for flexibility between platforms, like different gestures whether the user is on a PC or Mac. Moving from desktop to mobile? Just swap out mouse-based gestures for touch-based gestures, keeping all the same behaviors, allowing you to keep a consistent experience between devices.</p>
<h3>Layout</h3>
<p>Layout is a complicated problem, but tinytlf manages to cope. Tinytlf has a central <code>ITextLayout</code> actor for the <code>ITextEngine</code>, which renders lines from multiple <code>TextBlocks</code> between multiple <code>DisplayObjectContainers (DOC)</code>. Each DOC gets its own layout controller, called an <code>ITextContainer</code>. I have <a href="http://guyinthechair.com?p=412" title="TextBlocks, TextLines, and Text Layout" target="_blank">previously blogged about</a> various techniques for text layout, which are part of tinytlf&#8217;s default layout controllers. I&#8217;m still working on features for tinytlf v.1.0, but the current algorithm is pretty good.</p>
<p>During layout and re-render, tinytlf will only render the invalid <code>TextLines</code> from each <code>TextBlock</code>. This is one of many optimizations provided by the FTE of which tinytlf takes advantage.</p>
<h2>Still rough around the edges&#8230;</h2>
<p>Tinytlf isn&#8217;t finished. I&#8217;m working furiously to have 1.0 for my <a href="http://www.360flex.com/schedule/" target="_blank">360|Flex session</a>. It needs more gestures and behaviors. I&#8217;m working on the layout algorithm to get text flow around images. Of course, editability is a huge feature everybody requests. I have a general idea of where the bottle necks in the framework are, but I haven&#8217;t done much formal testing. And of course I&#8217;m committed to releasing it with full test coverage.</p>
<p>If you would like to help, you can <a href="mailto:guyinthechair@gmail.com">email me</a> and/or <a href="http://github.com/guyinthechair/tinytlf/" title="tinytlf github repository" target="_blank">jump in</a> any time. The simplest thing you can do is request features. I&#8217;ve built this for myself, so I&#8217;m curious about other people&#8217;s requirements. I&#8217;ve already received some awesome feature requests that have kept my brain churning. At the very least I can keep them in the back of my mind, and try to keep from short-circuiting the framework, making those features impossible.</p>
<p><span style="font-size:22px;">What are you waiting for? <a href="http://github.com/guyinthechair/tinytlf/" title="tinytlf github repository" target="_blank">Fork it on github!</a></span></p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/08/tinytlf-overview/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Introducing tinytlf</title>
		<link>http://guyinthechair.com/2010/08/introducing-tinytlf/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducing-tinytlf</link>
		<comments>http://guyinthechair.com/2010/08/introducing-tinytlf/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 15:56:46 +0000</pubDate>
		<dc:creator>Paul Taylor</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[community]]></category>
		<category><![CDATA[Flash Text Engine]]></category>
		<category><![CDATA[tinytlf]]></category>

		<guid isPermaLink="false">http://guyinthechair.com/?p=515</guid>
		<description><![CDATA[Today I&#8217;m very proud to announce the official public beta release of tinytlf [tiny tee-el-eff], a new ActionScript 3.0 text layout framework I&#8217;ve been working on. I&#8217;m pushing it out as beta v.0.5, with 1.0 due out near the end of September. Adobe&#8217;s TLF and tinytlf Tinytlf isn&#8217;t affiliated in any way with Adobe&#8217;s TLF. [...]]]></description>
			<content:encoded><![CDATA[<p><span style="font-size:18px;">Today </span>I&#8217;m very proud to announce the official public beta release of <a href="http://github.com/guyinthechair/tinytlf/" title="tinytlf github repository" target="_blank">tinytlf</a> [tiny tee-el-eff], a new ActionScript 3.0 text layout framework I&#8217;ve been working on. I&#8217;m pushing it out as beta v.0.5, with 1.0 due out near the end of September.</p>
<h3>Adobe&#8217;s TLF and tinytlf</h3>
<p>Tinytlf isn&#8217;t affiliated in any way with <a href="http://labs.adobe.com/technologies/textlayout/" title="Adobe's Text Layout Framework" target="_blank">Adobe&#8217;s TLF</a>. Adobe has their project and I have mine. Tinytlf is not an add-on to Adobe&#8217;s TLF, it has no dependencies on Adobe&#8217;s TLF, and I haven&#8217;t recycled any TLF code. Tinytlf is a different effort than Adobe&#8217;s TLF.</p>
<h2>Why?</h2>
<p>If the TLF already exists, why create another rich-text framework? Because tinytlf represents a fundamental departure from the design concepts that drove Adobe&#8217;s TLF. Tinytlf has no dedicated model. Tinytlf doesn&#8217;t define the interactions, decorations, layouts, or styles in the framework code, tinytlf expects external definitions of what a &#8220;Text Field&#8221; is.</p>
<p>How does a TextField draw underlines or background colors? How does a TextField manage mouse and keyboard interaction? Instead of answering these questions in the core framework, tinytlf instead says: &#8220;here, you can draw decorations,&#8221; and &#8220;hey, you can interact with text, so how do you want to do it?&#8221;</p>
<p>Extreme modularity, <strong>everything</strong> is exposed and/or expected to be defined externally. Tinytlf has an <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-core/src/org/tinytlf/ITextEngineConfiguration.as#L14">interface specifically for external configuration</a>. Take a look at the <a href="http://github.com/guyinthechair/tinytlf/blob/master/tinytlf-components/src/org/tinytlf/components/flash/TextFieldEngineConfiguration.as#L30">configuration for the default TextField component</a>. Everything, from how to parse and interpret data, to which classes render text decorations, to the user gestures and behaviors that govern interaction, is mapped externally.</p>
<p>Tinytlf is 5 individual projects: <strong>utils</strong>, <strong>core</strong>, <strong>gestures</strong>, <strong>extensions</strong>, and <strong>components</strong>, respectively. Each adds new features and builds on top of the previous projects. It is explicitly structured with pay-as-you-go modularity. The core framework is tiny: <strong>36kb</strong>. Including components, the whole project is <strong>135kb</strong>.</p>
<h2>Features</h2>
<p>Here&#8217;s a quick list of features from the framework so far:</p>
<ul>
<li>Standards compliant XHTML, including inline and some block-level styles.</li>
<li>Real CSS stylesheets: style inheritance, pseudo-classes, and cascading.</li>
<li>A completely configurable decoration engine for drawing shapes in with text.</li>
<li>A two pronged approach to interaction: inclusion of a powerful gestures API, but also the ability to keep interaction contextual to FTE <code>ContentElements</code>.</li>
<li>Complex text layouts, including text flow between <code>DisplayObjectContainers</code>.</li>
<li>Unordered and ordered lists.</li>
<li>Did I mention CSS pseudo-classes?</li>
<li>Hooking into the FTE&#8217;s performance enhancing techniques, such as only re-rendering invalid TextLines.</li>
<li>The speed you expect from a TextField, the power you expect from a Text Engine.</li>
</ul>
<p>&#8230;and so much more.</p>
<h2>Demos</h2>
<p><a href="http://guyinthechair.com/flash/tinytlf/demos/srcview/index.html">Source for both demos</a><br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_14" width="600" height="200" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/CrimsonRose.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/CrimsonRose.swf" width="600" height="200" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
<br />

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_15" width="600" height="420" align="center">
      <param name="movie" value="http://guyinthechair.com/wp-content/uploads/2010/08/TinyTLF_Example.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://guyinthechair.com/wp-content/uploads/2010/08/TinyTLF_Example.swf" width="600" height="420" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>
</p>
<hr/>
<span style="font-size:22px;"><a href="http://github.com/guyinthechair/tinytlf/" title="tinytlf github repository" target="_blank">Fork it on github!</a></span></p>
<h2>From Here?</h2>
<p>Tinytlf still has a long way to go. In the next few days and weeks leading up to my 360|Flex D.C. session, I&#8217;m going to be putting more documentation on the github wiki. I have a lengthy &#8220;Deep Dive&#8221; article that I&#8217;m editing and will post soon, as well as break up for entry into the wiki. I am aiming for a 1.0 launch at 360|Flex D.C. As always, feel free to <a href="mailto:guyinthechair@gmail.com">email me</a> with any questions, feature requests, or general feedback. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://guyinthechair.com/2010/08/introducing-tinytlf/feed/</wfw:commentRss>
		<slash:comments>15</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_16" 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_17" 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_18" 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_19" 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_20" 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_21" 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_22" 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_23" 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_24" 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_25" 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_26" 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_27" 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_28" 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_29" 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>

