Измерьте высоту пикселя повернутой строки Java - PullRequest
1 голос
/ 20 октября 2019

Я пытаюсь вычислить высоту пикселя повернутой строки в Java. В данный момент я создаю аффинное преобразование и поворачиваю его на требуемую величину.

Затем я создаю шрифт, полученный из этого аффинного преобразования. Я также создаю FontRenderContect и GlyphVector.

Когда я пытаюсь получить границы пикселей от вектора глифа, он дает мне высоту текста, как если бы он не вращался

AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(Math.toRadians(45),0,0);

Font rotatedFont = font.deriveFont(affineTransform);

FontRenderContext frc = new FontRenderContext(affineTransform, true, false);


GlyphVector gv = rotatedFont.createGlyphVector(frc, "i");

System.out.println(gv.getPixelBounds(frc, 0, 0).getBounds());

gv = rotatedFont.createGlyphVector(frc, "iiiiiiiiiiii");
System.out.println(gv.getPixelBounds(frc, 0, 0).getBounds());

Результат:

java.awt.Rectangle[x=0,y=1,width=9,height=2]
java.awt.Rectangle[x=0,y=1,width=31,height=2]

Высота должна быть намного больше, поскольку она поворачивается под углом 45 градусов (ширина должна быть равна высоте).

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 21 октября 2019

Определить ограничивающий прямоугольник легко, используя Shape и применяя AffineTransform непосредственно к этой форме.

enter image description here

import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class BoundingBoxRotatedText {

    private JComponent ui = null;
    JLabel output = new JLabel();
    Font font = new Font(Font.SERIF, Font.PLAIN, 20);
    String string = "The quick brown fox jumps over the lazy dog";
    Shape textShape = getShapeOfText(font, string);
    Rectangle2D rectangle = textShape.getBounds2D();

    BoundingBoxRotatedText() {
        initUI();
    }

    public final void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new BorderLayout(4,4));
        ui.setBorder(new EmptyBorder(4,4,4,4));

        ui.add(output);
        output.setIcon(new ImageIcon(getImage()));
    }

    public static Shape getShapeOfText(Font font, String msg) {
        BufferedImage bi = new BufferedImage(
                1, 1, BufferedImage.TYPE_INT_RGB);

        Graphics2D g = bi.createGraphics();

        FontRenderContext frc = g.getFontRenderContext();
        GlyphVector gv = font.createGlyphVector(frc, msg);

        return gv.getOutline();
    }

    public static Shape moveShapeToCenter(Shape shape, int w, int h) {
        Rectangle2D b = shape.getBounds2D();
        double xOff = -b.getX() + ((w - b.getWidth()) / 2d);
        double yOff = -b.getY() + ((h - b.getHeight()) / 2d);
        AffineTransform move = AffineTransform.getTranslateInstance(xOff, yOff);
        return move.createTransformedShape(shape);
    }

    private BufferedImage getImage() {
        int sz = (int)(rectangle.getBounds().width*1.2);
        BufferedImage bi = new BufferedImage(
                sz, sz, BufferedImage.TYPE_INT_RGB);

        Graphics2D g = bi.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, sz, sz);

        Shape shape = moveShapeToCenter(textShape, sz, sz);
        g.setColor(Color.GREEN);
        g.fill(shape);
        g.draw(shape);
        g.draw(shape.getBounds());

        AffineTransform rotate45 = AffineTransform.
                getRotateInstance(Math.PI/4, sz/2, sz/2);
        shape = rotate45.createTransformedShape(shape);
        g.setColor(Color.BLUE);
        g.fill(shape);
        g.draw(shape);
        g.draw(shape.getBounds());

        shape = rotate45.createTransformedShape(shape);
        g.setColor(Color.RED);
        g.fill(shape);
        g.draw(shape);
        g.draw(shape.getBounds());

        g.dispose();

        return bi;
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            try {
                UIManager.setLookAndFeel(
                        UIManager.getSystemLookAndFeelClassName());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            BoundingBoxRotatedText o = new BoundingBoxRotatedText();

            JFrame f = new JFrame(o.getClass().getSimpleName());
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setLocationByPlatform(true);

            f.setContentPane(o.getUI());
            f.pack();
            f.setMinimumSize(f.getSize());

            f.setVisible(true);
        };
        SwingUtilities.invokeLater(r);
    }
}
...