예제 #1
0
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
    const char* name = 0;
    CString nameString; // Keeps name valid within scope of this function in case that name is from a family.

    // If a fallback font is being created (e.g. "-webkit-monospace"), convert
    // it in to the fallback name (e.g. "monospace").
    if (!family.length() || family.startsWith("-webkit-"))
        name = getFallbackFontName(fontDescription);
    else {
        nameString = family.string().utf8();
        name = nameString.data();
    }

    int style = SkTypeface::kNormal;
    if (fontDescription.weight() >= FontWeightBold)
        style |= SkTypeface::kBold;
    if (fontDescription.italic())
        style |= SkTypeface::kItalic;

    SkTypeface* typeface = 0;
    FontPlatformData* result = 0;
    FallbackScripts fallbackScript = SkGetFallbackScriptFromID(name);
    if (SkTypeface_ValidScript(fallbackScript)) {
        typeface = SkCreateTypefaceForScript(fallbackScript);
        if (typeface)
            result = new FontPlatformData(typeface, name, fontDescription.computedSize(),
                                          (style & SkTypeface::kBold) && !typeface->isBold(),
                                          (style & SkTypeface::kItalic) && !typeface->isItalic(),
                                          fontDescription.orientation());
    } else {
        typeface = SkTypeface::CreateFromName(name, SkTypeface::kNormal);

        // CreateFromName always returns a typeface, falling back to a default font
        // if the one requested could not be found. Calling Equal() with a null
        // pointer will compare the returned font against the default, with the
        // caveat that the default is always of normal style. When that happens,
        // ignore the default font and allow WebCore to provide the next font on the
        // CSS fallback list. The only exception to this occurs when the family name
        // is a commonly used generic family, which is the case when called by
        // getSimilarFontPlatformData() or getLastResortFallbackFont(). In that case
        // the default font is an acceptable result.

        if (!SkTypeface::Equal(typeface, 0) || isFallbackFamily(family.string())) {
            // We had to use normal styling to see if this was a default font. If
            // we need bold or italic, replace with the corrected typeface.
            if (style != SkTypeface::kNormal) {
                typeface->unref();
                typeface = SkTypeface::CreateFromName(name, static_cast<SkTypeface::Style>(style));
            }
            result = new FontPlatformData(typeface, name, fontDescription.computedSize(),
                                          (style & SkTypeface::kBold) && !typeface->isBold(),
                                          (style & SkTypeface::kItalic) && !typeface->isItalic(),
                                          fontDescription.orientation());
        }
    }

    SkSafeUnref(typeface);
    return result;
}
예제 #2
0
SkTypeface* SkCreateTypefaceForScript(FallbackScripts script) {
    if (!SkTypeface_ValidScript(script)) {
        return NULL;
    }

    // ensure that our table is populated
    initFBScriptInfo();

    FBScriptInfo& scriptInfo = gFBScriptInfo[script];

    // ensure the element with that index actually maps to the correct script
    SkASSERT(scriptInfo.fScript == script);

    // if a suitable script could not be found then return NULL
    if (scriptInfo.fFontID == 0) {
        return NULL;
    }

    SkAutoMutexAcquire  ac(gFamilyHeadAndNameListMutex);

    // retrieve the typeface the corresponds to this fontID
    SkTypeface* tf = find_from_uniqueID(scriptInfo.fFontID);
    // we ref(), since the semantic is to return a new instance
    tf->ref();
    return tf;
}