use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method init.
private void init() {
// first, we need to check for graphic components on the TOP or BOTTOM baselines. So
// we perform the work that used to be in getMetrics here.
float ascent = 0;
float descent = 0;
float leading = 0;
float advance = 0;
// ascent + descent must not be less than this value
float maxGraphicHeight = 0;
float maxGraphicHeightWithLeading = 0;
// walk through EGA's
TextLineComponent tlc;
boolean fitTopAndBottomGraphics = false;
isSimple = true;
for (int i = 0; i < fComponents.length; i++) {
tlc = fComponents[i];
isSimple &= tlc.isSimple();
CoreMetrics cm = tlc.getCoreMetrics();
byte baseline = (byte) cm.baselineIndex;
if (baseline >= 0) {
float baselineOffset = fBaselineOffsets[baseline];
ascent = Math.max(ascent, -baselineOffset + cm.ascent);
float gd = baselineOffset + cm.descent;
descent = Math.max(descent, gd);
leading = Math.max(leading, gd + cm.leading);
} else {
fitTopAndBottomGraphics = true;
float graphicHeight = cm.ascent + cm.descent;
float graphicHeightWithLeading = graphicHeight + cm.leading;
maxGraphicHeight = Math.max(maxGraphicHeight, graphicHeight);
maxGraphicHeightWithLeading = Math.max(maxGraphicHeightWithLeading, graphicHeightWithLeading);
}
}
if (fitTopAndBottomGraphics) {
if (maxGraphicHeight > ascent + descent) {
descent = maxGraphicHeight - ascent;
}
if (maxGraphicHeightWithLeading > ascent + leading) {
leading = maxGraphicHeightWithLeading - ascent;
}
}
leading -= descent;
if (fitTopAndBottomGraphics) {
// we have top or bottom baselines, so expand the baselines array
// full offsets are needed by CoreMetrics.effectiveBaselineOffset
fBaselineOffsets = new float[] { fBaselineOffsets[0], fBaselineOffsets[1], fBaselineOffsets[2], descent, -ascent };
}
float x = 0;
float y = 0;
CoreMetrics pcm = null;
boolean needPath = false;
locs = new float[fComponents.length * 2 + 2];
for (int i = 0, n = 0; i < fComponents.length; ++i, n += 2) {
tlc = fComponents[getComponentLogicalIndex(i)];
CoreMetrics cm = tlc.getCoreMetrics();
if ((pcm != null) && // adjust because of italics
(pcm.italicAngle != 0 || cm.italicAngle != 0) && (pcm.italicAngle != cm.italicAngle || pcm.baselineIndex != cm.baselineIndex || pcm.ssOffset != cm.ssOffset)) {
// 1) compute the area of overlap - min effective ascent and min effective descent
// 2) compute the x positions along italic angle of ascent and descent for left and right
// 3) compute maximum left - right, adjust right position by this value
// this is a crude form of kerning between textcomponents
// note glyphvectors preposition glyphs based on offset,
// so tl doesn't need to adjust glyphvector position
// 1)
float pb = pcm.effectiveBaselineOffset(fBaselineOffsets);
float pa = pb - pcm.ascent;
float pd = pb + pcm.descent;
// pb += pcm.ssOffset;
float cb = cm.effectiveBaselineOffset(fBaselineOffsets);
float ca = cb - cm.ascent;
float cd = cb + cm.descent;
// cb += cm.ssOffset;
float a = Math.max(pa, ca);
float d = Math.min(pd, cd);
// 2)
float pax = pcm.italicAngle * (pb - a);
float pdx = pcm.italicAngle * (pb - d);
float cax = cm.italicAngle * (cb - a);
float cdx = cm.italicAngle * (cb - d);
// 3)
float dax = pax - cax;
float ddx = pdx - cdx;
float dx = Math.max(dax, ddx);
x += dx;
y = cb;
} else {
// no italic adjustment for x, but still need to compute y
// + cm.ssOffset;
y = cm.effectiveBaselineOffset(fBaselineOffsets);
}
locs[n] = x;
locs[n + 1] = y;
x += tlc.getAdvance();
pcm = cm;
needPath |= tlc.getBaselineTransform() != null;
}
// do we want italic padding at the right of the line?
if (pcm.italicAngle != 0) {
float pb = pcm.effectiveBaselineOffset(fBaselineOffsets);
float pa = pb - pcm.ascent;
float pd = pb + pcm.descent;
pb += pcm.ssOffset;
float d;
if (pcm.italicAngle > 0) {
d = pb + pcm.ascent;
} else {
d = pb - pcm.descent;
}
d *= pcm.italicAngle;
x += d;
}
locs[locs.length - 2] = x;
// locs[locs.length - 1] = 0; // final offset is always back on baseline
// ok, build fMetrics since we have the final advance
advance = x;
fMetrics = new TextLineMetrics(ascent, descent, leading, advance);
// build path if we need it
if (needPath) {
isSimple = false;
Point2D.Double pt = new Point2D.Double();
double tx = 0, ty = 0;
SegmentPathBuilder builder = new SegmentPathBuilder();
builder.moveTo(locs[0], 0);
for (int i = 0, n = 0; i < fComponents.length; ++i, n += 2) {
tlc = fComponents[getComponentLogicalIndex(i)];
AffineTransform at = tlc.getBaselineTransform();
if (at != null && ((at.getType() & AffineTransform.TYPE_TRANSLATION) != 0)) {
double dx = at.getTranslateX();
double dy = at.getTranslateY();
builder.moveTo(tx += dx, ty += dy);
}
pt.x = locs[n + 2] - locs[n];
pt.y = 0;
if (at != null) {
at.deltaTransform(pt, pt);
}
builder.lineTo(tx += pt.x, ty += pt.y);
}
lp = builder.complete();
if (lp == null) {
// empty path
tlc = fComponents[getComponentLogicalIndex(0)];
AffineTransform at = tlc.getBaselineTransform();
if (at != null) {
lp = new EmptyPath(at);
}
}
}
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method getOutline.
public Shape getOutline(AffineTransform tx) {
GeneralPath dstShape = new GeneralPath(GeneralPath.WIND_NON_ZERO);
for (int i = 0, n = 0; i < fComponents.length; i++, n += 2) {
TextLineComponent tlc = fComponents[getComponentLogicalIndex(i)];
dstShape.append(tlc.getOutline(locs[n], locs[n + 1]), false);
}
if (tx != null) {
dstShape.transform(tx);
}
return dstShape;
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method createLineFromText.
/**
* Create a TextLine from the Font and character data over the
* range. The range is relative to both the StyledParagraph and the
* character array.
*/
public static TextLine createLineFromText(char[] chars, StyledParagraph styledParagraph, TextLabelFactory factory, boolean isDirectionLTR, float[] baselineOffsets) {
factory.setLineContext(0, chars.length);
Bidi lineBidi = factory.getLineBidi();
int[] charsLtoV = null;
byte[] levels = null;
if (lineBidi != null) {
levels = BidiUtils.getLevels(lineBidi);
int[] charsVtoL = BidiUtils.createVisualToLogicalMap(levels);
charsLtoV = BidiUtils.createInverseMap(charsVtoL);
}
TextLineComponent[] components = getComponents(styledParagraph, chars, 0, chars.length, charsLtoV, levels, factory);
return new TextLine(factory.getFontRenderContext(), components, baselineOffsets, chars, 0, chars.length, charsLtoV, levels, isDirectionLTR);
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextLine method getVisualBounds.
/**
* Return the union of the visual bounds of all the components.
* This incorporates the path. It does not include logical
* bounds (used by carets).
*/
public Rectangle2D getVisualBounds() {
Rectangle2D result = null;
for (int i = 0, n = 0; i < fComponents.length; i++, n += 2) {
TextLineComponent tlc = fComponents[getComponentLogicalIndex(i)];
Rectangle2D r = tlc.getVisualBounds();
Point2D.Float pt = new Point2D.Float(locs[n], locs[n + 1]);
if (lp == null) {
r.setRect(r.getMinX() + pt.x, r.getMinY() + pt.y, r.getWidth(), r.getHeight());
} else {
lp.pathToPoint(pt, false, pt);
AffineTransform at = tlc.getBaselineTransform();
if (at != null) {
AffineTransform tx = AffineTransform.getTranslateInstance(pt.x - at.getTranslateX(), pt.y - at.getTranslateY());
tx.concatenate(at);
r = tx.createTransformedShape(r).getBounds2D();
} else {
r.setRect(r.getMinX() + pt.x, r.getMinY() + pt.y, r.getWidth(), r.getHeight());
}
}
if (result == null) {
result = r;
} else {
result.add(r);
}
}
if (result == null) {
result = new Rectangle2D.Float(Float.MAX_VALUE, Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_VALUE);
}
return result;
}
use of sun.font.TextLineComponent in project jdk8u_jdk by JetBrains.
the class TextMeasurer method makeTextLineOnRange.
private TextLine makeTextLineOnRange(int startPos, int limitPos) {
int[] charsLtoV = null;
byte[] charLevels = null;
if (fBidi != null) {
Bidi lineBidi = fBidi.createLineBidi(startPos, limitPos);
charLevels = BidiUtils.getLevels(lineBidi);
int[] charsVtoL = BidiUtils.createVisualToLogicalMap(charLevels);
charsLtoV = BidiUtils.createInverseMap(charsVtoL);
}
TextLineComponent[] components = makeComponentsOnRange(startPos, limitPos);
return new TextLine(fFrc, components, fBaselineOffsets, fChars, startPos, limitPos, charsLtoV, charLevels, fIsDirectionLTR);
}
Aggregations