のねのBlog

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

fontFileElementHandler

     83 /**
     84  * Handler for font files. This processes the attributes for language and
     85  * variants then lets textHandler handle the actual file name
     86  */
     87 void fontFileElementHandler(FamilyData *familyData, const char **attributes) {
     88     FontFileInfo* newFileInfo = new FontFileInfo();
     89     if (attributes) {
     90         int currentAttributeIndex = 0;
     91         while (attributes[currentAttributeIndex]) {
     92             const char* attributeName = attributes[currentAttributeIndex];
     93             const char* attributeValue = attributes[currentAttributeIndex+1];
     94             int nameLength = strlen(attributeName);
     95             int valueLength = strlen(attributeValue);
     96             if (strncmp(attributeName, "variant", nameLength) == 0) {
     97                 if (strncmp(attributeValue, "elegant", valueLength) == 0) {
     98                     newFileInfo->fVariant = SkPaint::kElegant_Variant;
     99                 } else if (strncmp(attributeValue, "compact", valueLength) == 0) {
    100                     newFileInfo->fVariant = SkPaint::kCompact_Variant;
    101                 }
    102             } else if (strncmp(attributeName, "lang", nameLength) == 0) {
    103                 newFileInfo->fLanguage = SkLanguage(attributeValue);
    104             }
    105             //each element is a pair of attributeName/attributeValue string pairs
    106             currentAttributeIndex += 2;
    107         }
    108     }
    109     *(familyData->currentFamily->fFontFileArray.append()) = newFileInfo;
    110     familyData->currentFontInfo = newFileInfo;
    111     XML_SetCharacterDataHandler(*familyData->parser, textHandler);
    112 }

    114 /**
    115  * Handler for the start of a tag. The only tags we expect are family, nameset,
    116  * fileset, name, and file.
    117  */
    118 void startElementHandler(void *data, const char *tag, const char **atts) {
    119     FamilyData *familyData = (FamilyData*) data;
    120     int len = strlen(tag);
    121     if (strncmp(tag, "family", len)== 0) {
    122         familyData->currentFamily = new FontFamily();
    123         familyData->currentFamily->order = -1;
    124         // The Family tag has an optional "order" attribute with an integer value >= 0
    125         // If this attribute does not exist, the default value is -1
    126         for (int i = 0; atts[i] != NULL; i += 2) {
    127             const char* attribute = atts[i];
    128             const char* valueString = atts[i+1];
    129             int value;
    130             int len = sscanf(valueString, "%d", &value);
    131             if (len > 0) {
    132                 familyData->currentFamily->order = value;
    133             }
    134         }
    135     } else if (len == 7 && strncmp(tag, "nameset", len) == 0) {
    136         familyData->currentTag = NAMESET_TAG;
    137     } else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
    138         familyData->currentTag = FILESET_TAG;
    139     } else if (strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) {
    140         // If it's a Name, parse the text inside
    141         XML_SetCharacterDataHandler(*familyData->parser, textHandler);
    142     } else if (strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG) {
    143         // If it's a file, parse the attributes, then parse the text inside
    144         fontFileElementHandler(familyData, atts); <==========================================
    145     }
    146 }
    170 /**
    171  * This function parses the given filename and stores the results in the given
    172  * families array.
    173  */
    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 }
    198 void getSystemFontFamilies(SkTDArray<FontFamily*> &fontFamilies) {
    199     parseConfigFile(SYSTEM_FONTS_FILE, fontFamilies); <=================
    200 }
    201 
    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 }