Search in sources :

Example 36 with TextLayout

use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.

the class WPathGraphics method drawString.

/**
     * Renders the text specified by the specified <code>String</code>,
     * using the current <code>Font</code> and <code>Paint</code> attributes
     * in the <code>Graphics2D</code> context.
     * The baseline of the first character is at position
     * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
     * The rendering attributes applied include the <code>Clip</code>,
     * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
     * <code>Composite</code> attributes. For characters in script systems
     * such as Hebrew and Arabic, the glyphs can be rendered from right to
     * left, in which case the coordinate supplied is the location of the
     * leftmost character on the baseline.
     * @param s the <code>String</code> to be rendered
     * @param x,&nbsp;y the coordinates where the <code>String</code>
     * should be rendered
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see java.awt.Graphics#setFont
     * @see #setTransform
     * @see #setComposite
     * @see #setClip
     */
@Override
public void drawString(String str, float x, float y, Font font, FontRenderContext frc, float targetW) {
    if (str.length() == 0) {
        return;
    }
    if (WPrinterJob.shapeTextProp) {
        super.drawString(str, x, y, font, frc, targetW);
        return;
    }
    /* If the Font has layout attributes we need to delegate to TextLayout.
         * TextLayout renders text as GlyphVectors. We try to print those
         * using printer fonts - ie using Postscript text operators so
         * we may be reinvoked. In that case the "!printingGlyphVector" test
         * prevents us recursing and instead sends us into the body of the
         * method where we can safely ignore layout attributes as those
         * are already handled by TextLayout.
         * Similarly if layout is needed based on the text, then we
         * delegate to TextLayout if possible, or failing that we delegate
         * upwards to filled shapes.
         */
    boolean layoutNeeded = strNeedsTextLayout(str, font);
    if ((font.hasLayoutAttributes() || layoutNeeded) && !printingGlyphVector) {
        TextLayout layout = new TextLayout(str, font, frc);
        layout.draw(this, x, y);
        return;
    } else if (layoutNeeded) {
        super.drawString(str, x, y, font, frc, targetW);
        return;
    }
    AffineTransform deviceTransform = getTransform();
    AffineTransform fontTransform = new AffineTransform(deviceTransform);
    fontTransform.concatenate(font.getTransform());
    int transformType = fontTransform.getType();
    /* Use GDI for the text if the graphics transform is something
         * for which we can obtain a suitable GDI font.
         * A flip or shearing transform on the graphics or a transform
         * on the font force us to decompose the text into a shape.
         */
    boolean directToGDI = ((transformType != AffineTransform.TYPE_GENERAL_TRANSFORM) && ((transformType & AffineTransform.TYPE_FLIP) == 0));
    WPrinterJob wPrinterJob = (WPrinterJob) getPrinterJob();
    try {
        wPrinterJob.setTextColor((Color) getPaint());
    } catch (ClassCastException e) {
        // peek should detect such paints.
        directToGDI = false;
    }
    if (!directToGDI) {
        super.drawString(str, x, y, font, frc, targetW);
        return;
    }
    /* Now we have checked everything is OK to go through GDI as text
         * with the exception of testing GDI can find and use the font. That
         * is handled in the textOut() call.
         */
    /* Compute the starting position of the string in
         * device space.
         */
    Point2D.Float userpos = new Point2D.Float(x, y);
    Point2D.Float devpos = new Point2D.Float();
    /* Already have the translate from the deviceTransform,
         * but the font may have a translation component too.
         */
    if (font.isTransformed()) {
        AffineTransform fontTx = font.getTransform();
        float translateX = (float) (fontTx.getTranslateX());
        float translateY = (float) (fontTx.getTranslateY());
        if (Math.abs(translateX) < 0.00001)
            translateX = 0f;
        if (Math.abs(translateY) < 0.00001)
            translateY = 0f;
        userpos.x += translateX;
        userpos.y += translateY;
    }
    deviceTransform.transform(userpos, devpos);
    if (getClip() != null) {
        deviceClip(getClip().getPathIterator(deviceTransform));
    }
    /* Get the font size in device coordinates.
         * The size needed is the font height scaled to device space.
         * Although we have already tested that there is no shear,
         * there may be a non-uniform scale, so the width of the font
         * does not scale equally with the height. That is handled
         * by specifying an 'average width' scale to GDI.
         */
    float fontSize = font.getSize2D();
    double devResX = wPrinterJob.getXRes();
    double devResY = wPrinterJob.getYRes();
    double fontDevScaleY = devResY / DEFAULT_USER_RES;
    int orient = getPageFormat().getOrientation();
    if (orient == PageFormat.LANDSCAPE || orient == PageFormat.REVERSE_LANDSCAPE) {
        double tmp = devResX;
        devResX = devResY;
        devResY = tmp;
    }
    double devScaleX = devResX / DEFAULT_USER_RES;
    double devScaleY = devResY / DEFAULT_USER_RES;
    fontTransform.scale(1.0 / devScaleX, 1.0 / devScaleY);
    Point2D.Double pty = new Point2D.Double(0.0, 1.0);
    fontTransform.deltaTransform(pty, pty);
    double scaleFactorY = Math.sqrt(pty.x * pty.x + pty.y * pty.y);
    float scaledFontSizeY = (float) (fontSize * scaleFactorY * fontDevScaleY);
    Point2D.Double ptx = new Point2D.Double(1.0, 0.0);
    fontTransform.deltaTransform(ptx, ptx);
    double scaleFactorX = Math.sqrt(ptx.x * ptx.x + ptx.y * ptx.y);
    float awScale = getAwScale(scaleFactorX, scaleFactorY);
    int iangle = getAngle(ptx);
    ptx = new Point2D.Double(1.0, 0.0);
    deviceTransform.deltaTransform(ptx, ptx);
    double advanceScaleX = Math.sqrt(ptx.x * ptx.x + ptx.y * ptx.y);
    pty = new Point2D.Double(0.0, 1.0);
    deviceTransform.deltaTransform(pty, pty);
    double advanceScaleY = Math.sqrt(pty.x * pty.x + pty.y * pty.y);
    Font2D font2D = FontUtilities.getFont2D(font);
    if (font2D instanceof TrueTypeFont) {
        textOut(str, font, (TrueTypeFont) font2D, frc, scaledFontSizeY, iangle, awScale, advanceScaleX, advanceScaleY, x, y, devpos.x, devpos.y, targetW);
    } else if (font2D instanceof CompositeFont) {
        /* Composite fonts are made up of multiple fonts and each
             * substring that uses a particular component font needs to
             * be separately sent to GDI.
             * This works for standard composite fonts, alternate ones,
             * Fonts that are a physical font backed by a standard composite,
             * and with fallback fonts.
             */
        CompositeFont compFont = (CompositeFont) font2D;
        float userx = x, usery = y;
        float devx = devpos.x, devy = devpos.y;
        char[] chars = str.toCharArray();
        int len = chars.length;
        int[] glyphs = new int[len];
        compFont.getMapper().charsToGlyphs(len, chars, glyphs);
        int startChar = 0, endChar = 0, slot = 0;
        while (endChar < len) {
            startChar = endChar;
            slot = glyphs[startChar] >>> 24;
            while (endChar < len && ((glyphs[endChar] >>> 24) == slot)) {
                endChar++;
            }
            String substr = new String(chars, startChar, endChar - startChar);
            PhysicalFont slotFont = compFont.getSlotFont(slot);
            textOut(substr, font, slotFont, frc, scaledFontSizeY, iangle, awScale, advanceScaleX, advanceScaleY, userx, usery, devx, devy, 0f);
            Rectangle2D bds = font.getStringBounds(substr, frc);
            float xAdvance = (float) bds.getWidth();
            userx += xAdvance;
            userpos.x += xAdvance;
            deviceTransform.transform(userpos, devpos);
            devx = devpos.x;
            devy = devpos.y;
        }
    } else {
        super.drawString(str, x, y, font, frc, targetW);
    }
}
Also used : TrueTypeFont(sun.font.TrueTypeFont) CompositeFont(sun.font.CompositeFont) Font2D(sun.font.Font2D) Rectangle2D(java.awt.geom.Rectangle2D) TextLayout(java.awt.font.TextLayout) Point2D(java.awt.geom.Point2D) PhysicalFont(sun.font.PhysicalFont) AffineTransform(java.awt.geom.AffineTransform)

Example 37 with TextLayout

use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.

the class GlyphListPipe method drawString.

public void drawString(SunGraphics2D sg2d, String s, double x, double y) {
    FontInfo info = sg2d.getFontInfo();
    if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
        SurfaceData.outlineTextRenderer.drawString(sg2d, s, x, y);
        return;
    }
    float devx, devy;
    if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
        double[] origin = { x + info.originX, y + info.originY };
        sg2d.transform.transform(origin, 0, origin, 0, 1);
        devx = (float) origin[0];
        devy = (float) origin[1];
    } else {
        devx = (float) (x + info.originX + sg2d.transX);
        devy = (float) (y + info.originY + sg2d.transY);
    }
    /* setFromString returns false if shaping is needed, and we then back
         * off to a TextLayout. Such text may benefit slightly from a lower
         * overhead in this approach over the approach in previous releases.
         */
    GlyphList gl = GlyphList.getInstance();
    if (gl.setFromString(info, s, devx, devy)) {
        drawGlyphList(sg2d, gl);
        gl.dispose();
    } else {
        // release this asap.
        gl.dispose();
        TextLayout tl = new TextLayout(s, sg2d.getFont(), sg2d.getFontRenderContext());
        tl.draw(sg2d, (float) x, (float) y);
    }
}
Also used : GlyphList(sun.font.GlyphList) FontInfo(sun.java2d.loops.FontInfo) TextLayout(java.awt.font.TextLayout)

Example 38 with TextLayout

use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.

the class PSPathGraphics method drawString.

protected void drawString(String str, float x, float y, Font font, FontRenderContext frc, float w) {
    if (str.length() == 0) {
        return;
    }
    /* If the Font has layout attributes we need to delegate to TextLayout.
         * TextLayout renders text as GlyphVectors. We try to print those
         * using printer fonts - ie using Postscript text operators so
         * we may be reinvoked. In that case the "!printingGlyphVector" test
         * prevents us recursing and instead sends us into the body of the
         * method where we can safely ignore layout attributes as those
         * are already handled by TextLayout.
         */
    if (font.hasLayoutAttributes() && !printingGlyphVector) {
        TextLayout layout = new TextLayout(str, font, frc);
        layout.draw(this, x, y);
        return;
    }
    Font oldFont = getFont();
    if (!oldFont.equals(font)) {
        setFont(font);
    } else {
        oldFont = null;
    }
    boolean drawnWithPS = false;
    float translateX = 0f, translateY = 0f;
    boolean fontisTransformed = getFont().isTransformed();
    if (fontisTransformed) {
        AffineTransform fontTx = getFont().getTransform();
        int transformType = fontTx.getType();
        /* TYPE_TRANSLATION is a flag bit but we can do "==" here
             * because we want to detect when its just that bit set and
             *
             */
        if (transformType == AffineTransform.TYPE_TRANSLATION) {
            translateX = (float) (fontTx.getTranslateX());
            translateY = (float) (fontTx.getTranslateY());
            if (Math.abs(translateX) < 0.00001)
                translateX = 0f;
            if (Math.abs(translateY) < 0.00001)
                translateY = 0f;
            fontisTransformed = false;
        }
    }
    boolean directToPS = !fontisTransformed;
    if (!PSPrinterJob.shapeTextProp && directToPS) {
        PSPrinterJob psPrinterJob = (PSPrinterJob) getPrinterJob();
        if (psPrinterJob.setFont(getFont())) {
            /* Set the text color.
                 * We should not be in this shape printing path
                 * if the application is drawing with non-solid
                 * colors. We should be in the raster path. Because
                 * we are here in the shape path, the cast of the
                 * paint to a Color should be fine.
                 */
            try {
                psPrinterJob.setColor((Color) getPaint());
            } catch (ClassCastException e) {
                if (oldFont != null) {
                    setFont(oldFont);
                }
                throw new IllegalArgumentException("Expected a Color instance");
            }
            psPrinterJob.setTransform(getTransform());
            psPrinterJob.setClip(getClip());
            drawnWithPS = psPrinterJob.textOut(this, str, x + translateX, y + translateY, font, frc, w);
        }
    }
    /* The text could not be converted directly to PS text
         * calls so decompose the text into a shape.
         */
    if (drawnWithPS == false) {
        if (oldFont != null) {
            setFont(oldFont);
            oldFont = null;
        }
        super.drawString(str, x, y, font, frc, w);
    }
    if (oldFont != null) {
        setFont(oldFont);
    }
}
Also used : AffineTransform(java.awt.geom.AffineTransform) Font(java.awt.Font) TextLayout(java.awt.font.TextLayout)

Example 39 with TextLayout

use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.

the class PathGraphics method drawString.

protected void drawString(String str, float x, float y, Font font, FontRenderContext frc, float w) {
    TextLayout layout = new TextLayout(str, font, frc);
    Shape textShape = layout.getOutline(AffineTransform.getTranslateInstance(x, y));
    fill(textShape);
}
Also used : Shape(java.awt.Shape) TextLayout(java.awt.font.TextLayout)

Example 40 with TextLayout

use of java.awt.font.TextLayout in project jdk8u_jdk by JetBrains.

the class PathGraphics method drawString.

public void drawString(AttributedCharacterIterator iterator, float x, float y) {
    if (iterator == null) {
        throw new NullPointerException("attributedcharacteriterator is null");
    }
    TextLayout layout = new TextLayout(iterator, getFontRenderContext());
    layout.draw(this, x, y);
}
Also used : TextLayout(java.awt.font.TextLayout)

Aggregations

TextLayout (java.awt.font.TextLayout)108 AttributedString (java.text.AttributedString)32 Graphics2D (java.awt.Graphics2D)25 FontRenderContext (java.awt.font.FontRenderContext)25 Font (java.awt.Font)20 AttributedCharacterIterator (java.text.AttributedCharacterIterator)17 LineBreakMeasurer (java.awt.font.LineBreakMeasurer)16 Point (java.awt.Point)11 Rectangle (java.awt.Rectangle)10 Rectangle2D (java.awt.geom.Rectangle2D)10 Color (java.awt.Color)9 Paint (java.awt.Paint)8 AffineTransform (java.awt.geom.AffineTransform)8 Shape (java.awt.Shape)7 TextLayoutInfo (g4p_controls.StyledString.TextLayoutInfo)5 Dimension (java.awt.Dimension)5 TextHitInfo (java.awt.font.TextHitInfo)4 ArrayList (java.util.ArrayList)4 Graphics (java.awt.Graphics)3 Insets (java.awt.Insets)3