diff options
Diffstat (limited to 'WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp')
-rw-r--r-- | WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp | 183 |
1 files changed, 114 insertions, 69 deletions
diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp index 347a3fb..2c79815 100644 --- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp +++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp @@ -50,11 +50,6 @@ using std::min; namespace WebCore { -void FontCache::platformInit() -{ - // Not needed on Windows. -} - // FIXME: consider adding to WebKit String class static bool charactersAreAllASCII(const String& s) { @@ -329,6 +324,86 @@ static bool fontContainsCharacter(const FontPlatformData* fontData, return cmap->contains(character); } +// Tries the given font and save it |outFontFamilyName| if it succeeds. +static SimpleFontData* fontDataFromDescriptionAndLogFont(FontCache* fontCache, const FontDescription& fontDescription, const LOGFONT& font, wchar_t* outFontFamilyName) +{ + SimpleFontData* fontData = fontCache->getCachedFontData(fontDescription, font.lfFaceName); + if (fontData) + memcpy(outFontFamilyName, font.lfFaceName, sizeof(font.lfFaceName)); + return fontData; +} + +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 void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont) +{ + // The size here looks unusual. The negative number is intentional. + // Unlike WebKit trunk, we don't multiply the size by 32. That seems to be + // some kind of artifact of their CG backend, or something. + winfont->lfHeight = -fontDescription.computedPixelSize(); + winfont->lfWidth = 0; + winfont->lfEscapement = 0; + winfont->lfOrientation = 0; + winfont->lfUnderline = false; + winfont->lfStrikeOut = false; + winfont->lfCharSet = DEFAULT_CHARSET; + winfont->lfOutPrecision = OUT_TT_ONLY_PRECIS; + winfont->lfQuality = ChromiumBridge::layoutTestMode() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY; // Honor user's desktop settings. + winfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; + winfont->lfItalic = fontDescription.italic(); + winfont->lfWeight = toGDIFontWeight(fontDescription.weight()); +} + +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 = logFont->lfWeight; + 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::platformInit() +{ + // Not needed on Windows. +} + // Given the desired base font, this will create a SimpleFontData for a specific // font that can be used to render the given range of characters. const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) @@ -438,73 +513,43 @@ SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& desc else if (generic == FontDescription::MonospaceFamily) fontStr = courierStr; - return getCachedFontData(description, fontStr); -} - -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 void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont) -{ - // The size here looks unusual. The negative number is intentional. - // Unlike WebKit trunk, we don't multiply the size by 32. That seems to be - // some kind of artifact of their CG backend, or something. - winfont->lfHeight = -fontDescription.computedPixelSize(); - winfont->lfWidth = 0; - winfont->lfEscapement = 0; - winfont->lfOrientation = 0; - winfont->lfUnderline = false; - winfont->lfStrikeOut = false; - winfont->lfCharSet = DEFAULT_CHARSET; - winfont->lfOutPrecision = OUT_TT_ONLY_PRECIS; - winfont->lfQuality = ChromiumBridge::layoutTestMode() ? NONANTIALIASED_QUALITY : DEFAULT_QUALITY; // Honor user's desktop settings. - winfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; - winfont->lfItalic = fontDescription.italic(); - winfont->lfWeight = toGDIFontWeight(fontDescription.weight()); -} - -struct TraitsInFamilyProcData { - TraitsInFamilyProcData(const AtomicString& familyName) - : m_familyName(familyName) - { + SimpleFontData* simpleFont = getCachedFontData(description, fontStr); + if (simpleFont) + return simpleFont; + + // Fall back to system fonts as Win Safari does because this function must + // return a valid font. Once we find a valid system font, we save its name + // to a static variable and use it to prevent trying system fonts again. + static wchar_t fallbackFontName[LF_FACESIZE] = {0}; + if (fallbackFontName[0]) + return getCachedFontData(description, fallbackFontName); + + // Fall back to the DEFAULT_GUI_FONT if no known Unicode fonts are available. + if (HFONT defaultGUIFont = static_cast<HFONT>(GetStockObject(DEFAULT_GUI_FONT))) { + LOGFONT defaultGUILogFont; + GetObject(defaultGUIFont, sizeof(defaultGUILogFont), &defaultGUILogFont); + if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, defaultGUILogFont, fallbackFontName)) + return simpleFont; } - 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); + // Fall back to Non-client metrics fonts. + NONCLIENTMETRICS nonClientMetrics = {0}; + nonClientMetrics.cbSize = sizeof(nonClientMetrics); + if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(nonClientMetrics), &nonClientMetrics, 0)) { + if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfMessageFont, fallbackFontName)) + return simpleFont; + if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfMenuFont, fallbackFontName)) + return simpleFont; + if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfStatusFont, fallbackFontName)) + return simpleFont; + if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfCaptionFont, fallbackFontName)) + return simpleFont; + if (simpleFont = fontDataFromDescriptionAndLogFont(this, description, nonClientMetrics.lfSmCaptionFont, fallbackFontName)) + return simpleFont; + } - unsigned traitsMask = 0; - traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask; - traitsMask |= FontVariantNormalMask; - LONG weight = logFont->lfWeight; - 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; + ASSERT_NOT_REACHED(); + return 0; } void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) |