TextMetricsCalculatorpublic class TextMetricsCalculator extends Object This class operates with an arbitrary text string which can include
any number of style, font and direction runs. It is responsible for computation
of the text metrics, such as ascent, descent, leading and advance. Actually,
each text run segment contains logic which allows it to compute its own metrics and
responsibility of this class is to combine metrics for all segments included in the text,
managed by the associated TextRunBreaker object. |
Fields Summary |
---|
TextRunBreaker | breaker | float | ascent | float | descent | float | leading | float | advance | private float[] | baselineOffsets | int | baselineIndex |
Constructors Summary |
---|
public TextMetricsCalculator(TextRunBreaker breaker)
this.breaker = breaker;
checkBaselines();
|
Methods Summary |
---|
public void | checkBaselines()Take baseline offsets from the first font or graphic attribute
and normalizes them, than caches the results.
// Take baseline offsets of the first font and normalize them
HashMap<Integer, Font> fonts = breaker.fonts;
Object val = fonts.get(new Integer(0));
if (val instanceof Font) {
Font firstFont = (Font) val;
LineMetrics lm = firstFont.getLineMetrics(breaker.text, 0, 1, breaker.frc);
baselineOffsets = lm.getBaselineOffsets();
baselineIndex = lm.getBaselineIndex();
} else if (val instanceof GraphicAttribute) {
// Get first graphic attribute and use it
GraphicAttribute ga = (GraphicAttribute) val;
int align = ga.getAlignment();
if (
align == GraphicAttribute.TOP_ALIGNMENT ||
align == GraphicAttribute.BOTTOM_ALIGNMENT
) {
baselineIndex = GraphicAttribute.ROMAN_BASELINE;
} else {
baselineIndex = align;
}
baselineOffsets = new float[3];
baselineOffsets[0] = 0;
baselineOffsets[1] = (ga.getDescent() - ga.getAscent()) / 2.f;
baselineOffsets[2] = -ga.getAscent();
} else { // Use defaults - Roman baseline and zero offsets
baselineIndex = GraphicAttribute.ROMAN_BASELINE;
baselineOffsets = new float[3];
}
// Normalize offsets if needed
if (baselineOffsets[baselineIndex] != 0) {
float baseOffset = baselineOffsets[baselineIndex];
for (int i = 0; i < baselineOffsets.length; i++) {
baselineOffsets[i] -= baseOffset;
}
}
| void | computeMetrics()Computes metrics for the text managed by the associated TextRunBreaker
ArrayList<TextRunSegment> segments = breaker.runSegments;
float maxHeight = 0;
float maxHeightLeading = 0;
for (int i = 0; i < segments.size(); i++) {
TextRunSegment segment = segments.get(i);
BasicMetrics metrics = segment.metrics;
int baseline = metrics.baseLineIndex;
if (baseline >= 0) {
float baselineOffset = baselineOffsets[metrics.baseLineIndex];
float fixedDescent = metrics.descent + baselineOffset;
ascent = Math.max(ascent, metrics.ascent - baselineOffset);
descent = Math.max(descent, fixedDescent);
leading = Math.max(leading, fixedDescent + metrics.leading);
} else { // Position is not fixed by the baseline, need sum of ascent and descent
float height = metrics.ascent + metrics.descent;
maxHeight = Math.max(maxHeight, height);
maxHeightLeading = Math.max(maxHeightLeading, height + metrics.leading);
}
}
// Need to increase sizes for graphics?
if (maxHeightLeading != 0) {
descent = Math.max(descent, maxHeight - ascent);
leading = Math.max(leading, maxHeightLeading - ascent);
}
// Normalize leading
leading -= descent;
BasicMetrics currMetrics;
float currAdvance = 0;
for (int i = 0; i < segments.size(); i++) {
TextRunSegment segment = segments.get(breaker.getSegmentFromVisualOrder(i));
currMetrics = segment.metrics;
segment.y = getBaselineOffset(currMetrics.baseLineIndex)
+ currMetrics.superScriptOffset;
segment.x = currAdvance;
currAdvance += segment.getAdvance();
}
advance = currAdvance;
| public void | correctAdvance(BasicMetrics metrics)Corrects advance after justification. Gets BasicMetrics object
and updates advance stored into it.
ArrayList<TextRunSegment> segments = breaker.runSegments;
TextRunSegment segment = segments.get(breaker
.getSegmentFromVisualOrder(segments.size() - 1));
advance = segment.x + segment.getAdvance();
metrics.advance = advance;
| public BasicMetrics | createMetrics()Computes metrics and creates BasicMetrics object from them
computeMetrics();
return new BasicMetrics(this);
| float | getBaselineOffset(int baselineIndex)Returns either values cached by checkBaselines method or reasonable
values for the TOP and BOTTOM alignments.
if (baselineIndex >= 0) {
return baselineOffsets[baselineIndex];
} else if (baselineIndex == GraphicAttribute.BOTTOM_ALIGNMENT) {
return descent;
} else if (baselineIndex == GraphicAttribute.TOP_ALIGNMENT) {
return -ascent;
} else {
// awt.3F=Invalid baseline index
throw new IllegalArgumentException(Messages.getString("awt.3F")); //$NON-NLS-1$
}
| public float[] | getBaselineOffsets()
float ret[] = new float[baselineOffsets.length];
System.arraycopy(baselineOffsets, 0, ret, 0, baselineOffsets.length);
return ret;
|
|