Search code examples
javaswingfontsgraphics2d

How to either not provide a font that won't render bold or force it to be bold


I have a zoom function that adjusts the font size of row/column labels to match a displayed grid/image. The row/column label corresponding to the hovered cell is bold and all other labels are plain. However, sometimes the hovered horizontal row label will appear plain even though the vertical column label of the same size appears bold.

I've done some testing and have determined that this is happening at certain standard font sizes (12, 18, 24, etc.) for certain fonts (e.g. Courier) and not for other fonts (e.g. Helvetica Neue). Odd font sizes are bolded as expected for all fonts, including the problematic fonts. Even when the font does not appear as bold, when I call myfont.isBold(), it returns true.

My assessment here is that in the case of some fonts, such as my version of courier, a bold version of the font is not available when the size is one that is provided directly from the font library and thus the font defaults to plain. In the case of the odd font sizes, or when the font is rendered vertically, a programmatic bold style is applied.

Am I correct that this is what is happening? If so, how can I catch when this is happening or going to happen, and either not provide that font as an available font, or force the font to render as bold at the problem sizes (e.g. 12)?

Here is a working example:

import java.awt.*; 

public class Test {
    public static void main ( String[] args ) {
        class helloFrame extends Frame {
            public void paint( Graphics g ) {
                final Graphics2D g2d = (Graphics2D) g;
                g2d.setFont(new Font("Courier",Font.BOLD,12));
                System.out.println("Style is [" + (g2d.getFont().isBold() ? "bold" : "not bold") + "].");
                g2d.drawString("Hello", 10, 40 );
                g2d.setFont(new Font("Courier",Font.BOLD,13));
                System.out.println("Style is [" + (g2d.getFont().isBold() ? "bold" : "not bold") + "].");
                g2d.drawString("Hello", 10, 55 );
                g2d.setFont(new Font("Courier",Font.BOLD,17));
                System.out.println("Style is [" + (g2d.getFont().isBold() ? "bold" : "not bold") + "].");
                g2d.drawString("Hello", 10, 70 );
                g2d.setFont(new Font("Courier",Font.BOLD,18));
                System.out.println("Style is [" + (g2d.getFont().isBold() ? "bold" : "not bold") + "].");
                g2d.drawString("Hello", 10, 85 );
                g2d.setFont(new Font("Courier",Font.BOLD,19));
                System.out.println("Style is [" + (g2d.getFont().isBold() ? "bold" : "not bold") + "].");
                g2d.drawString("Hello", 10, 100 );
            }
        }

        helloFrame frm = new helloFrame();
        frm.setSize(150,120);
        frm.setVisible(true);
    }
}

which prints:

Style is [bold].
Style is [bold].
Style is [bold].
Style is [bold].
Style is [bold].

for every print even though the font does not appear as bold for font sizes 12 & 18:

enter image description here

UPDATE: It appears that this problem is OS-specific. The non-bold text is apparent on Mac but everything appears as it should on Windows.


Solution

  • Try adding:

    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                         RenderingHints.VALUE_ANTIALIAS_ON);
    

    This turns on antialiasing which (at least on my system) greatly improve the font rendering and all sizes appear bold.