int FindCreateFont()

in src/propsheet/fontdlg.cpp [1123:1361]


int FindCreateFont(
    __in DWORD Family,
    __in_ecount(LF_FACESIZE) LPWSTR pwszFace,
    __in COORD Size,
    __in LONG Weight,
    __in UINT CodePage)
{
#define NOT_CREATED_NOR_FOUND -1
#define CREATED_BUT_NOT_FOUND -2

    int FontIndex = NOT_CREATED_NOR_FOUND;
    BOOL bFontOK;
    WCHAR AltFaceName[LF_FACESIZE];
    COORD AltFontSize;
    BYTE AltFontFamily;
    ULONG AltFontIndex = 0, i;
    LPWSTR pwszAltFace;

    BYTE CharSet = CodePageToCharSet(CodePage);

    FAIL_FAST_IF(!(OEMCP != 0));

    DBGFONTS(("FindCreateFont Family=%x %ls (%d,%d) %d %d %x\n",
              Family,
              pwszFace,
              Size.X,
              Size.Y,
              Weight,
              CodePage,
              CharSet));

    if (g_fEastAsianSystem)
    {
        if (IS_DBCS_OR_OEM_CHARSET(CharSet))
        {
            if (pwszFace == nullptr || *pwszFace == TEXT('\0'))
            {
                pwszFace = DefaultFaceName;
            }
            if (Size.Y == 0)
            {
                Size = DefaultFontSize;
            }
        }
        else
        {
            MakeAltRasterFont(CodePage, &AltFontSize, &AltFontFamily, &AltFontIndex, AltFaceName);

            if (pwszFace == nullptr || *pwszFace == TEXT('\0'))
            {
                pwszFace = AltFaceName;
            }
            if (Size.Y == 0)
            {
                Size.X = AltFontSize.X;
                Size.Y = AltFontSize.Y;
            }
        }
    }
    else
    {
        if (pwszFace == nullptr || *pwszFace == TEXT('\0'))
        {
            pwszFace = DefaultFaceName;
        }
        if (Size.Y == 0)
        {
            Size = DefaultFontSize;
        }
    }

    // If _DefaultTTFont_ is specified, find the appropriate face name for our current codepage.
    if (wcscmp(pwszFace, DEFAULT_TT_FONT_FACENAME) == 0)
    {
        // retrieve default font face name for this codepage, and then set it as our current face
        WCHAR szDefaultCodepageTTFont[LF_FACESIZE] = { 0 };
        if (NT_SUCCESS(GetTTFontFaceForCodePage(CodePage, szDefaultCodepageTTFont, ARRAYSIZE(szDefaultCodepageTTFont))) &&
            NT_SUCCESS(StringCchCopyW(DefaultTTFaceName, ARRAYSIZE(DefaultTTFaceName), szDefaultCodepageTTFont)))
        {
            pwszFace = DefaultTTFaceName;
            Size.X = 0;
        }
    }

    if (ShouldAllowAllMonoTTFonts() || IsAvailableTTFont(pwszFace))
    {
        pwszAltFace = GetAltFaceName(pwszFace);
    }
    else
    {
        pwszAltFace = pwszFace;
    }

    /*
     * Try to find the exact font
     */
TryFindExactFont:
    for (i = 0; i < NumberOfFonts; i++)
    {
        /*
         * If looking for a particular Family, skip non-matches
         */
        if (Family != 0 && (BYTE)Family != FontInfo[i].Family)
        {
            continue;
        }

        /*
         * Skip non-matching sizes
         */
        if ((FontInfo[i].SizeWant.Y != Size.Y) &&
            !SIZE_EQUAL(FontInfo[i].Size, Size))
        {
            continue;
        }

        /*
         * Skip non-matching weights
         */
        if ((Weight != 0) && (Weight != FontInfo[i].Weight))
        {
            continue;
        }

        if (!TM_IS_TT_FONT(FontInfo[i].Family) &&
            (FontInfo[i].tmCharSet != CharSet &&
             !(FontInfo[i].tmCharSet == OEM_CHARSET && g_fEastAsianSystem)))
        {
            continue;
        }

        /*
         * Size (and maybe Family) match. If we don't care about the name or
         * if it matches, use this font. Otherwise, if name doesn't match and
         * it is a raster font, consider it.
         */
        if ((pwszFace == nullptr) || (pwszFace[0] == TEXT('\0')) ||
            (lstrcmp(FontInfo[i].FaceName, pwszFace) == 0) ||
            (lstrcmp(FontInfo[i].FaceName, pwszAltFace) == 0))
        {
            FontIndex = i;
            goto FoundFont;
        }
        else if (!TM_IS_TT_FONT(FontInfo[i].Family))
        {
            FontIndex = i;
        }
    }

    if (FontIndex == NOT_CREATED_NOR_FOUND)
    {
        /*
         * Didn't find the exact font, so try to create it
         */
        if (Size.Y < 0)
        {
            Size.Y = -Size.Y;
        }
        bFontOK = DoFontEnum(nullptr, pwszFace, &Size.Y, 1);
        if (bFontOK)
        {
            DBGFONTS(("FindCreateFont created font!\n"));
            FontIndex = CREATED_BUT_NOT_FOUND;
            goto TryFindExactFont;
        }
        else
        {
            DBGFONTS(("FindCreateFont failed to create font!\n"));
        }
    }
    else if (FontIndex >= 0)
    {
        // a close Raster Font fit - only the name doesn't match.
        goto FoundFont;
    }

    /*
     * Failed to find exact match, even after enumeration, so now try to find
     * a font of same family and same size or bigger.
     */
    for (i = 0; i < NumberOfFonts; i++)
    {
        if (g_fEastAsianSystem)
        {
            if (Family != 0 && (BYTE)Family != FontInfo[i].Family)
            {
                continue;
            }

            if (!TM_IS_TT_FONT(FontInfo[i].Family) &&
                FontInfo[i].tmCharSet != CharSet)
            {
                continue;
            }
        }
        else
        {
            if ((BYTE)Family != FontInfo[i].Family)
            {
                continue;
            }
        }

        if (FontInfo[i].Size.Y >= Size.Y && FontInfo[i].Size.X >= Size.X)
        {
            // Same family, size >= desired.
            FontIndex = i;
            break;
        }
    }

    if (FontIndex < 0)
    {
        DBGFONTS(("FindCreateFont defaults!\n"));
        if (g_fEastAsianSystem)
        {
            if (CodePage == OEMCP)
            {
                FontIndex = DefaultFontIndex;
            }
            else
            {
                FontIndex = AltFontIndex;
            }
        }
        else
        {
            FontIndex = DefaultFontIndex;
        }
    }

FoundFont:
    FAIL_FAST_IF(!(FontIndex < (int)NumberOfFonts));
    DBGFONTS(("FindCreateFont returns %x : %ls (%d,%d)\n", FontIndex, FontInfo[FontIndex].FaceName, FontInfo[FontIndex].Size.X, FontInfo[FontIndex].Size.Y));
    return FontIndex;

#undef NOT_CREATED_NOR_FOUND
#undef CREATED_BUT_NOT_FOUND
}