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" | |
11 #include "SkTypeface.h" | 10 #include "SkTypeface.h" |
12 | 11 |
13 #include <expat.h> | 12 #include <expat.h> |
14 #include <stdio.h> | 13 #include <stdio.h> |
15 #include <sys/system_properties.h> | 14 #include <sys/system_properties.h> |
16 | 15 |
17 #include <limits> | |
18 | |
19 #define SYSTEM_FONTS_FILE "/system/etc/system_fonts.xml" | 16 #define SYSTEM_FONTS_FILE "/system/etc/system_fonts.xml" |
20 #define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml" | 17 #define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml" |
21 #define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml" | 18 #define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml" |
22 | 19 |
23 // These defines are used to determine the kind of tag that we're currently | 20 // These defines are used to determine the kind of tag that we're currently |
24 // populating with data. We only care about the sibling tags nameset and fileset | 21 // populating with data. We only care about the sibling tags nameset and fileset |
25 // for now. | 22 // for now. |
26 #define NO_TAG 0 | 23 #define NO_TAG 0 |
27 #define NAMESET_TAG 1 | 24 #define NAMESET_TAG 1 |
28 #define FILESET_TAG 2 | 25 #define FILESET_TAG 2 |
(...skipping 15 matching lines...) Expand all Loading... |
44 FontFamily *currentFamily; // The current family being created | 41 FontFamily *currentFamily; // The current family being created |
45 FontFileInfo *currentFontInfo; // The current fontInfo being created | 42 FontFileInfo *currentFontInfo; // The current fontInfo being created |
46 int currentTag; // A flag to indicate whether we're in na
meset/fileset tags | 43 int currentTag; // A flag to indicate whether we're in na
meset/fileset tags |
47 }; | 44 }; |
48 | 45 |
49 /** | 46 /** |
50 * Handler for arbitrary text. This is used to parse the text inside each name | 47 * Handler for arbitrary text. This is used to parse the text inside each name |
51 * or file tag. The resulting strings are put into the fNames or FontFileInfo ar
rays. | 48 * or file tag. The resulting strings are put into the fNames or FontFileInfo ar
rays. |
52 */ | 49 */ |
53 static void textHandler(void *data, const char *s, int len) { | 50 static void textHandler(void *data, const char *s, int len) { |
54 SkAutoAsciiToLC tolc(s); | |
55 FamilyData *familyData = (FamilyData*) data; | 51 FamilyData *familyData = (FamilyData*) data; |
56 // Make sure we're in the right state to store this name information | 52 // Make sure we're in the right state to store this name information |
57 if (familyData->currentFamily && | 53 if (familyData->currentFamily && |
58 (familyData->currentTag == NAMESET_TAG || familyData->currentTag ==
FILESET_TAG)) { | 54 (familyData->currentTag == NAMESET_TAG || familyData->currentTag ==
FILESET_TAG)) { |
59 switch (familyData->currentTag) { | 55 switch (familyData->currentTag) { |
60 case NAMESET_TAG: | 56 case NAMESET_TAG: |
61 familyData->currentFamily->fNames.push_back().set(tolc.lc(), len); | 57 familyData->currentFamily->fNames.push_back().set(s, len); |
62 break; | 58 break; |
63 case FILESET_TAG: | 59 case FILESET_TAG: |
64 if (familyData->currentFontInfo) { | 60 if (familyData->currentFontInfo) { |
65 familyData->currentFontInfo->fFileName.set(s, len); | 61 familyData->currentFontInfo->fFileName.set(s, len); |
66 } | 62 } |
67 break; | 63 break; |
68 default: | 64 default: |
69 // Noop - don't care about any text that's not in the Fonts or Names
list | 65 // Noop - don't care about any text that's not in the Fonts or Names
list |
70 break; | 66 break; |
71 } | 67 } |
72 } | 68 } |
73 } | 69 } |
74 | 70 |
75 /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega
tive-def */ | |
76 template <typename T> static bool parseNonNegativeInteger(const char* s, T* valu
e) { | |
77 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); | |
78 const T nMax = std::numeric_limits<T>::max() / 10; | |
79 const T dMax = std::numeric_limits<T>::max() - (nMax * 10); | |
80 T n = 0; | |
81 for (; *s; ++s) { | |
82 // Check if digit | |
83 if (*s < '0' || '9' < *s) { | |
84 return false; | |
85 } | |
86 int d = *s - '0'; | |
87 // Check for overflow | |
88 if (n > nMax || (n == nMax && d > dMax)) { | |
89 return false; | |
90 } | |
91 n = (n * 10) + d; | |
92 } | |
93 *value = n; | |
94 return true; | |
95 } | |
96 | |
97 /** | 71 /** |
98 * Handler for font files. This processes the attributes for language and | 72 * Handler for font files. This processes the attributes for language and |
99 * variants then lets textHandler handle the actual file name | 73 * variants then lets textHandler handle the actual file name |
100 */ | 74 */ |
101 static void fontFileElementHandler(FamilyData *familyData, const char **attribut
es) { | 75 static void fontFileElementHandler(FamilyData *familyData, const char **attribut
es) { |
102 | 76 |
103 FontFileInfo& newFileInfo = familyData->currentFamily->fFontFiles.push_back(
); | 77 FontFileInfo& newFileInfo = familyData->currentFamily->fFontFiles.push_back(
); |
104 if (attributes) { | 78 if (attributes) { |
105 int currentAttributeIndex = 0; | 79 int currentAttributeIndex = 0; |
106 while (attributes[currentAttributeIndex]) { | 80 while (attributes[currentAttributeIndex]) { |
107 const char* attributeName = attributes[currentAttributeIndex]; | 81 const char* attributeName = attributes[currentAttributeIndex]; |
108 const char* attributeValue = attributes[currentAttributeIndex+1]; | 82 const char* attributeValue = attributes[currentAttributeIndex+1]; |
109 int nameLength = strlen(attributeName); | 83 int nameLength = strlen(attributeName); |
110 int valueLength = strlen(attributeValue); | 84 int valueLength = strlen(attributeValue); |
111 if (strncmp(attributeName, "variant", nameLength) == 0) { | 85 if (strncmp(attributeName, "variant", nameLength) == 0) { |
112 if (strncmp(attributeValue, "elegant", valueLength) == 0) { | 86 if (strncmp(attributeValue, "elegant", valueLength) == 0) { |
113 newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndro
id::kElegant_Variant); | 87 newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndro
id::kElegant_Variant); |
114 } else if (strncmp(attributeValue, "compact", valueLength) == 0)
{ | 88 } else if (strncmp(attributeValue, "compact", valueLength) == 0)
{ |
115 newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndro
id::kCompact_Variant); | 89 newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndro
id::kCompact_Variant); |
116 } | 90 } |
117 } else if (strncmp(attributeName, "lang", nameLength) == 0) { | 91 } else if (strncmp(attributeName, "lang", nameLength) == 0) { |
118 newFileInfo.fPaintOptions.setLanguage(attributeValue); | 92 newFileInfo.fPaintOptions.setLanguage(attributeValue); |
119 } else if (strncmp(attributeName, "index", nameLength) == 0) { | |
120 int value; | |
121 if (parseNonNegativeInteger(attributeValue, &value)) { | |
122 newFileInfo.fIndex = value; | |
123 } else { | |
124 SkDebugf("---- SystemFonts index=%s (INVALID)", attributeVal
ue); | |
125 } | |
126 } | 93 } |
127 //each element is a pair of attributeName/attributeValue string pair
s | 94 //each element is a pair of attributeName/attributeValue string pair
s |
128 currentAttributeIndex += 2; | 95 currentAttributeIndex += 2; |
129 } | 96 } |
130 } | 97 } |
131 familyData->currentFontInfo = &newFileInfo; | 98 familyData->currentFontInfo = &newFileInfo; |
132 XML_SetCharacterDataHandler(*familyData->parser, textHandler); | 99 XML_SetCharacterDataHandler(*familyData->parser, textHandler); |
133 } | 100 } |
134 | 101 |
135 /** | 102 /** |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 SkString locale(6); | 306 SkString locale(6); |
340 char* localeCStr = locale.writable_str(); | 307 char* localeCStr = locale.writable_str(); |
341 | 308 |
342 strncpy(localeCStr, propLang, 2); | 309 strncpy(localeCStr, propLang, 2); |
343 localeCStr[2] = '-'; | 310 localeCStr[2] = '-'; |
344 strncpy(&localeCStr[3], propRegn, 2); | 311 strncpy(&localeCStr[3], propRegn, 2); |
345 localeCStr[5] = '\0'; | 312 localeCStr[5] = '\0'; |
346 | 313 |
347 return locale; | 314 return locale; |
348 } | 315 } |
OLD | NEW |