textutilities.java

来自「JfreeChart 常用图表例子」· Java 代码 · 共 885 行 · 第 1/3 页

JAVA
885
字号
     * @param g2  the graphics device.     * @param x  the x coordinate for the anchor point.     * @param y  the y coordinate for the anchor point.     * @param textAnchor  the text anchor.     * @param angle  the angle.     * @param rotationAnchor  the rotation anchor.     *      * @return The bounds (possibly <code>null</code>).     */    public static Shape calculateRotatedStringBounds(final String text,             final Graphics2D g2, final float x, final float y,            final TextAnchor textAnchor, final double angle,            final TextAnchor rotationAnchor) {        if (text == null || text.equals("")) {            return null;        }        final float[] textAdj = deriveTextBoundsAnchorOffsets(            g2, text, textAnchor        );        if (logger.isDebugEnabled()) {            logger.debug(                "TextBoundsAnchorOffsets = " + textAdj[0] + ", " + textAdj[1]            );           }        final float[] rotateAdj = deriveRotationAnchorOffsets(            g2, text, rotationAnchor        );        if (logger.isDebugEnabled()) {            logger.debug(                "RotationAnchorOffsets = " + rotateAdj[0] + ", " + rotateAdj[1]            );           }        final Shape result = calculateRotatedStringBounds(            text, g2, x + textAdj[0], y + textAdj[1],            angle, x + textAdj[0] + rotateAdj[0], y + textAdj[1] + rotateAdj[1]        );        return result;                }        /**     * A utility method that calculates the anchor offsets for a string.       * Normally, the (x, y) coordinate for drawing text is a point on the      * baseline at the left of the text string.  If you add these offsets to      * (x, y) and draw the string, then the anchor point should coincide with      * the (x, y) point.     *     * @param g2  the graphics device (not <code>null</code>).     * @param text  the text.     * @param anchor  the anchor point.     *     * @return  The offsets.     */    private static float[] deriveTextBoundsAnchorOffsets(final Graphics2D g2,             final String text, final TextAnchor anchor) {        final float[] result = new float[2];        final FontRenderContext frc = g2.getFontRenderContext();        final Font f = g2.getFont();        final FontMetrics fm = g2.getFontMetrics(f);        final Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);        final LineMetrics metrics = f.getLineMetrics(text, frc);        final float ascent = metrics.getAscent();        final float halfAscent = ascent / 2.0f;        final float descent = metrics.getDescent();        final float leading = metrics.getLeading();        float xAdj = 0.0f;        float yAdj = 0.0f;        if (anchor == TextAnchor.TOP_CENTER                || anchor == TextAnchor.CENTER                || anchor == TextAnchor.BOTTOM_CENTER                || anchor == TextAnchor.BASELINE_CENTER                || anchor == TextAnchor.HALF_ASCENT_CENTER) {                                xAdj = (float) -bounds.getWidth() / 2.0f;                    }        else if (anchor == TextAnchor.TOP_RIGHT                || anchor == TextAnchor.CENTER_RIGHT                || anchor == TextAnchor.BOTTOM_RIGHT                || anchor == TextAnchor.BASELINE_RIGHT                || anchor == TextAnchor.HALF_ASCENT_RIGHT) {                                xAdj = (float) -bounds.getWidth();                    }        if (anchor == TextAnchor.TOP_LEFT                || anchor == TextAnchor.TOP_CENTER                || anchor == TextAnchor.TOP_RIGHT) {                                yAdj = -descent - leading + (float) bounds.getHeight();                    }        else if (anchor == TextAnchor.HALF_ASCENT_LEFT                || anchor == TextAnchor.HALF_ASCENT_CENTER                || anchor == TextAnchor.HALF_ASCENT_RIGHT) {                                yAdj = halfAscent;                    }        else if (anchor == TextAnchor.CENTER_LEFT                || anchor == TextAnchor.CENTER                || anchor == TextAnchor.CENTER_RIGHT) {                                yAdj = -descent - leading + (float) (bounds.getHeight() / 2.0);                    }        else if (anchor == TextAnchor.BASELINE_LEFT                || anchor == TextAnchor.BASELINE_CENTER                || anchor == TextAnchor.BASELINE_RIGHT) {                                yAdj = 0.0f;                    }        else if (anchor == TextAnchor.BOTTOM_LEFT                || anchor == TextAnchor.BOTTOM_CENTER                || anchor == TextAnchor.BOTTOM_RIGHT) {                                yAdj = -metrics.getDescent() - metrics.getLeading();                    }        result[0] = xAdj;        result[1] = yAdj;        return result;    }    /**     * A utility method that calculates the rotation anchor offsets for a      * string.  These offsets are relative to the text starting coordinate      * (BASELINE_LEFT).     *     * @param g2  the graphics device.     * @param text  the text.     * @param anchor  the anchor point.     *     * @return  The offsets.     */    private static float[] deriveRotationAnchorOffsets(final Graphics2D g2,             final String text, final TextAnchor anchor) {        final float[] result = new float[2];        final FontRenderContext frc = g2.getFontRenderContext();        final LineMetrics metrics = g2.getFont().getLineMetrics(text, frc);        final FontMetrics fm = g2.getFontMetrics();        final Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);        final float ascent = metrics.getAscent();        final float halfAscent = ascent / 2.0f;        final float descent = metrics.getDescent();        final float leading = metrics.getLeading();        float xAdj = 0.0f;        float yAdj = 0.0f;        if (anchor == TextAnchor.TOP_LEFT                || anchor == TextAnchor.CENTER_LEFT                || anchor == TextAnchor.BOTTOM_LEFT                || anchor == TextAnchor.BASELINE_LEFT                || anchor == TextAnchor.HALF_ASCENT_LEFT) {            xAdj = 0.0f;        }        else if (anchor == TextAnchor.TOP_CENTER                || anchor == TextAnchor.CENTER                || anchor == TextAnchor.BOTTOM_CENTER                || anchor == TextAnchor.BASELINE_CENTER                || anchor == TextAnchor.HALF_ASCENT_CENTER) {                                xAdj = (float) bounds.getWidth() / 2.0f;                   }        else if (anchor == TextAnchor.TOP_RIGHT                || anchor == TextAnchor.CENTER_RIGHT                || anchor == TextAnchor.BOTTOM_RIGHT                || anchor == TextAnchor.BASELINE_RIGHT                || anchor == TextAnchor.HALF_ASCENT_RIGHT) {                                xAdj = (float) bounds.getWidth();                    }        if (anchor == TextAnchor.TOP_LEFT                || anchor == TextAnchor.TOP_CENTER                || anchor == TextAnchor.TOP_RIGHT) {                                yAdj = descent + leading - (float) bounds.getHeight();                    }        else if (anchor == TextAnchor.CENTER_LEFT                || anchor == TextAnchor.CENTER                || anchor == TextAnchor.CENTER_RIGHT) {                                yAdj = descent + leading - (float) (bounds.getHeight() / 2.0);                    }        else if (anchor == TextAnchor.HALF_ASCENT_LEFT                || anchor == TextAnchor.HALF_ASCENT_CENTER                || anchor == TextAnchor.HALF_ASCENT_RIGHT) {                                yAdj = -halfAscent;                    }        else if (anchor == TextAnchor.BASELINE_LEFT                || anchor == TextAnchor.BASELINE_CENTER                || anchor == TextAnchor.BASELINE_RIGHT) {                                yAdj = 0.0f;                    }        else if (anchor == TextAnchor.BOTTOM_LEFT                || anchor == TextAnchor.BOTTOM_CENTER                || anchor == TextAnchor.BOTTOM_RIGHT) {                                yAdj = metrics.getDescent() + metrics.getLeading();                    }        result[0] = xAdj;        result[1] = yAdj;        return result;    }    /**     * Returns a shape that represents the bounds of the string after the      * specified rotation has been applied.     *      * @param text  the text (<code>null</code> permitted).     * @param g2  the graphics device.     * @param textX  the x coordinate for the text.     * @param textY  the y coordinate for the text.     * @param angle  the angle.     * @param rotateX  the x coordinate for the rotation point.     * @param rotateY  the y coordinate for the rotation point.     *      * @return The bounds (<code>null</code> if <code>text</code> is      *         </code>null</code> or has zero length).     */    public static Shape calculateRotatedStringBounds(final String text,                                                     final Graphics2D g2,                                                     final float textX,                                                     final float textY,                                                     final double angle,                                                     final float rotateX,                                                     final float rotateY) {        if ((text == null) || (text.equals(""))) {            return null;        }        final FontMetrics fm = g2.getFontMetrics();        final Rectangle2D bounds = TextUtilities.getTextBounds(text, g2, fm);        final AffineTransform translate = AffineTransform.getTranslateInstance(            textX, textY        );        final Shape translatedBounds = translate.createTransformedShape(bounds);        final AffineTransform rotate = AffineTransform.getRotateInstance(            angle, rotateX, rotateY        );        final Shape result = rotate.createTransformedShape(translatedBounds);        return result;    }    /**      * A flag that controls whether the FontMetrics.getStringBounds() method      * is used or a workaround is applied.     */    private static boolean useFontMetricsGetStringBounds = true;    /**     * Returns the flag that controls whether the FontMetrics.getStringBounds()      * method is used or not.  If you are having trouble with label alignment     * or positioning, try changing the value of this flag.     *      * @return A boolean.     */    public static boolean getUseFontMetricsGetStringBounds() {        return useFontMetricsGetStringBounds;        }        /**     * Sets the flag that controls whether the FontMetrics.getStringBounds()      * method is used or not.  If you are having trouble with label alignment      * or positioning, try changing the value of this flag.     *      * @param use  the flag.     */    public static void setUseFontMetricsGetStringBounds(final boolean use) {        useFontMetricsGetStringBounds = use;       }    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?