Get characters above Baseline

So I want to be able to fill a Rectangle with a String on my JFrame. I basically have everything working but one small part. The problem is that some characters such as "g" or "," are going below the so called baseline at which others such as "e" are drawn. I want to only find the ones that are above the "line" in a String.

This is my current code (sorry for not complying to java conventions):

public static final void DrawString(String Message, ERect Bounds, Color Color, Font Font)
    // Gets Font Render Context
    FontRenderContext FRC = CanvasGraphics.getFontRenderContext();

    // initializes the font size to some reasonable number
    float FontSize = 25;

    // Gets the bounds of the entire string
    Rectangle StringBounds = Font.deriveFont(FontSize).createGlyphVector(FRC, Message).getPixelBounds(null, 0, 0);
    // Approximates font size by looking at the ratio from expected dimensions to
    // actual ones
    FontSize *= EMath.Min(Bounds.GetWidth() / StringBounds.width, Bounds.GetHeight() / StringBounds.height);

    // Ensures that that the font truly fills out the rect by checking if a bigger
    // font would still fit
    while (true)
        // checks new height
        StringBounds = Font.deriveFont(FontSize + 1).createGlyphVector(FRC, Message).getPixelBounds(null, 0, 0);

        // if it exceeds the bounds, we can use the previous font size
        if (StringBounds.height > Bounds.GetHeight() || StringBounds.width > Bounds.GetWidth())
            StringBounds = Font.deriveFont(FontSize).createGlyphVector(FRC, Message).getPixelBounds(null, 0, 0);
        // font wasn't big enough yet..

    // We set the font
    Font = Font.deriveFont(FontSize);
    // We get the entire height of the String
    float TextHeight = Font.createGlyphVector(FRC, Message).getPixelBounds(null, 0, 0).height;

    // !!! Problem

    // Since some characters go below the y coordinate, such a 'g', we
    // want to figure out what the height to the line is
    float LineTextHeight = Font.createGlyphVector(FRC, GetAboveLineCharacters(Message)).getPixelBounds(null, 0, 0).height;

    // !!! Problem

    // We set the font and color

    // We draw the string in the center of the box
    CanvasGraphics.drawString(Message, Bounds.GetX() + (Bounds.GetWidth() - StringBounds.width) / 2,
            Bounds.GetY() + (Bounds.GetHeight() - TextHeight) / 2 + LineTextHeight);

Basically I need an implementation for "GetAboveLineCharacter" or at least some way to get the height above the line (Problem being that strings like "A" and "e" have different heights.

Thank you very much for your help!

1 answer

  • answered 2019-08-13 10:50 mdre

    Even though it doesn't cover all cases, this is my current workaround for most fonts from what I tested. Its by far not a general solution but it works fine for an approximate:

    private static final String GetAboveLineCharacters(String ToTest)
        final char blank = Character.MIN_VALUE;
        String ToReturn = ToTest.replace('g', blank).replace('y', blank).replace('p', blank).replace('q', blank)
                .replace('j', 'i').replace('J', 'A').replace('a', blank);
        return (ToReturn == "" ? "e" : ToReturn);