Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}