3

I have a region in my JPanel bounded by the point (0,0) and (width,height). It is a square.

I have a word

String s;

I'd like to find the maximum font size that I can use for s. Now, I know there is a way to do it using FontMetrics and making a for loop to keep increasing the size of the font until it doesn't fit inside the region. But this is SO inefficient and there must be a way to compute the font size of a given font type, such as "Courier" that will fit in this region.

Example of BAD way:

Font f = new Font("Courier", Font.PLAIN, 1);
FontMetrics fm = this.getFontMetrics(f); //this is a JPanel
do {
    f = new Font("Courier", Font.PLAIN, f.getSize()+1);
    fm = this.getFontMetrics(f);
while(fm.stringWidth(s) < width && fm.getHeight() < height);
4

2 に答える 2

2

私は同じ問題を抱えていて、すべてのフォントサイズを繰り返すだけでなく、少し最適化された解決策を見つけました。1未満のdiffフォントサイズが見つかるまで、加算または減算するdiffを調整することにより、最適なフォントサイズに収束しようとします。

Graphics2D graphics = image.createGraphics();
graphics.setColor(Color.black);

if (subtitleFont == null) {
    //create rectangle first (from a separate library
    int[] rect = matrix.getEnclosingRectangle();
    // define the maximum rect for the text
    Rectangle2D maxRect = new Rectangle2D.Float(0, 0, w - 7, h - rect[0] - rect[3] - 10);

    subtitleX = 0;
    subtitleY = 0;
    // starting with a very big font due to a high res image
    float size = 80f * 4f;
    // starting with a diff half the size of the font
    float diff = size / 2;
    subtitleFont = graphics.getFont().deriveFont(Font.BOLD).deriveFont(size);
    FontMetrics fontMetrics = graphics.getFontMetrics(subtitleFont);
    Rectangle2D stringBounds = null;

    while (Math.abs(diff) > 1) {
        subtitleFont = subtitleFont.deriveFont(size);
        graphics.setFont(subtitleFont);
        fontMetrics = graphics.getFontMetrics(subtitleFont);
        stringBounds = fontMetrics.getStringBounds(options.subtitle, graphics);
        stringBounds = new Rectangle2D.Float(0f, 0f, (float) (stringBounds.getX() + stringBounds.getWidth()), (float) ( stringBounds.getHeight()));

        if (maxRect.contains(stringBounds)) {
            if (0 < diff) {
                diff = Math.abs(diff);
            } else if (diff < 0) {
                diff = Math.abs(diff) / 2;
            }
        } else {
            if (0 < diff) {
                diff = - Math.abs(diff) / 2;
            } else if (diff < 0) {
                if (size <= Math.abs(diff)) {
                    diff = - Math.abs(diff) / 2;
                } else {
                    diff = - Math.abs(diff);
                }
            }
        }
        size += diff;
    }

    subtitleX = (int) ((w/2) - (stringBounds.getWidth() / 2));
    subtitleY = (int) (h - maxRect.getHeight() + fontMetrics.getAscent());
}

graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
        RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics.drawString(options.subtitle, subtitleX, subtitleY);

画像の解像度とフォントのサイズを変えて試してみました。最大の長方形に合うフォントが見つかるまで、10〜12回の反復が必要です。誰かのお役に立てば幸いです。

于 2012-10-06T15:37:36.770 に答える