Recipe 9.27.
Working with Advanced Text Layout
Problem
You
want to work with advanced
text layout.
Solution
Use the numLines property and the
getCharBoundaries( ),
getCharIndexAtPoint(
), getFirstCharInParagraph( ),
getLineIndexAtPoint(
), getLineIndexOfChar(
), getLine- Length(
), getLineMetrics(
), getLineOffset(
), getLineText( ),
and getParagraphLength(
) methods.
Discussion
In versions of Flash Player up to and including
Flash Player 8, it was difficult to control and read text layout
with much precision. Starting with Flash Player 8.5, though, the
TextField class defines an API for more precise reading of
text layout.
The TextField class defines two methods
for retrieving information about characters from text. The
getCharBoundaries( ) method returns a flash.geom.Rectangle object that
defines the boundaries of the character at the index specified by
the parameter. The getCharIndexAtPoint( ) method returns the
index of a character at the x and y
coordinates specified by the parameters. The following example uses
getCharIndexAtPoint( ) and getCharBoundaries( ) to
highlight a character when the user clicks on it:
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
public class Text extends Sprite {
private var _field:TextField;
private var _highlight:Sprite;
public function Text( ) {
_field = new TextField( );
_field.border = true;
_field.background = true;
_field.multiline = true;
_field.wordWrap = true;
_field.selectable = false;
_field.width = 400;
_field.height = 400;
addChild(_field);
_field.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi tortor purus, aliquet a, ornare ac, suscipit a, est. Nullam hendrerit molestie erat. Nunc nulla tortor, ullamcorper et, elementum vel, fringilla sed, dui. Praesent fermentum interdum orci.";
_field.addEventListener(MouseEvent.CLICK, onClick);
_highlight = new Sprite( );
addChild(_highlight);
}
private function onClick(event:MouseEvent):void {
var index:int = _field.getCharIndexAtPoint(mouseX, mouseY);
var rectangle:Rectangle = _field.getCharBoundaries(index);
_highlight.graphics.clear( );
_highlight.graphics.lineStyle(0, 0, 0);
_highlight.graphics.beginFill(0x00FFFF, .25);
_highlight.graphics.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
_highlight.graphics.endFill( );
}
}
}
The TextField class also defines a
property and methods for retrieving information about lines of
text. The numLines property tells you how many lines of text
a text field contains. The getLineIndexAtPoint( ) method
returns the index of a line at the coordinates specified as the
parameters passed to the method. The getLine- IndexOfChar( )
returns the line index of the line that contains the character with
the index specified by the parameter passed to the method. The
getLineLength( ) method returns the number of characters in
a line specified by its line index. The getLineText( )
method returns the text contained within a line at a specified line
index. The getLineOffset( ) method returns the character
index the first character of a line at a specified line index. The
getLineMetrics( ) method returns a
flash.text.TextLineMetrics object for a line with a
specified line index. The TextLineMetrics class defines
ascent, descent, height, width, leading, and x properties that describe the line of
text.
There are two methods for retrieving information
about paragraphs. The getFirstCharInParagraph( ) method
returns the character index of the first character in a paragraph
that also contains the character at the index specified in the
parameter. The getParagraphLength( ) method returns the
number of characters in a paragraph that contain the character at
the index specified by the parameter.
The following example uses most of the methods
discussed in this recipe to highlight a paragraph when the user
clicks a character:
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.text.TextLineMetrics;
public class Text extends Sprite {
private var _field:TextField;
private var _highlight:Sprite;
public function Text( ) {
_field = new TextField( );
_field.border = true;
_field.background = true;
_field.multiline = true;
_field.wordWrap = true;
_field.selectable = false;
_field.width = 400;
_field.height = 400;
addChild(_field);
_field.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi tortor purus, aliquet a, ornare ac, suscipit a, est. Nullam hendrerit molestie erat. Nunc nulla tortor, ullamcorper et, elementum vel, fringilla sed, dui. Praesent fermentum interdum orci.";
_field.addEventListener(MouseEvent.CLICK, onDoubleClick);
_highlight = new Sprite( );
addChild(_highlight);
}
private function onDoubleClick(event:MouseEvent):void {
var index:int = _field.getCharIndexAtPoint(mouseX, mouseY);
var startIndex:int = _field.getFirstCharInParagraph(index);
var stopIndex:int = startIndex + _field.getParagraphLength(index);
var startLine:int = _field.getLineIndexOfChar(startIndex);
var stopLine:int = _field.getLineIndexOfChar(stopIndex - 1);
var metrics:TextLineMetrics;
var lineCharacter:int;
var rectangle:Rectangle;
_highlight.graphics.clear( );
_highlight.graphics.lineStyle(0, 0, 0);
for(var i:int = startLine; i <= stopLine; i++) {
lineCharacter = _field.getLineOffset(i);
rectangle = _field.getCharBoundaries(lineCharacter);
metrics = _field.getLineMetrics(i);
_highlight.graphics.beginFill(0x00FFFF, .25);
_highlight.graphics.drawRect(rectangle.x, rectangle.y, metrics.width, metrics.height);
_highlight.graphics.endFill( );
}
}
}
}
|