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