Posted By

LeeProbert on 03/24/10


Tagged

textmate text layout Framework TLF TextFlow LinkElement ParagraphElement


Versions (?)

programmatically creating a TextFlow stream of Link Elements


 / Published in: MXML
 

This code relates to an issue with the Adobe Text Layout Framework which you can read about here :

http://forums.adobe.com/message/2682942#2682942

and

http://forums.adobe.com/thread/598789?tstart=0

Basically, if you link several hundred A links together within a paragraph in a TextFlow object it causes a massive performance issue if you then try and format the link to have a hover state.

This code will programmatically add link elements to the flow and importantly will create a new paragraph if the link sits at the start of a new line. This will fix the performance issue as long as there aren't too many links in one paragraph.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application
  3.  
  4. xmlns:fx="http://ns.adobe.com/mxml/2009"
  5. xmlns:s="library://ns.adobe.com/flex/spark"
  6. xmlns:mx="library://ns.adobe.com/flex/mx"
  7. xmlns:maps="com.cravens.nr.maps.*"
  8.  
  9. minWidth="955" minHeight="600"
  10.  
  11. viewSourceURL="srcview/index.html"
  12. >
  13.  
  14. <fx:Declarations>
  15. <maps:MainEventMap id="eventMap" />
  16. <maps:ModelMap id="modelMap" />
  17. </fx:Declarations>
  18.  
  19. <fx:Script>
  20. <![CDATA[
  21. import com.cravens.nr.model.FontsManager;
  22.  
  23. import flash.text.engine.BreakOpportunity;
  24. import flash.text.engine.FontLookup;
  25. import flash.text.engine.RenderingMode;
  26. import flash.text.engine.TypographicCase;
  27.  
  28. import flashx.textLayout.compose.TextFlowLine;
  29. import flashx.textLayout.conversion.TextConverter;
  30. import flashx.textLayout.elements.Configuration;
  31. import flashx.textLayout.elements.LinkElement;
  32. import flashx.textLayout.elements.OverflowPolicy;
  33. import flashx.textLayout.elements.ParagraphElement;
  34. import flashx.textLayout.elements.SpanElement;
  35. import flashx.textLayout.elements.SubParagraphGroupElement;
  36. import flashx.textLayout.elements.TextFlow;
  37. import flashx.textLayout.events.CompositionCompleteEvent;
  38. import flashx.textLayout.events.DamageEvent;
  39. import flashx.textLayout.events.FlowOperationEvent;
  40. import flashx.textLayout.events.UpdateCompleteEvent;
  41. import flashx.textLayout.formats.TextAlign;
  42. import flashx.textLayout.formats.TextLayoutFormat;
  43.  
  44. import mx.collections.ArrayCollection;
  45. import mx.events.FlexEvent;
  46. import mx.utils.ObjectUtil;
  47.  
  48. protected var config:Configuration;
  49.  
  50. protected var paragraphText:String = "<p>";
  51.  
  52. [Bindable]
  53. protected var textFlow:TextFlow;
  54.  
  55. [Bindable]
  56. protected var namesArr:ArrayCollection;
  57.  
  58. protected var linkCount:int = 0;
  59.  
  60. protected var para:ParagraphElement;
  61. protected var link:LinkElement;
  62. protected var space:SpanElement;
  63.  
  64. protected var updateDelayTimer:Timer;
  65.  
  66. //---------------------------------------------------------------------------
  67. public function handleResult(e:Object):void
  68. {
  69. trace("Result:"+ObjectUtil.toString(e));
  70.  
  71. /*
  72. The XML structure returned from the server maps to an ArrayCollection
  73. */
  74. namesArr = e.signatures.signature as ArrayCollection;
  75. startTextFlowCreation();
  76. }
  77. //---------------------------------------------------------
  78. public function handleFault(e:Object):void
  79. {
  80. trace("Fault:"+ObjectUtil.toString(e));
  81. }
  82. //---------------------------------------------------------------------------
  83. protected function startTextFlowCreation():void
  84. {
  85. FontsManager.getInstance();
  86.  
  87. config = Configuration(TextFlow.defaultConfiguration).clone();
  88.  
  89. var linkNormalFormat:TextLayoutFormat = new TextLayoutFormat();
  90. linkNormalFormat.color = 0x000000;
  91. var linkHoverFormat:TextLayoutFormat = new TextLayoutFormat();
  92. linkHoverFormat.color = 0x999999;
  93.  
  94. var defaultFormat:TextLayoutFormat = new TextLayoutFormat();
  95. defaultFormat.paddingTop = 6;
  96. defaultFormat.color = 0x333333;
  97. defaultFormat.textAlign = TextAlign.JUSTIFY;
  98. defaultFormat.textAlignLast = TextAlign.JUSTIFY;
  99. defaultFormat.fontSize = 10;
  100. defaultFormat.lineHeight = 12;
  101. defaultFormat.fontLookup = FontLookup.EMBEDDED_CFF;
  102. defaultFormat.typographicCase = TypographicCase.UPPERCASE;
  103. defaultFormat.renderingMode = RenderingMode.CFF;
  104. defaultFormat.fontFamily = FontsManager.NOVAMONO;
  105.  
  106. config.textFlowInitialFormat = defaultFormat;
  107. config.defaultLinkNormalFormat = linkNormalFormat;
  108. config.defaultLinkHoverFormat = linkHoverFormat;
  109. config.overflowPolicy = OverflowPolicy.FIT_DESCENDERS;
  110.  
  111. textFlow = new TextFlow(config);
  112. textFlow.columnCount = 4;
  113.  
  114. para = new ParagraphElement();
  115. textFlow.addChild(para);
  116.  
  117. updateDelayTimer = new Timer(50,1);
  118. updateDelayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,checkLink);
  119. addLinkElement();
  120. }
  121. //---------------------------------------------------------
  122. protected function addLinkElement():void
  123. {
  124. var o:Object = namesArr[linkCount];
  125. var firstName:String = o.first_name;
  126. var lastName:String = o.last_name;
  127.  
  128. link = new LinkElement();
  129. link.href = "event:"+o.id;
  130. var linkText:SpanElement = new SpanElement();
  131. linkText.text = o.first_name+" "+o.last_name;
  132. space = new SpanElement();
  133. space.text = " ";
  134. link.addChild(linkText);
  135.  
  136. para.addChild(link);
  137. para.addChild(space);
  138.  
  139. textFlow.flowComposer.composeToPosition(textFlow.textLength);
  140.  
  141. updateDelayTimer.start();
  142. }
  143. //---------------------------------------------------------
  144. protected function checkLink(event:TimerEvent = null):void
  145. {
  146. updateDelayTimer.reset();
  147.  
  148. if(link)
  149. {
  150. var linkStart:int = link.getAbsoluteStart();
  151. var linkEnd:int = linkStart+link.textLength;
  152.  
  153. var textFlowLine:TextFlowLine = textFlow.flowComposer.findLineAtPosition(linkStart);
  154. var lineStart:int = textFlowLine.absoluteStart;
  155. var isStartOfLine:Boolean = linkStart==lineStart;
  156.  
  157. if(isStartOfLine && linkStart!=0)
  158. {
  159. para.removeChild(link);
  160. para.removeChild(space);
  161.  
  162. para = new ParagraphElement();
  163. textFlow.addChild(para);
  164.  
  165. para.addChild(link);
  166. para.addChild(space);
  167. }
  168.  
  169. linkCount++;
  170. if(linkCount == namesArr.length) textFlowComplete();
  171. else addLinkElement();
  172. }
  173. }
  174. //---------------------------------------------------------
  175. protected function textFlowComplete():void
  176. {
  177. updateDelayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,checkLink);
  178. updateDelayTimer = null;
  179. }
  180.  
  181. ]]>
  182. </fx:Script>
  183.  
  184. <s:VGroup width="100%" height="100%">
  185. <s:TextArea
  186.  
  187. id="textArea"
  188. width="100%"
  189. height="100%"
  190. textFlow="{textFlow}"
  191. editable="false"
  192. selectable="false"
  193. />
  194.  
  195. </s:VGroup>
  196.  
  197.  
  198. </s:Application>

Report this snippet  

You need to login to post a comment.