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.
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:maps="com.cravens.nr.maps.*" minWidth="955" minHeight="600" viewSourceURL="srcview/index.html" > <fx:Declarations> <maps:MainEventMap id="eventMap" /> <maps:ModelMap id="modelMap" /> </fx:Declarations> <fx:Script> <![CDATA[ import com.cravens.nr.model.FontsManager; import flash.text.engine.BreakOpportunity; import flash.text.engine.FontLookup; import flash.text.engine.RenderingMode; import flash.text.engine.TypographicCase; import flashx.textLayout.compose.TextFlowLine; import flashx.textLayout.conversion.TextConverter; import flashx.textLayout.elements.Configuration; import flashx.textLayout.elements.LinkElement; import flashx.textLayout.elements.OverflowPolicy; import flashx.textLayout.elements.ParagraphElement; import flashx.textLayout.elements.SpanElement; import flashx.textLayout.elements.SubParagraphGroupElement; import flashx.textLayout.elements.TextFlow; import flashx.textLayout.events.CompositionCompleteEvent; import flashx.textLayout.events.DamageEvent; import flashx.textLayout.events.FlowOperationEvent; import flashx.textLayout.events.UpdateCompleteEvent; import flashx.textLayout.formats.TextAlign; import flashx.textLayout.formats.TextLayoutFormat; import mx.collections.ArrayCollection; import mx.events.FlexEvent; import mx.utils.ObjectUtil; protected var config:Configuration; protected var paragraphText:String = "<p>"; [Bindable] protected var textFlow:TextFlow; [Bindable] protected var namesArr:ArrayCollection; protected var linkCount:int = 0; protected var para:ParagraphElement; protected var link:LinkElement; protected var space:SpanElement; protected var updateDelayTimer:Timer; //--------------------------------------------------------------------------- public function handleResult(e:Object):void { trace("Result:"+ObjectUtil.toString(e)); /* The XML structure returned from the server maps to an ArrayCollection */ namesArr = e.signatures.signature as ArrayCollection; startTextFlowCreation(); } //--------------------------------------------------------- public function handleFault(e:Object):void { trace("Fault:"+ObjectUtil.toString(e)); } //--------------------------------------------------------------------------- protected function startTextFlowCreation():void { FontsManager.getInstance(); config = Configuration(TextFlow.defaultConfiguration).clone(); var linkNormalFormat:TextLayoutFormat = new TextLayoutFormat(); linkNormalFormat.color = 0x000000; var linkHoverFormat:TextLayoutFormat = new TextLayoutFormat(); linkHoverFormat.color = 0x999999; var defaultFormat:TextLayoutFormat = new TextLayoutFormat(); defaultFormat.paddingTop = 6; defaultFormat.color = 0x333333; defaultFormat.textAlign = TextAlign.JUSTIFY; defaultFormat.textAlignLast = TextAlign.JUSTIFY; defaultFormat.fontSize = 10; defaultFormat.lineHeight = 12; defaultFormat.fontLookup = FontLookup.EMBEDDED_CFF; defaultFormat.typographicCase = TypographicCase.UPPERCASE; defaultFormat.renderingMode = RenderingMode.CFF; defaultFormat.fontFamily = FontsManager.NOVAMONO; config.textFlowInitialFormat = defaultFormat; config.defaultLinkNormalFormat = linkNormalFormat; config.defaultLinkHoverFormat = linkHoverFormat; config.overflowPolicy = OverflowPolicy.FIT_DESCENDERS; textFlow = new TextFlow(config); textFlow.columnCount = 4; para = new ParagraphElement(); textFlow.addChild(para); updateDelayTimer = new Timer(50,1); updateDelayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,checkLink); addLinkElement(); } //--------------------------------------------------------- protected function addLinkElement():void { var o:Object = namesArr[linkCount]; var firstName:String = o.first_name; var lastName:String = o.last_name; link = new LinkElement(); link.href = "event:"+o.id; var linkText:SpanElement = new SpanElement(); linkText.text = o.first_name+" "+o.last_name; space = new SpanElement(); space.text = " "; link.addChild(linkText); para.addChild(link); para.addChild(space); textFlow.flowComposer.composeToPosition(textFlow.textLength); updateDelayTimer.start(); } //--------------------------------------------------------- protected function checkLink(event:TimerEvent = null):void { updateDelayTimer.reset(); if(link) { var linkStart:int = link.getAbsoluteStart(); var linkEnd:int = linkStart+link.textLength; var textFlowLine:TextFlowLine = textFlow.flowComposer.findLineAtPosition(linkStart); var lineStart:int = textFlowLine.absoluteStart; var isStartOfLine:Boolean = linkStart==lineStart; if(isStartOfLine && linkStart!=0) { para.removeChild(link); para.removeChild(space); para = new ParagraphElement(); textFlow.addChild(para); para.addChild(link); para.addChild(space); } linkCount++; if(linkCount == namesArr.length) textFlowComplete(); else addLinkElement(); } } //--------------------------------------------------------- protected function textFlowComplete():void { updateDelayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE,checkLink); updateDelayTimer = null; } ]]> </fx:Script> <s:VGroup width="100%" height="100%"> <s:TextArea id="textArea" width="100%" height="100%" textFlow="{textFlow}" editable="false" selectable="false" /> </s:VGroup> </s:Application>
You need to login to post a comment.
