Search code examples
winapifontspycharmfixed-widthmonospace

how does a font tell the OS that "I AM a MONSPACED / FIXED-WIDTH FONT"?


at the very first, i only want to know, why in IDE PYCHARM on Windows 10, while "show only monospaced fonts" checked, many fonts will not be listed in the editor's font selecting dialog-box[settings/editor/colors and fonts/font], also in mintty.

I don't know how does the pycharm do, but the mintty uses the win32 API "LOGFONT".

then, how did the windows OS know whether the font is monospaced(fixed-width)?

i.e.: "source code pro" is listed, "source code pro black / extralight / light ... are not;

"fira code" is listed, but fira code light/medium/retina are not;

and, some other monospaced fonts are not listed there if "show only monospaced".

it seems that pycharm only recognize the font family name when checked "show only monospced fonts"

in OSX(Mavericks) it's a little complicated : if the 'show only monospaced fonts' was checked, pycharm could still get the family name, but it could not know which font-weight is default if the rugular weighted font version was installed.


then, i tried to modify some fonts, and by the way having a glance to the original font's 'file-info' in font forge, but i don't know which part really effects the WINDOWS or PYCHARM(IDEA/INTELIJ/by JDK in fact?) to know which font is monospaced.

in "OS/2" part, any parameters mentioned fixed-width/monospace/monospaced are checked, but not helped any, and in windows pycharm still can't detect them.

so, at last, i really wonder, which parameter do TTF files or any other font file types use to tell the [windows/osx/mac os/linux] OS that 'i am monospaced'?


Solution

  • PyCharm and for that matter all of the JetBrains IDEA suite do not use font flags to identify monospace fonts. Instead, they determine if a font is monospaced using the following algorithm:

    • Are the 'l', 'W' and ' ' characters of the regular variant the same width at size 12?
    • Are the 'l', 'W' and ' ' characters of the bold variant the same width as the regular variant at size 12?
    • Are the 'l', 'W' and ' ' characters of the italics variant the same width as the regular variant at size 12?
    • Are the 'l', 'W' and ' ' characters of the bold-italics variant the same width as the regular variant at size 12?

    The font will be listed as non-monospace if any of the width calculations above return an inconsistent answer.

    To solve this problem, you should install a bold variant of the font you are trying to use. If a bold version of the font is not available, IntelliJ's font renderer will auto-generate one which affects the width of the characters, and therefore, causes the monospace check to fail.


    Source: The IntelliJ Community Edition Source Code (Excerpts shortened for brevity, and are licensed under the Apache 2.0 license rather than StackOverflow's CC-BY-SA licence.)

    private static int getFontWidth(Font font, int mask) {
        int width = getCharWidth(font, ' ');
        return width == getCharWidth(font, 'l')
            && width == getCharWidth(font, 'W') ? width : 0;
    }
    

    In the FontInfo constructor.

    int width = getFontWidth(font, Font.PLAIN);
    if (!plainOnly) {
        if (width != 0 && width != getFontWidth(font, Font.BOLD)) width = 0;
        if (width != 0 && width != getFontWidth(font, Font.ITALIC)) width = 0;
        if (width != 0 && width != getFontWidth(font, Font.BOLD | Font.ITALIC)) width = 0;
    }
    boolean isMonospaced = width > 0;