⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fontcachewin.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            break;        LOGFONT logFont;        logFont.lfCharSet = DEFAULT_CHARSET;        memcpy(logFont.lfFaceName, linkedFonts->at(linkedFontIndex).characters(), linkedFonts->at(linkedFontIndex).length() * sizeof(WCHAR));        logFont.lfFaceName[linkedFonts->at(linkedFontIndex).length()] = 0;        EnumFontFamiliesEx(hdc, &logFont, linkedFontEnumProc, reinterpret_cast<LPARAM>(&hfont), 0);        linkedFontIndex++;    }    if (hfont) {        if (!familyName.isEmpty()) {            FontPlatformData* result = getCachedFontPlatformData(font.fontDescription(), familyName);            if (result)                fontData = getCachedFontData(result);        }        SelectObject(hdc, oldFont);        DeleteObject(hfont);    }    ReleaseDC(0, hdc);    return fontData;}FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font){    return 0;}FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription){    // FIXME: Would be even better to somehow get the user's default font here.  For now we'll pick    // the default that the user would get without changing any prefs.    static AtomicString timesStr("Times New Roman");    return getCachedFontPlatformData(fontDescription, timesStr);}static LONG toGDIFontWeight(FontWeight fontWeight){    static LONG gdiFontWeights[] = {        FW_THIN,        // FontWeight100        FW_EXTRALIGHT,  // FontWeight200        FW_LIGHT,       // FontWeight300        FW_NORMAL,      // FontWeight400        FW_MEDIUM,      // FontWeight500        FW_SEMIBOLD,    // FontWeight600        FW_BOLD,        // FontWeight700        FW_EXTRABOLD,   // FontWeight800        FW_HEAVY        // FontWeight900    };    return gdiFontWeights[fontWeight];}static inline bool isGDIFontWeightBold(LONG gdiFontWeight){    return gdiFontWeight >= FW_SEMIBOLD;}static LONG adjustedGDIFontWeight(LONG gdiFontWeight, const String& family){    static AtomicString lucidaStr("Lucida Grande");    if (equalIgnoringCase(family, lucidaStr)) {        if (gdiFontWeight == FW_NORMAL)            return FW_MEDIUM;        if (gdiFontWeight == FW_BOLD)            return FW_SEMIBOLD;    }    return gdiFontWeight;}struct MatchImprovingProcData {    MatchImprovingProcData(LONG desiredWeight, bool desiredItalic)        : m_desiredWeight(desiredWeight)        , m_desiredItalic(desiredItalic)        , m_hasMatched(false)    {    }    LONG m_desiredWeight;    bool m_desiredItalic;    bool m_hasMatched;    LOGFONT m_chosen;};static int CALLBACK matchImprovingEnumProc(CONST LOGFONT* candidate, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam){    MatchImprovingProcData* matchData = reinterpret_cast<MatchImprovingProcData*>(lParam);    if (!matchData->m_hasMatched) {        matchData->m_hasMatched = true;        matchData->m_chosen = *candidate;        return 1;    }    if (!candidate->lfItalic != !matchData->m_chosen.lfItalic) {        if (!candidate->lfItalic == !matchData->m_desiredItalic)            matchData->m_chosen = *candidate;        return 1;    }    unsigned chosenWeightDeltaMagnitude = abs(matchData->m_chosen.lfWeight - matchData->m_desiredWeight);    unsigned candidateWeightDeltaMagnitude = abs(candidate->lfWeight - matchData->m_desiredWeight);    // If both are the same distance from the desired weight, prefer the candidate if it is further from regular.    if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude && abs(candidate->lfWeight - FW_NORMAL) > abs(matchData->m_chosen.lfWeight - FW_NORMAL)) {        matchData->m_chosen = *candidate;        return 1;    }    // Otherwise, prefer the one closer to the desired weight.    if (candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude)        matchData->m_chosen = *candidate;    return 1;}static HFONT createGDIFont(const AtomicString& family, LONG desiredWeight, bool desiredItalic, int size){    HDC hdc = GetDC(0);    LOGFONT logFont;    logFont.lfCharSet = DEFAULT_CHARSET;    unsigned familyLength = min(family.length(), static_cast<unsigned>(LF_FACESIZE - 1));    memcpy(logFont.lfFaceName, family.characters(), familyLength * sizeof(UChar));    logFont.lfFaceName[familyLength] = 0;    logFont.lfPitchAndFamily = 0;    MatchImprovingProcData matchData(desiredWeight, desiredItalic);    EnumFontFamiliesEx(hdc, &logFont, matchImprovingEnumProc, reinterpret_cast<LPARAM>(&matchData), 0);    ReleaseDC(0, hdc);    if (!matchData.m_hasMatched)        return 0;    matchData.m_chosen.lfHeight = -size;    matchData.m_chosen.lfWidth = 0;    matchData.m_chosen.lfEscapement = 0;    matchData.m_chosen.lfOrientation = 0;    matchData.m_chosen.lfUnderline = false;    matchData.m_chosen.lfStrikeOut = false;    matchData.m_chosen.lfCharSet = DEFAULT_CHARSET;#if PLATFORM(CG) || PLATFORM(CAIRO)    matchData.m_chosen.lfOutPrecision = OUT_TT_ONLY_PRECIS;#else    matchData.m_chosen.lfOutPrecision = OUT_TT_PRECIS;#endif    matchData.m_chosen.lfQuality = DEFAULT_QUALITY;    matchData.m_chosen.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;    HFONT result = CreateFontIndirect(&matchData.m_chosen);    if (!result)        return 0;    HDC dc = GetDC(0);    SaveDC(dc);    SelectObject(dc, result);    WCHAR actualName[LF_FACESIZE];    GetTextFace(dc, LF_FACESIZE, actualName);    RestoreDC(dc, -1);    ReleaseDC(0, dc);    if (wcsicmp(matchData.m_chosen.lfFaceName, actualName)) {        DeleteObject(result);        result = 0;    }    return result;}struct TraitsInFamilyProcData {    TraitsInFamilyProcData(const AtomicString& familyName)        : m_familyName(familyName)    {    }    const AtomicString& m_familyName;    HashSet<unsigned> m_traitsMasks;};static int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam){    TraitsInFamilyProcData* procData = reinterpret_cast<TraitsInFamilyProcData*>(lParam);    unsigned traitsMask = 0;    traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask;    traitsMask |= FontVariantNormalMask;    LONG weight = adjustedGDIFontWeight(logFont->lfWeight, procData->m_familyName);    traitsMask |= weight == FW_THIN ? FontWeight100Mask :        weight == FW_EXTRALIGHT ? FontWeight200Mask :        weight == FW_LIGHT ? FontWeight300Mask :        weight == FW_NORMAL ? FontWeight400Mask :        weight == FW_MEDIUM ? FontWeight500Mask :        weight == FW_SEMIBOLD ? FontWeight600Mask :        weight == FW_BOLD ? FontWeight700Mask :        weight == FW_EXTRABOLD ? FontWeight800Mask :                                 FontWeight900Mask;    procData->m_traitsMasks.add(traitsMask);    return 1;}void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks){    HDC hdc = GetDC(0);    LOGFONT logFont;    logFont.lfCharSet = DEFAULT_CHARSET;    unsigned familyLength = min(familyName.length(), static_cast<unsigned>(LF_FACESIZE - 1));    memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UChar));    logFont.lfFaceName[familyLength] = 0;    logFont.lfPitchAndFamily = 0;    TraitsInFamilyProcData procData(familyName);    EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0);    copyToVector(procData.m_traitsMasks, traitsMasks);    ReleaseDC(0, hdc);}FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family){    bool isLucidaGrande = false;    static AtomicString lucidaStr("Lucida Grande");    if (equalIgnoringCase(family, lucidaStr))        isLucidaGrande = true;    bool useGDI = fontDescription.renderingMode() == AlternateRenderingMode && !isLucidaGrande;    // The logical size constant is 32. We do this for subpixel precision when rendering using Uniscribe.    // This masks rounding errors related to the HFONT metrics being  different from the CGFont metrics.    // FIXME: We will eventually want subpixel precision for GDI mode, but the scaled rendering doesn't    // look as nice. That may be solvable though.    LONG weight = adjustedGDIFontWeight(toGDIFontWeight(fontDescription.weight()), family);    HFONT hfont = createGDIFont(family, weight, fontDescription.italic(), fontDescription.computedPixelSize() * (useGDI ? 1 : 32));    if (!hfont)        return 0;    if (isLucidaGrande)        useGDI = false; // Never use GDI for Lucida Grande.    LOGFONT logFont;    GetObject(hfont, sizeof(LOGFONT), &logFont);    bool synthesizeBold = isGDIFontWeightBold(weight) && !isGDIFontWeightBold(logFont.lfWeight);    bool synthesizeItalic = fontDescription.italic() && !logFont.lfItalic;    FontPlatformData* result = new FontPlatformData(hfont, fontDescription.computedPixelSize(), synthesizeBold, synthesizeItalic, useGDI);#if PLATFORM(CG)    bool fontCreationFailed = !result->cgFont();#elif PLATFORM(CAIRO)    bool fontCreationFailed = !result->fontFace();#endif    if (fontCreationFailed) {        // The creation of the CGFontRef failed for some reason.  We already asserted in debug builds, but to make        // absolutely sure that we don't use this font, go ahead and return 0 so that we can fall back to the next        // font.        delete result;        DeleteObject(hfont);        return 0;    }            return result;}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -