|
|
|
|
Formatting
|
|
The API cross references
give an immediate access to relevant interfaces and classes.
|
|
Font Metrics
We 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.
|
|
Distance
A 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.
|
|
|
|
Decalage
A 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 Action
While 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 :
- reducing the interword,
- reducing the indentation,
- shrinking a glyph,
- shrinking some children of a glyph,
- breaking a line,
- doing nothing.
|
|
|
|
Formatting Algorithm
A 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 Customization
As we use the same generic
formatting algorithm
in different context, functors provide the basis
for customization.
- In interactive mode, the
StrategySetOrigin.INCREMENTAL
save the old origin before storing the new value. This
information will be use to compute the optimal refresh
area.
- In interactive mode, the
StrategySetSize.INCREMENTAL
save the old dimension before storing the new value. This
information will be use to compute the optimal refresh
area.
- When building a big box structure with parallel
display the
StrategyReadyToFormat.UNSAFE
will test that the box is stable before trying to format.
- When building a big box structure with parallel
display the
StrategyImproveSizeEstimation.ACTIVE
will trigger regular formatting of the current box
structure to allow early display.
|
|
API Cross References
- Interfaces:
- Classes:
- Exceptions:
|
|
|
|
|
|
|
|
|
|