のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

loadFontInfo

    676 static void loadFontInfoLocked() {
    677     resetFallbackFontListsLocked();
    678 
    679     SkTDArray<FontFamily*> fontFamilies;
    680     getFontFamilies(fontFamilies);
    681 
    682     gSystemFonts.reset();
    683 
    684     for (int i = 0; i < fontFamilies.count(); ++i) {
    685         FontFamily *family = fontFamilies[i];
    686         for (int j = 0; j < family->fFontFileArray.count(); ++j) {
    687             const char* filename = family->fFontFileArray[j]->fFileName;
    688             if (haveSystemFont(filename)) {
    689                 SkDebugf("---- system font and fallback font files specify a duplicate "
    690                         "font %s, skipping the second occurrence", filename);
    691                 continue;
    692             }
    693 
    694             FontInitRec fontInfoRecord;
    695             fontInfoRecord.fFileName = filename;
    696             fontInfoRecord.fVariant = family->fFontFileArray[j]->fVariant;
    697             fontInfoRecord.fLanguage = family->fFontFileArray[j]->fLanguage;
    698             if (j == 0) {
    699                 if (family->fNames.count() == 0) {
    700                     // Fallback font
    701                     fontInfoRecord.fNames = (char **)gFBNames;
    702                 } else {
    703                     SkTDArray<const char*> names = family->fNames;
    704                     const char **nameList = (const char**)
    705                             malloc((names.count() + 1) * sizeof(char*));
    706                     if (nameList == NULL) {
    707                         // shouldn't get here
    708                         break;
    709                     }
    710                     if (gDefaultNames == NULL) {
    711                         gDefaultNames = (char**) nameList;
    712                     }
    713                     for (int i = 0; i < names.count(); ++i) {
    714                         nameList[i] = names[i];
    715                     }
    716                     nameList[names.count()] = NULL;
    717                     fontInfoRecord.fNames = nameList;
    718                 }
    719             } else {
    720                 fontInfoRecord.fNames = NULL;
    721             }
    722             gSystemFonts.push_back(fontInfoRecord);
    723         }
    724     }
    725     fontFamilies.deleteAll();
    726 
    727     SkDEBUGF(("---- We have %d system fonts", gSystemFonts.count()));
    728     for (int i = 0; i < gSystemFonts.count(); ++i) {
    729         SkDEBUGF(("---- gSystemFonts[%d] fileName=%s", i, gSystemFonts[i].fFileName));
    730     }
    731 }
     26 struct FontFileInfo {
     27     FontFileInfo() : fFileName(NULL), fVariant(SkPaint::kDefault_Variant),
     28             fLanguage() {
     29     }
     30 
     31     const char*          fFileName;
     32     SkPaint::FontVariant fVariant;
     33     SkLanguage           fLanguage;
     34 };
     36 /**
     37  * The FontFamily data structure is created during parsing 
         * and handed back to Skia to fold into its representation of font families. 
         * fNames is the list of font names that alias to a font family.
         * fontFileArray is the list of information about each file. 
         * Order is the priority order for the font.
         * This is used internally to determine the order 
         * in which to place fallback fonts as
     42  * they are read from the configuration files.
     43  */
     44 struct FontFamily {
     45     SkTDArray<const char*>   fNames;
     46     SkTDArray<FontFileInfo*> fFontFileArray;
     47     int order;
     48 };></blockquote><
    231 /**
    232  * Loads data on font families from various expected configuration files. The
    233  * resulting data is returned in the given fontFamilies array.
    234  */
    235 void getFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
    236     SkTDArray<FontFamily*> fallbackFonts;
    237 
    238     getSystemFontFamilies(fontFamilies);
    239     getFallbackFontFamilies(fallbackFonts);
    240 
    241     // Append all fallback fonts to system fonts
    242     for (int i = 0; i < fallbackFonts.count(); ++i) {
    243         *fontFamilies.append() = fallbackFonts[i];
    244     }
    245 }
    198 void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
    199     parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies);
    200 }

    174 void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &families) {
    175     XML_Parser parser = XML_ParserCreate(NULL);
    176     FamilyData *familyData = new FamilyData(&parser, families);
    177     XML_SetUserData(parser, familyData);
    178     XML_SetElementHandler(parser, startElementHandler, endElementHandler);
    179     FILE *file = fopen(filename, "r");
    180     // Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml)
    181     // are optional - failure here is okay because one of these optional files may not exist.
    182     if (file == NULL) {
    183         return;
    184     }
    185     char buffer[512];
    186     bool done = false;
    187     while (!done) {
    188         fgets(buffer, sizeof(buffer), file);
    189         int len = strlen(buffer);
    190         if (feof(file) != 0) {
    191             done = true;
    192         }
    193         XML_Parse(parser, buffer, len, done);
    194     }
    195     fclose(file);
    196 }
    202 void getFallbackFontFamilies(SkTDArray<FontFamily*> &fallbackFonts) {
    203     SkTDArray<FontFamily*> vendorFonts;
    204     parseConfigFile(FALLBACK_FONTS_FILE, fallbackFonts);
    205     parseConfigFile(VENDOR_FONTS_FILE, vendorFonts);
    206 
    207     // This loop inserts the vendor fallback fonts in the correct order in the
    208     // overall fallbacks list.
    209     int currentOrder = -1;
    210     for (int i = 0; i < vendorFonts.count(); ++i) {
    211         FontFamily* family = vendorFonts[i];
    212         int order = family->order;
    213         if (order < 0) {
    214             if (currentOrder < 0) {
    215                 // Default case - just add it to the end of the fallback list
    216                 *fallbackFonts.append() = family;
    217             } else {
    218                 // no order specified on this font, but we're incrementing the order
    219                 // based on an earlier order insertion request
    220                 *fallbackFonts.insert(currentOrder++) = family;
    221             }
    222         } else {
    223             // Add the font into the fallback list in the specified order. Set
    224             // currentOrder for correct placement of other fonts in the vendor list.
    225             *fallbackFonts.insert(order) = family;
    226             currentOrder = order + 1;
    227         }
    228     }
    229 }
     38 /**
     39  * The FamilyData structure is passed around by the parser so that each handler
     40  * can read these variables that are relevant to the current parsing.
     41  */
     42 struct FamilyData {
     43     FamilyData(XML_Parser *parserRef, SkTDArray<FontFamily*> &familiesRef) :
     44             parser(parserRef), families(familiesRef), currentTag(NO_TAG) {};
     45 
     46     XML_Parser *parser;                // The expat parser doing the work
     47     SkTDArray<FontFamily*> &families;  // The array that each family is put into as it is parsed
     48     FontFamily *currentFamily;         // The current family being created
     49     FontFileInfo *currentFontInfo;     // The current fontInfo being created
     50     int currentTag;                    // A flag to indicate whether we're in nameset/fileset tags
     51 };