Search in sources :

Example 11 with TextLineComponent

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);
            }
        }
    }
}
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)

Example 12 with TextLineComponent

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;
}
Also used : GeneralPath(java.awt.geom.GeneralPath) TextLineComponent(sun.font.TextLineComponent)

Example 13 with TextLineComponent

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);
}
Also used : Bidi(java.text.Bidi) TextLineComponent(sun.font.TextLineComponent)

Example 14 with TextLineComponent

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;
}
Also used : Point2D(java.awt.geom.Point2D) Rectangle2D(java.awt.geom.Rectangle2D) TextLineComponent(sun.font.TextLineComponent) AffineTransform(java.awt.geom.AffineTransform)

Example 15 with TextLineComponent

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);
}
Also used : Bidi(java.text.Bidi) TextLineComponent(sun.font.TextLineComponent)

Aggregations

TextLineComponent (sun.font.TextLineComponent)15 AffineTransform (java.awt.geom.AffineTransform)4 Rectangle2D (java.awt.geom.Rectangle2D)4 Point2D (java.awt.geom.Point2D)3 Bidi (java.text.Bidi)3 Decoration (sun.font.Decoration)2 Font (java.awt.Font)1 Graphics2D (java.awt.Graphics2D)1 Rectangle (java.awt.Rectangle)1 GeneralPath (java.awt.geom.GeneralPath)1 BufferedImage (java.awt.image.BufferedImage)1 AttributeValues (sun.font.AttributeValues)1 CoreMetrics (sun.font.CoreMetrics)1 FontLineMetrics (sun.font.FontLineMetrics)1 GraphicComponent (sun.font.GraphicComponent)1 EmptyPath (sun.font.LayoutPathImpl.EmptyPath)1 SegmentPathBuilder (sun.font.LayoutPathImpl.SegmentPathBuilder)1 TextLabelFactory (sun.font.TextLabelFactory)1