Search in sources :

Example 1 with EmptyPath

use of sun.font.LayoutPathImpl.EmptyPath 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);
            }
        }
    }
}
Also used : CoreMetrics(sun.font.CoreMetrics) Point2D(java.awt.geom.Point2D) TextLineComponent(sun.font.TextLineComponent) AffineTransform(java.awt.geom.AffineTransform) SegmentPathBuilder(sun.font.LayoutPathImpl.SegmentPathBuilder) EmptyPath(sun.font.LayoutPathImpl.EmptyPath)

Aggregations

AffineTransform (java.awt.geom.AffineTransform)1 Point2D (java.awt.geom.Point2D)1 CoreMetrics (sun.font.CoreMetrics)1 EmptyPath (sun.font.LayoutPathImpl.EmptyPath)1 SegmentPathBuilder (sun.font.LayoutPathImpl.SegmentPathBuilder)1 TextLineComponent (sun.font.TextLineComponent)1