Reputation: 59
I got a issue with the TLF trying to find the position of an element (e.g. LinkElement), before it is added to the display list.
I tried the following code:
Create my textFlow:
var textFlow:TextFlow = TextConverter.importToFlow(MY_HTML_STRING,
TextConverter.TEXT_FIELD_HTML_FORMAT);
Grab all the Element I need:
var lElem:Array = findLinkElement(textFlow, []);
private function findLinkElement(group:FlowGroupElement, arr:Array):Array {
var childGroups:Array = [];
for (var i:int = 0; i < group.numChildren; i++) {
var element:FlowElement = group.getChildAt(i);
if (element is LinkElement) {
arr.push(element as LinkElement);
} else if (element is FlowGroupElement) {
childGroups.push(element);
}
}
for (i = 0; i < childGroups.length; i++) {
var childGroup:FlowGroupElement = childGroups[i];
findLinkElement(childGroup, arr);
}
return arr;
}
For each element found try to get the boundaries:
for each (var le:LinkElement in lElem){
var abs:int = le.getAbsoluteStart();
var tl:TextLine = le.getTextFlow().flowComposer.getLineAt(abs).getTextLine(true);
var rect:Rectangle = tl.getAtomBounds(tl.getAtomIndexAtCharIndex(abs));
}
It seems I can't retrieve the Textline because the flowComposer is null.
Any idea how I can get the boundaries / why the composer is always null?
Upvotes: 2
Views: 798
Reputation: 18193
The problem is not that the flowComposer is null. It's actually an object, but you've got such a long chain of objects in this expression and something else in that chain is null:
var tl:TextLine = le.getTextFlow().flowComposer.getLineAt(abs).getTextLine(true);
The issue is is that you are getting the character index of each LinkElement
-- this is not the line number. So when you do flowComposer.getLineAt(abs)
it's returning null because that line does not exist.
Instead, you want to use flowComposer.getLineAtPosition(abs)
. Also, as an optimization the entire flow may not have been generated. So before you do this, it is wise to call flowComposer.composeToPosition(abs)
.
Below is your code that I've modified to do the above. You may not need the composeToPosition()
call, it could actually be a performance issue doing it many times inside of a loop. I'll leave that for you to decide.
Here's the code that I used (minus the declaration of my html
variable). The pertinent code that I modified is inside that for each
loop:
var container:Sprite = new Sprite;
stage.addChild(container);
var textFlow:TextFlow = TextConverter.importToFlow(html, TextConverter.TEXT_FIELD_HTML_FORMAT);
var controller:ContainerController = new ContainerController(container, 200,200);
textFlow.flowComposer.addController(controller);
textFlow.flowComposer.updateAllControllers();
var links:Array = findLinkElement(textFlow, []);
// modified this code
for each (var le:LinkElement in links){
var abs:int = le.getAbsoluteStart();
var composer:IFlowComposer = le.getTextFlow().flowComposer;
composer.composeToPosition(abs);
var textFlowLine:TextFlowLine = composer.findLineAtPosition(abs);
var tl:TextLine = textFlowLine.getTextLine(true);
var rect:Rectangle = tl.getAtomBounds(tl.getAtomIndexAtCharIndex(abs));
}
Upvotes: 1