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. #if PLATFORM(CG) bool canCreateCGFontWithLOGFONT = wkCanCreateCGFontWithLOGFONT(); #else bool canCreateCGFontWithLOGFONT = true; #endif LONG weight = adjustedGDIFontWeight(toGDIFontWeight(fontDescription.weight()), family); HFONT hfont = createGDIFont(family, weight, fontDescription.italic(), fontDescription.computedPixelSize() * (useGDI ? 1 : 32), useGDI && canCreateCGFontWithLOGFONT); 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; }
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { LOGFONT winfont; // The size here looks unusual. The negative number is intentional. The logical size constant is 32. winfont.lfHeight = -fontDescription.computedPixelSize() * 32; winfont.lfWidth = 0; winfont.lfEscapement = 0; winfont.lfOrientation = 0; winfont.lfUnderline = false; winfont.lfStrikeOut = false; winfont.lfCharSet = DEFAULT_CHARSET; #if PLATFORM(CG) winfont.lfOutPrecision = OUT_TT_ONLY_PRECIS; #else winfont.lfOutPrecision = OUT_TT_PRECIS; #endif winfont.lfQuality = 5; // Force cleartype. winfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; winfont.lfItalic = fontDescription.italic(); // FIXME: Support weights for real. Do our own enumeration of the available weights. // We can't rely on Windows here, since we need to follow the CSS2 algorithm for how to fill in // gaps in the weight list. // FIXME: Hardcoding Lucida Grande for now. It uses different weights than typical Win32 fonts // (500/600 instead of 400/700). static AtomicString lucidaStr("Lucida Grande"); if (equalIgnoringCase(family, lucidaStr)) winfont.lfWeight = fontDescription.bold() ? 600 : 500; else winfont.lfWeight = fontDescription.bold() ? 700 : 400; int len = min(family.length(), (unsigned int)LF_FACESIZE - 1); memcpy(winfont.lfFaceName, family.characters(), len * sizeof(WORD)); winfont.lfFaceName[len] = '\0'; HFONT hfont = CreateFontIndirect(&winfont); // Windows will always give us a valid pointer here, even if the face name is non-existent. We have to double-check // and see if the family name was really used. HDC dc = GetDC((HWND)0); SaveDC(dc); SelectObject(dc, hfont); WCHAR name[LF_FACESIZE]; GetTextFace(dc, LF_FACESIZE, name); RestoreDC(dc, -1); ReleaseDC(0, dc); if (_wcsicmp(winfont.lfFaceName, name)) { DeleteObject(hfont); return 0; } FontPlatformData* result = new FontPlatformData(hfont, fontDescription.computedPixelSize(), fontDescription.bold(), fontDescription.italic()); if (!result->cgFont()) { // 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; }