static void load_directory_fonts(const SkString& directory, unsigned int* count) { SkOSFile::Iter iter(directory.c_str(), ".ttf"); SkString name; while (iter.next(&name, false)) { SkString filename(directory); filename.append(name); bool isFixedWidth; SkString realname; SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedWidth)) { SkDebugf("------ can't load <%s> as a font\n", filename.c_str()); continue; } FamilyRec* family = find_familyrec(realname.c_str()); if (family && family->fFaces[style]) { continue; } // this constructor puts us into the global gFamilyHead llist FamilyTypeface* tf = SkNEW_ARGS(FileTypeface, (style, true, // system-font (cannot delete) family, // what family to join filename.c_str(), isFixedWidth) // filename ); if (NULL == family) { add_name(realname.c_str(), tf->getFamily()); } *count += 1; } SkOSFile::Iter dirIter(directory.c_str()); while (dirIter.next(&name, true)) { if (name.startsWith(".")) { continue; } SkString dirname(directory); dirname.append(name); dirname.append(SK_FONT_FILE_DIR_SEPERATOR); load_directory_fonts(dirname, count); } }
static void reload_fallback_fonts() { if (gTestFallbackConfigFile) { // No need to reload fallback fonts in test environment. return; } SkGraphics::PurgeFontCache(); SkTDArray<FontFamily*> fallbackFamilies; getFallbackFontFamilies(fallbackFamilies); int fallbackCount = 0; for (int i = 0; i < fallbackFamilies.count(); ++i) { FontFamily *family = fallbackFamilies[i]; for (int j = 0; j < family->fFileNames.count(); ++j) { if (family->fFileNames[j]) { // ensure the fallback font exists before adding it to the list bool isFixedWidth; SkString name; SkTypeface::Style style; if (!get_name_and_style(family->fFileNames[j], &name, &style, &isFixedWidth, false)) { continue; } size_t uniqueID = find_uniqueID(family->fFileNames[j]); SkASSERT(uniqueID != 0); #if SK_DEBUG_FONTS SkDebugf("---- reload %s as fallback[%d] fontID %d oldFontID %d", family->fFileNames[j], fallbackCount, uniqueID, gFallbackFonts[fallbackCount]); #endif gFallbackFonts[fallbackCount++] = uniqueID; break; // The fallback set contains only the first font of each family } } } // reset the sentinel the end of the newly ordered array gFallbackFonts[fallbackCount] = 0; }
/* Called once (ensured by the sentinel check at the beginning of our body). Initializes all the globals, and register the system fonts. */ static void load_system_fonts() { // check if we've already be called if (NULL != gDefaultNormal) { return; } const FontInitRec* rec = gSystemFonts; SkTypeface* firstInFamily = NULL; int fallbackCount = 0; for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { // if we're the first in a new family, clear firstInFamily if (rec[i].fNames != NULL) { firstInFamily = NULL; } SkString name; SkTypeface::Style style; // we expect all the fonts, except the "fallback" fonts bool isExpected = (rec[i].fNames != gFBNames); if (!get_name_and_style(rec[i].fFileName, &name, &style, isExpected)) { continue; } SkTypeface* tf = SkNEW_ARGS(FileTypeface, (style, true, // system-font (cannot delete) firstInFamily, // what family to join rec[i].fFileName) // filename ); if (rec[i].fNames != NULL) { // see if this is one of our fallback fonts if (rec[i].fNames == gFBNames) { // SkDebugf("---- adding %s as fallback[%d] fontID %d\n", // rec[i].fFileName, fallbackCount, tf->uniqueID()); gFallbackFonts[fallbackCount++] = tf->uniqueID(); } firstInFamily = tf; FamilyRec* family = find_family(tf); const char* const* names = rec[i].fNames; // record the default family if this is it if (names == DEFAULT_NAMES) { gDefaultFamily = family; } // add the names to map to this family while (*names) { add_name(*names, family); names += 1; } } } // do this after all fonts are loaded. This is our default font, and it // acts as a sentinel so we only execute load_system_fonts() once gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal); // now terminate our fallback list with the sentinel value gFallbackFonts[fallbackCount] = 0; }
static void load_system_fonts() { // check if we've already be called if (NULL != gDefaultNormal) { // printf("---- default font %p\n", gDefaultNormal); return; } SkOSFile::Iter iter(SK_FONT_FILE_PREFIX, ".ttf"); SkString name; int count = 0; while (iter.next(&name, false)) { SkString filename; GetFullPathForSysFonts(&filename, name.c_str()); bool isFixedWidth; SkString realname; SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedWidth)) { SkDebugf("------ can't load <%s> as a font\n", filename.c_str()); continue; } // SkDebugf("font: <%s> %d <%s>\n", realname.c_str(), style, filename.c_str()); FamilyRec* family = find_familyrec(realname.c_str()); if (family && family->fFaces[style]) { // SkDebugf("---- skipping duplicate typeface %s style %d\n", // realname.c_str(), style); continue; } // this constructor puts us into the global gFamilyHead llist FamilyTypeface* tf = SkNEW_ARGS(FileTypeface, (style, true, // system-font (cannot delete) family, // what family to join filename.c_str(), isFixedWidth) // filename ); if (NULL == family) { add_name(realname.c_str(), tf->getFamily()); } count += 1; } if (0 == count) { SkNEW(EmptyTypeface); } // do this after all fonts are loaded. This is our default font, and it // acts as a sentinel so we only execute load_system_fonts() once static const char* gDefaultNames[] = { "Arial", "Verdana", "Times New Roman", NULL }; const char** names = gDefaultNames; while (*names) { SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal); if (tf) { gDefaultNormal = tf; break; } } // check if we found *something* if (NULL == gDefaultNormal) { if (NULL == gFamilyHead) { sk_throw(); } for (int i = 0; i < 4; i++) { if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) { break; } } } if (NULL == gDefaultNormal) { sk_throw(); } gFallBackTypeface = gDefaultNormal; gDefaultFamily = find_family(gDefaultNormal); // SkDebugf("---- default %p head %p family %p\n", gDefaultNormal, gFamilyHead, gDefaultFamily); }
/* * Called once (ensured by the sentinel check at the beginning of our body). * Initializes all the globals, and register the system fonts. * * gFamilyHeadAndNameListMutex must already be acquired. */ static void init_system_fonts() { // check if we've already been called if (gDefaultNormal) { return; } SkASSERT(gUniqueFontID == 0); load_font_info(); FontInitRec* rec = gSystemFonts; SkTypeface* firstInFamily = NULL; int fallbackCount = 0; for (size_t i = 0; i < gNumSystemFonts; i++) { // if we're the first in a new family, clear firstInFamily if (rec[i].fNames != NULL) { firstInFamily = NULL; } bool isFixedWidth; SkString name; SkTypeface::Style style; // we expect all the fonts, except the "fallback" fonts bool isExpected = (rec[i].fNames != gFBNames); if (!get_name_and_style(rec[i].fFileName, &name, &style, &isFixedWidth, isExpected)) { // We need to increase gUniqueFontID here so that the unique id of // each font matches its index in gSystemFonts array, as expected // by find_uniqueID. sk_atomic_inc(&gUniqueFontID); continue; } SkTypeface* tf = SkNEW_ARGS(FileTypeface, (style, true, // system-font (cannot delete) firstInFamily, // what family to join rec[i].fFileName, isFixedWidth) // filename ); #if SK_DEBUG_FONTS SkDebugf("---- SkTypeface[%d] %s fontID %d", i, rec[i].fFileName, tf->uniqueID()); #endif if (rec[i].fNames != NULL) { // see if this is one of our fallback fonts if (rec[i].fNames == gFBNames) { #if SK_DEBUG_FONTS SkDebugf("---- adding %s as fallback[%d] fontID %d", rec[i].fFileName, fallbackCount, tf->uniqueID()); #endif gFallbackFonts[fallbackCount++] = tf->uniqueID(); // Use the font file name as the name of the typeface. const char **nameList = (const char**)malloc(2 * sizeof(char*)); if (nameList == NULL) { // shouldn't get here SkDEBUGFAIL("Failed to allocate nameList"); break; } nameList[0] = rec[i].fFileName; nameList[1] = NULL; rec[i].fNames = nameList; } firstInFamily = tf; FamilyRec* family = find_family(tf); const char* const* names = rec[i].fNames; // record the default family if this is it if (names == gDefaultNames) { gDefaultFamily = family; } // add the names to map to this family while (*names) { add_name(*names, family); names += 1; } } } // do this after all fonts are loaded. This is our default font, and it // acts as a sentinel so we only execute load_system_fonts() once gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal); // now terminate our fallback list with the sentinel value gFallbackFonts[fallbackCount] = 0; // SkDEBUGCODE(dump_globals()); }