In this series I am going to explain the basics of using Adobe's new Text Framework. In this first part you'll learn about the Flash Text Engine.
The Flash Text Engine (FTE) is a set of new classes (found in the flash.text.engine.* package) that support low-level text functionality in Flash Player 10
While you can use the FTE in Flash Builder 4 to render text, you will probably more often use the TLF
(Text Layout Framework), which is a set of classes built on top of the FTE to provide more high-level text functionality, such as scrolling, selection and editing.
But let's not rush things (TLF will be covered in the next part). Right now let's take a quick look at the main classes of the Flash Text Engine and see what we can do with them.
A TextBlock holds a single paragraph of text, built from 3 types of ContentElements:
( ContentElement is the base class for each of the three, but it's an abstract class so you won't be able to create an instance of it by itself) :
- TextElement , which is simply a string
- GraphicElement which is any graphic or image that you wish to include in your text.
- GroupElement which is a just container for the other two classes, but may also contain other (nested) GroupElements.
The only problem with this TextBlock, however, would be that because it's not a DisplayObject,
no user will ever see it. And in fact, all of the aforementioned classes are purely logical classes in the sense that they just hold information about the text composition, but not the text itself.
Luckily, the TextBlock has a nice method called createTextLine() which, unsuprisingly, takes the TextBlock and generates TextLines from it that can easily be added to the display list (we'll see how it's done in a moment).
One additional class that does not show in the nice diagram above, but is just as important, is the ElementFormat class, which defines the text styling (like the color, alpah, font, etc.) for any ContentElement, via the elementFormat property.
But enough talk. Let's see some things in action! The following example application creates a TextBlock containing the first two sentences from the book "Moby Dick", and displays the first two TextLines from it.
Explanations - after the code (and also inside the code, as comments).
The result : |
The reason is that when you create a TextLine, you also must specify its desired (max) width. In this case I gave the two TextLines 550 pixels each, and that simply was not enough to hold all of my text.
The second thing to note is that for the first parameter, createTextLine() expects you pass the previously created TextLine (or Null if it's the first). This is required so that the function can calculate the position from which it should continue reading the text.
But what if we wanted to change the code so that ALL of my text will be shown, no matter what?
To do that, we would simply have to keep creating TextLines... until we run out of text :
|
createTextLine() returns Null when the end of the text is reached, so at that point we exit the loop.
**
In the next part I'll talk about the more useful Text Layout Framework (TLF) that simplifies things and adds some powerful functionality. I'll demonstrate how you can use it to enable mouse interactions on rendered text (i.e. show a tooltip on a word or phrase on mouseover).
thank you, the explanation was very clear.
ReplyDeleteHi,
ReplyDeletefor chemical formulars in my application I need to convert the sub tag.
I get the formula from the DataBase. I am able to display the formula but not to edit, because every part stays single.
I would need to merge them to a group but I don't know how. I tried some different ways but nothing works.
// variable with content from DataBase
var txtFormulaXMLFOTemp:String = "";
while(txtFormulaXMLFOTemp.length > 0){
formulaXMLFOSubStart = txtFormulaXMLFOTemp.search("lt sub gt" );
formulaXMLFOSubEnd = txtFormulaXMLFOTemp.search("lt/sub gt");
if(formulaXMLFOSubStart > -1 && formulaXMLFOSubEnd > -1 && (formulaXMLFOSubEnd > formulaXMLFOSubStart)){
txtFormulaXMLFO = txtFormulaXMLFOTemp.substring(0, formulaXMLFOSubStart);
txtFormulaXMLFOStart = txtFormulaXMLFO;
txtFormulaXMLFOSub = txtFormulaXMLFOTemp.substring((formulaXMLFOSubStart + 5), formulaXMLFOSubEnd);
txtFormulaXMLFOTemp = txtFormulaXMLFOTemp.substring((formulaXMLFOSubEnd + 6), txtFormulaXMLFOTemp.length);
var richTxtFormulaFOStart:RichEditableText;
richTxtFormulaFOStart = new RichEditableText();
richTxtFormulaFOStart.text = txtFormulaXMLFOStart;
hGroupEditView.addElement(richTxtFormulaFOStart);
var richTxtFormulaFOSub:RichEditableText;
richTxtFormulaFOSub = new RichEditableText();
richTxtFormulaFOSub.text = txtFormulaXMLFOSub;
richTxtFormulaFOSub.textFlow.baselineShift = "subscript";
richTxtFormulaFOSub.textFlow.dominantBaseline = "ascent";
richTxtFormulaFOSub.validateNow();
hGroupEditView.addElement(richTxtFormulaFOSub);
}
else{
txtFormulaXMLFO = txtFormulaXMLFOTemp;
txtFormulaXMLFOEnd = txtFormulaXMLFO;
var richTxtFormulaFOEnd:RichEditableText;
richTxtFormulaFOEnd = new RichEditableText();
richTxtFormulaFOEnd.text = txtFormulaXMLFOEnd;
hGroupEditView.addElement(richTxtFormulaFOEnd);
}
My future goal:
Below "editorFO" is a ButtonBarButton with some further possibilities to change the formula (bold, underline, add greek letters).
That works like shown in other examples:
protected function subBtn_clickHandler(evt:MouseEvent):void {
var txtLayFmt:TextLayoutFormat = editor.getFormatOfRange(null,
editor.selectionAnchorPosition,
editor.selectionActivePosition);
txtLayFmt.baselineShift = (txtLayFmt.baselineShift == BaselineShift.SUBSCRIPT ? BaselineShift.SUBSCRIPT : BaselineShift.SUBSCRIPT);
editor.setFormatOfRange(txtLayFmt,
editor.selectionAnchorPosition,
editor.selectionActivePosition);
editor.setFocus();
}
Any help is most appreciated.
Thank you
Ellen