Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving available font sizes on Windows

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?

like image 217
Jon Bright Avatar asked Jun 16 '09 19:06

Jon Bright


1 Answers

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;
    }
}
like image 130
ASk Avatar answered Oct 16 '22 04:10

ASk