|
|
||||||||||||||||||||||||
|
|||||||||||||||||||||||||
Formatting |
|||||||||||||||||||||||||
The API cross references give an immediate access to relevant interfaces and classes. |
|||||||||||||||||||||||||
Font MetricsWe use font metrics to compute the size of atoms for a given graphical context. As the rendering of a font is dependent of the context font metric are cached in it. |
|||||||||||||||||||||||||
The measures are given according to the baseline. The ascent is the difference between the baseline and the top. The descent is the difference between the baseline and the bottom. The width give the size but may differ from the drawing area as for some fonts characters may overflow. | |||||||||||||||||||||||||
Here is the reason to manage array of byte instead of strings or chars. |
|||||||||||||||||||||||||
DistanceA distance is a value whose evaluation returns the available space till the right margin. There is two kinds of distances : immediate distance which is given and lazy distance which is computed according to previous results. For lazy distance dwe can get the accurate (eager) value or the last value computed. A distance knows if there is sufficient place to contain a given dimension. While formatting we maintain a link to the associated glyph, a link to the decalage produced by the children of the box and a reference to the distance of the father. The dependent associated to the value is a pointer to the object that needs to be evaluated after each change. |
|||||||||||||||||||||||||
DecalageA decalage is a value whose evaluation returns the space consume by the children of a glyph according to their father. There is two kind of decalages : decalage to a father and decalages to a brother. As decalages are lazy values we can get the accurate (eager) value or the last value computed. While formatting we maintain a link to the father, and for all non first children a reference to the previous brother. The dependent associated to the value is a pointer to the object that needs to be evaluated after each change. |
|||||||||||||||||||||||||
Choosing and Executing a Formatting ActionWhile formatting we use an alternative structure to keep track of the current proposed formatting action and box location. When the algorithm uses the decalage history to propose another action, first we check that the action is complient with the glyph, next we choose the action whose is better than the other. Currently, the available actions are :
|
|||||||||||||||||||||||||
Formatting AlgorithmA box knows how to compute its size. As this information will be computed in different context (i.e. interactive/ batch mode, incremental or not), we use functors to customize the default behavior. This value is a computed one and allow lazy evaluation or memo function. Dependent objects will be notified when the value changed. Before we can compute the size we must format the box, i.e. determine how to arrange the various children according to the current font metric and within the available space given by the distance. Beside computing distance and decalage, we must provide alternatives that the formatting algorithm will try when the current choice failled. A particular box may or not be complient with a format action and if true implements the associated action. |
|||||||||||||||||||||||||
The standard algorithm for atoms is to check after the placement that the distance is still sufficient. public final void format2D( ... ) { _flyWeight = _flyWeight.format2D(aFontMetric,aDistance); aDistance.checkAfter(this,anAlternative); } For combinators we update the distance structure when going down to the lower level, going to the next brother or going up to the upper level. Before iterating on a child we check before that the space is still sufficient. Finally, when all the children have been formatted we compute the size. public final void format2D( ... ) { ... DistanceInterface theNewDistance = aDistance.lowerLevel(this); GlyphInterface theCurrentSon = null; ... while ( theRank < numberOfChildren() ) { theCurrentSon = getChild(theRank); theNewDistance.checkBefore(anAlternative); aReadyToFormatStrategy.doAlgorithm(aContext,theCurrentSon); theCurrentSon.format2D(...); theNewDistance.newBrother(theCurrentSon); theImproveSizeStrategyForChildren.doAlgorithm(...); } computeSize(...); theNewDistance.upperLevel(); } In the following example, we show the evolution of the distance structure. A new distance with a reference to the older is created when we go to the lower level. This distance is updated when we go through the successive brothers. Finally, the distance is destroyed when we go back to the upper level. The dependent relationship shows how an update must be propagated along the various elements. |
|||||||||||||||||||||||||
Algorithm CustomizationAs we use the same generic formatting algorithm in different context, functors provide the basis for customization.
|
|||||||||||||||||||||||||
API Cross References
| |||||||||||||||||||||||||
|
|||||||||||||||||||||||||
|
|||||||||||||||||||||||||
|
|||||||||||||||||||||||||
|