OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The Android Open Source Project | 2 * Copyright 2011 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkFontConfigParser_android.h" | 8 #include "SkFontConfigParser_android.h" |
9 #include "SkTDArray.h" | 9 #include "SkTDArray.h" |
10 #include "SkTSearch.h" | 10 #include "SkTSearch.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 const char* value = attributes[i+1]; | 90 const char* value = attributes[i+1]; |
91 int nameLen = strlen(name); | 91 int nameLen = strlen(name); |
92 int valueLen = strlen(value); | 92 int valueLen = strlen(value); |
93 if (nameLen == 4 && !strncmp("name", name, nameLen)) { | 93 if (nameLen == 4 && !strncmp("name", name, nameLen)) { |
94 family->fNames.push_back().set(value); | 94 family->fNames.push_back().set(value); |
95 } else if (nameLen == 4 && !strncmp("lang", name, nameLen)) { | 95 } else if (nameLen == 4 && !strncmp("lang", name, nameLen)) { |
96 family->fLanguage = SkLanguage (value); | 96 family->fLanguage = SkLanguage (value); |
97 } else if (nameLen == 7 && !strncmp("variant", name, nameLen)) { | 97 } else if (nameLen == 7 && !strncmp("variant", name, nameLen)) { |
98 // Value should be either elegant or compact. | 98 // Value should be either elegant or compact. |
99 if (valueLen == 7 && !strncmp("elegant", value, valueLen)) { | 99 if (valueLen == 7 && !strncmp("elegant", value, valueLen)) { |
100 family->fVariant = SkPaintOptionsAndroid::kElegant_Variant; | 100 family->fVariant = kElegant_FontVariant; |
101 } else if (valueLen == 7 && !strncmp("compact", value, valueLen)) { | 101 } else if (valueLen == 7 && !strncmp("compact", value, valueLen)) { |
102 family->fVariant = SkPaintOptionsAndroid::kCompact_Variant; | 102 family->fVariant = kCompact_FontVariant; |
103 } | 103 } |
104 } | 104 } |
105 } | 105 } |
106 } | 106 } |
107 | 107 |
108 void fontFileNameHandler(void *data, const char *s, int len) { | 108 void fontFileNameHandler(void *data, const char *s, int len) { |
109 FamilyData *familyData = (FamilyData*) data; | 109 FamilyData *familyData = (FamilyData*) data; |
110 familyData->currentFontInfo->fFileName.set(s, len); | 110 familyData->currentFontInfo->fFileName.set(s, len); |
111 } | 111 } |
112 | 112 |
113 void familyElementEndHandler(FontFamily* family) { | |
114 for (int i = 0; i < family->fFontFiles.count(); i++) { | |
115 family->fFontFiles[i].fPaintOptions.setLanguage(family->fLanguage); | |
116 family->fFontFiles[i].fPaintOptions.setFontVariant(family->fVariant); | |
117 } | |
118 } | |
119 | |
120 void fontElementHandler(XML_Parser* parser, FontFileInfo* file, const char** att
ributes) { | 113 void fontElementHandler(XML_Parser* parser, FontFileInfo* file, const char** att
ributes) { |
121 // A <font> should have weight (integer) and style (normal, italic) attribut
es. | 114 // A <font> should have weight (integer) and style (normal, italic) attribut
es. |
122 // NOTE: we ignore the style. | 115 // NOTE: we ignore the style. |
123 // The element should contain a filename. | 116 // The element should contain a filename. |
124 for (int i = 0; attributes[i] != NULL; i += 2) { | 117 for (int i = 0; attributes[i] != NULL; i += 2) { |
125 const char* name = attributes[i]; | 118 const char* name = attributes[i]; |
126 const char* value = attributes[i+1]; | 119 const char* value = attributes[i+1]; |
127 int nameLen = strlen(name); | 120 int nameLen = strlen(name); |
128 if (nameLen == 6 && !strncmp("weight", name, nameLen)) { | 121 if (nameLen == 6 && !strncmp("weight", name, nameLen)) { |
129 parseNonNegativeInteger(value, &file->fWeight); | 122 parseNonNegativeInteger(value, &file->fWeight); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 aliasElementHandler(familyData, attributes); | 246 aliasElementHandler(familyData, attributes); |
254 } | 247 } |
255 } | 248 } |
256 | 249 |
257 void endElementHandler(void* data, const char* tag) { | 250 void endElementHandler(void* data, const char* tag) { |
258 FamilyData *familyData = (FamilyData*) data; | 251 FamilyData *familyData = (FamilyData*) data; |
259 int len = strlen(tag); | 252 int len = strlen(tag); |
260 if (len == 9 && strncmp(tag, "familyset", len) == 0) { | 253 if (len == 9 && strncmp(tag, "familyset", len) == 0) { |
261 familysetElementEndHandler(familyData); | 254 familysetElementEndHandler(familyData); |
262 } else if (len == 6 && strncmp(tag, "family", len) == 0) { | 255 } else if (len == 6 && strncmp(tag, "family", len) == 0) { |
263 familyElementEndHandler(familyData->currentFamily); | |
264 *familyData->families.append() = familyData->currentFamily; | 256 *familyData->families.append() = familyData->currentFamily; |
265 familyData->currentFamily = NULL; | 257 familyData->currentFamily = NULL; |
266 } else if (len == 4 && !strncmp(tag, "font", len)) { | 258 } else if (len == 4 && !strncmp(tag, "font", len)) { |
267 XML_SetCharacterDataHandler(*familyData->parser, NULL); | 259 XML_SetCharacterDataHandler(*familyData->parser, NULL); |
268 } | 260 } |
269 } | 261 } |
270 | 262 |
271 } // lmpParser | 263 } // lmpParser |
272 | 264 |
273 namespace jbParser { | 265 namespace jbParser { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 static void fontFileElementHandler(FamilyData *familyData, const char **attribut
es) { | 298 static void fontFileElementHandler(FamilyData *familyData, const char **attribut
es) { |
307 FontFileInfo& newFileInfo = familyData->currentFamily->fFontFiles.push_back(
); | 299 FontFileInfo& newFileInfo = familyData->currentFamily->fFontFiles.push_back(
); |
308 if (attributes) { | 300 if (attributes) { |
309 int currentAttributeIndex = 0; | 301 int currentAttributeIndex = 0; |
310 while (attributes[currentAttributeIndex]) { | 302 while (attributes[currentAttributeIndex]) { |
311 const char* attributeName = attributes[currentAttributeIndex]; | 303 const char* attributeName = attributes[currentAttributeIndex]; |
312 const char* attributeValue = attributes[currentAttributeIndex+1]; | 304 const char* attributeValue = attributes[currentAttributeIndex+1]; |
313 int nameLength = strlen(attributeName); | 305 int nameLength = strlen(attributeName); |
314 int valueLength = strlen(attributeValue); | 306 int valueLength = strlen(attributeValue); |
315 if (nameLength == 7 && strncmp(attributeName, "variant", nameLength)
== 0) { | 307 if (nameLength == 7 && strncmp(attributeName, "variant", nameLength)
== 0) { |
| 308 const FontVariant prevVariant = familyData->currentFamily->fVari
ant; |
316 if (valueLength == 7 && strncmp(attributeValue, "elegant", value
Length) == 0) { | 309 if (valueLength == 7 && strncmp(attributeValue, "elegant", value
Length) == 0) { |
317 newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndro
id::kElegant_Variant); | 310 familyData->currentFamily->fVariant = kElegant_FontVariant; |
318 } else if (valueLength == 7 && | 311 } else if (valueLength == 7 && |
319 strncmp(attributeValue, "compact", valueLength) == 0)
{ | 312 strncmp(attributeValue, "compact", valueLength) == 0)
{ |
320 newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndro
id::kCompact_Variant); | 313 familyData->currentFamily->fVariant = kCompact_FontVariant; |
321 } | 314 } |
| 315 if (familyData->currentFamily->fFontFiles.count() > 1 && |
| 316 familyData->currentFamily->fVariant != prevVariant) { |
| 317 SkDebugf("Every font file within a family must have identica
l variants"); |
| 318 sk_throw(); |
| 319 } |
| 320 |
322 } else if (nameLength == 4 && strncmp(attributeName, "lang", nameLen
gth) == 0) { | 321 } else if (nameLength == 4 && strncmp(attributeName, "lang", nameLen
gth) == 0) { |
323 newFileInfo.fPaintOptions.setLanguage(attributeValue); | 322 SkLanguage prevLang = familyData->currentFamily->fLanguage; |
| 323 familyData->currentFamily->fLanguage = SkLanguage(attributeValue
); |
| 324 if (familyData->currentFamily->fFontFiles.count() > 1 && |
| 325 familyData->currentFamily->fLanguage != prevLang) { |
| 326 SkDebugf("Every font file within a family must have identica
l languages"); |
| 327 sk_throw(); |
| 328 } |
324 } else if (nameLength == 5 && strncmp(attributeName, "index", nameLe
ngth) == 0) { | 329 } else if (nameLength == 5 && strncmp(attributeName, "index", nameLe
ngth) == 0) { |
325 int value; | 330 int value; |
326 if (parseNonNegativeInteger(attributeValue, &value)) { | 331 if (parseNonNegativeInteger(attributeValue, &value)) { |
327 newFileInfo.fIndex = value; | 332 newFileInfo.fIndex = value; |
328 } else { | 333 } else { |
329 SkDebugf("---- SystemFonts index=%s (INVALID)", attributeVal
ue); | 334 SkDebugf("---- SystemFonts index=%s (INVALID)", attributeVal
ue); |
330 } | 335 } |
331 } | 336 } |
332 //each element is a pair of attributeName/attributeValue string pair
s | 337 //each element is a pair of attributeName/attributeValue string pair
s |
333 currentAttributeIndex += 2; | 338 currentAttributeIndex += 2; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 fileName.size() - fixedLen); | 487 fileName.size() - fixedLen); |
483 | 488 |
484 SkString absoluteFilename; | 489 SkString absoluteFilename; |
485 absoluteFilename.printf("%s/%s", dir, fileName.c_str()); | 490 absoluteFilename.printf("%s/%s", dir, fileName.c_str()); |
486 | 491 |
487 SkTDArray<FontFamily*> langSpecificFonts; | 492 SkTDArray<FontFamily*> langSpecificFonts; |
488 parseConfigFile(absoluteFilename.c_str(), langSpecificFonts); | 493 parseConfigFile(absoluteFilename.c_str(), langSpecificFonts); |
489 | 494 |
490 for (int i = 0; i < langSpecificFonts.count(); ++i) { | 495 for (int i = 0; i < langSpecificFonts.count(); ++i) { |
491 FontFamily* family = langSpecificFonts[i]; | 496 FontFamily* family = langSpecificFonts[i]; |
492 for (int j = 0; j < family->fFontFiles.count(); ++j) { | 497 family->fLanguage = SkLanguage(locale); |
493 family->fFontFiles[j].fPaintOptions.setLanguage(locale); | |
494 } | |
495 *fallbackFonts.append() = family; | 498 *fallbackFonts.append() = family; |
496 } | 499 } |
497 } | 500 } |
498 | 501 |
499 // proceed to the next entry in the directory | 502 // proceed to the next entry in the directory |
500 dirEntry = readdir(fontDirectory); | 503 dirEntry = readdir(fontDirectory); |
501 } | 504 } |
502 // cleanup the directory reference | 505 // cleanup the directory reference |
503 closedir(fontDirectory); | 506 closedir(fontDirectory); |
504 } | 507 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 if (NULL != testFallbackConfigFile) { | 565 if (NULL != testFallbackConfigFile) { |
563 parseConfigFile(testFallbackConfigFile, fallbackFonts); | 566 parseConfigFile(testFallbackConfigFile, fallbackFonts); |
564 } | 567 } |
565 | 568 |
566 // Append all fallback fonts to system fonts | 569 // Append all fallback fonts to system fonts |
567 for (int i = 0; i < fallbackFonts.count(); ++i) { | 570 for (int i = 0; i < fallbackFonts.count(); ++i) { |
568 fallbackFonts[i]->fIsFallbackFont = true; | 571 fallbackFonts[i]->fIsFallbackFont = true; |
569 *fontFamilies.append() = fallbackFonts[i]; | 572 *fontFamilies.append() = fallbackFonts[i]; |
570 } | 573 } |
571 } | 574 } |
| 575 |
| 576 SkLanguage SkLanguage::getParent() const { |
| 577 SkASSERT(!fTag.isEmpty()); |
| 578 const char* tag = fTag.c_str(); |
| 579 |
| 580 // strip off the rightmost "-.*" |
| 581 const char* parentTagEnd = strrchr(tag, '-'); |
| 582 if (parentTagEnd == NULL) { |
| 583 return SkLanguage(); |
| 584 } |
| 585 size_t parentTagLen = parentTagEnd - tag; |
| 586 return SkLanguage(tag, parentTagLen); |
| 587 } |
OLD | NEW |