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; }
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; }