Retrieving available font sizes on Windows

Go To StackoverFlow.com

5

When I open the Windows Common Font Dialog, it lists, for each font, a bunch of sizes. For all of the OpenType/TrueType fonts, it has the same list - 9, 10, 11, 12, 14, 16, 18... For bitmap fonts, the list varies according to the available bitmaps. "Small fonts" has 2,3,4,5,6,7, while plain old Courier has 10, 12, 15. I don't know, but I'm lead from previous reading to believe that even for TrueType fonts, certain sizes will be hinted and will look nicer than all those other sizes, so presumably I could also see a TrueType font with a more restricted set of sizes.

I'm implementing a feature in my application whereby Ctrl+Mousewheel will scale the font size up and down, as it does in browsers. I'd like to determine the available list of sizes for a font so that if I'm currently at size 12, my application knows that for Courier New, the next appropriate larger size is 14, while for plain old Courier, it's 15.

How do I go about doing this?

2009-06-16 19:16
by Jon Bright
What language are you doing this in - Psycho_Penguin 2009-06-16 19:19
I'm going directly against the Win32 API, so the question's language-agnostic. But I'm using C++ - Jon Bright 2009-06-16 19:24


5

See here for an explanation on how to enumerate fonts / font sizes for a specific font. Note, that TrueType fonts can be displayed at any size (and not just predetermined ones), since they are vector-based.

int EnumFontSizes(char *fontname)
{
    LOGFONT logfont;

    ZeroMemory(&logfont, sizeof logfont);

    logfont.lfHeight = 0;
    logfont.lfCharSet = DEFAULT_CHARSET;
    logfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;

    lstrcpy(logfont.lfFaceName, fontname);

    EnumFontFamiliesEx(hdc, &logfont, (FONTENUMPROC)FontSizesProc, 0, 0);

    return 0;
}

int CALLBACK FontSizesProc(
    LOGFONT *plf,      /* pointer to logical-font data */
    TEXTMETRIC *ptm,   /* pointer to physical-font data */
    DWORD FontType,    /* font type */
    LPARAM lParam      /* pointer to application-defined data */
    )
{
    static int truetypesize[] = { 8, 9, 10, 11, 12, 14, 16, 18, 20, 
            22, 24, 26, 28, 36, 48, 72 };

    int i;

    if(FontType != TRUETYPE_FONTTYPE)
    {
        int  logsize    = ptm->tmHeight - ptm->tmInternalLeading;
        long pointsize  = MulDiv(logsize, 72, GetDeviceCaps(hdc, LOGPIXELSY));

        for(i = 0; i < cursize; i++)
            if(currentsizes[i] == pointsize)
                return 1;

        printf("%d ", pointsize);

        currentsizes[cursize] = pointsize;

        if(++cursize == 200) return 0;
        return 1;   
    }
    else
    {

        for(i = 0; i < (sizeof(truetypesize) / sizeof(truetypesize[0])); i++)
        {
            printf("%d ", truetypesize[i]);
        }

        return 0;
    }
}
2009-06-16 19:26
by ASk
Thanks. I realise OpenType/TrueType will scale to any size, but they do often have particular sizes that have been manually hinted to look good - Jon Bright 2009-06-16 20:48
The webpage is down... Any alternative - raymai97 2018-02-23 15:39
Ads