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 }