Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/ports/SkFontConfigParser_android.cpp

Issue 1096063003: Regularize informative messages in Android font parser. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkFontMgr_android.h" 9 #include "SkFontMgr_android.h"
10 #include "SkStream.h" 10 #include "SkStream.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 kNameSet_CurrentTag, 52 kNameSet_CurrentTag,
53 kFileSet_CurrentTag 53 kFileSet_CurrentTag
54 }; 54 };
55 55
56 /** 56 /**
57 * The FamilyData structure is passed around by the parser so that each handler 57 * The FamilyData structure is passed around by the parser so that each handler
58 * can read these variables that are relevant to the current parsing. 58 * can read these variables that are relevant to the current parsing.
59 */ 59 */
60 struct FamilyData { 60 struct FamilyData {
61 FamilyData(XML_Parser parser, SkTDArray<FontFamily*>& families, 61 FamilyData(XML_Parser parser, SkTDArray<FontFamily*>& families,
62 const SkString& basePath, bool isFallback) 62 const SkString& basePath, bool isFallback, const char* filename)
63 : fParser(parser) 63 : fParser(parser)
64 , fFamilies(families) 64 , fFamilies(families)
65 , fCurrentFamily(NULL) 65 , fCurrentFamily(NULL)
66 , fCurrentFontInfo(NULL) 66 , fCurrentFontInfo(NULL)
67 , fCurrentTag(kNo_CurrentTag) 67 , fCurrentTag(kNo_CurrentTag)
68 , fVersion(0) 68 , fVersion(0)
69 , fBasePath(basePath) 69 , fBasePath(basePath)
70 , fIsFallback(isFallback) 70 , fIsFallback(isFallback)
71 , fFilename(filename)
71 { }; 72 { };
72 73
73 XML_Parser fParser; // The expat parser doing the work , owned by caller 74 XML_Parser fParser; // The expat parser doing the work , owned by caller
74 SkTDArray<FontFamily*>& fFamilies; // The array to append families, o wned by caller 75 SkTDArray<FontFamily*>& fFamilies; // The array to append families, o wned by caller
75 SkAutoTDelete<FontFamily> fCurrentFamily; // The family being created, owned by this 76 SkAutoTDelete<FontFamily> fCurrentFamily; // The family being created, owned by this
76 FontFileInfo* fCurrentFontInfo; // The fontInfo being created, own ed by fCurrentFamily 77 FontFileInfo* fCurrentFontInfo; // The fontInfo being created, own ed by fCurrentFamily
77 CurrentTag fCurrentTag; // The kind of tag currently being parsed. 78 CurrentTag fCurrentTag; // The kind of tag currently being parsed.
78 int fVersion; // The version of the file parsed. 79 int fVersion; // The version of the file parsed.
79 const SkString& fBasePath; // The current base path. 80 const SkString& fBasePath; // The current base path.
80 const bool fIsFallback; // Indicates the file being parsed is a fallback file 81 const bool fIsFallback; // Indicates the file being parsed is a fallback file
82 const char* fFilename; // The name of the file currently being parsed.
81 }; 83 };
82 84
83 /** Parses a null terminated string into an integer type, checking for overflow. 85 /** Parses a null terminated string into an integer type, checking for overflow.
84 * http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def 86 * http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def
85 * 87 *
86 * If the string cannot be parsed into 'value', returns false and does not chan ge 'value'. 88 * If the string cannot be parsed into 'value', returns false and does not chan ge 'value'.
87 */ 89 */
88 template <typename T> static bool parse_non_negative_integer(const char* s, T* v alue) { 90 template <typename T> static bool parse_non_negative_integer(const char* s, T* v alue) {
89 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); 91 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer);
90 const T nMax = std::numeric_limits<T>::max() / 10; 92 const T nMax = std::numeric_limits<T>::max() / 10;
(...skipping 15 matching lines...) Expand all
106 return true; 108 return true;
107 } 109 }
108 110
109 static bool memeq(const char* s1, const char* s2, size_t n1, size_t n2) { 111 static bool memeq(const char* s1, const char* s2, size_t n1, size_t n2) {
110 return n1 == n2 && 0 == memcmp(s1, s2, n1); 112 return n1 == n2 && 0 == memcmp(s1, s2, n1);
111 } 113 }
112 #define MEMEQ(c, s, n) memeq(c, s, sizeof(c) - 1, n) 114 #define MEMEQ(c, s, n) memeq(c, s, sizeof(c) - 1, n)
113 115
114 #define ATTS_NON_NULL(a, i) (a[i] != NULL && a[i+1] != NULL) 116 #define ATTS_NON_NULL(a, i) (a[i] != NULL && a[i+1] != NULL)
115 117
118 #define SK_FONTCONFIGPARSER_PREFIX "[SkFontConfigParser] "
119
120 #define SK_FONTCONFIGPARSER_WARNING(message, ...) SkDebugf( \
121 SK_FONTCONFIGPARSER_PREFIX "%s:%d:%d: warning: " message "\n", \
122 self->fFilename, \
123 XML_GetCurrentLineNumber(self->fParser), \
124 XML_GetCurrentColumnNumber(self->fParser), \
125 ##__VA_ARGS__);
126
116 namespace lmpParser { 127 namespace lmpParser {
117 128
118 static void family_element_handler(FontFamily* family, const char** attributes) { 129 static void family_element_handler(FontFamily* family, const char** attributes) {
119 // A non-fallback <family> tag must have a canonical name attribute. 130 // A <family> element without a 'name' (string) attribute is a fallback font .
120 // A fallback <family> tag has no name, and may have lang and variant 131 // The element may have 'lang' (string) and 'variant' ("elegant", "compact") attributes.
121 // attributes. 132 // The element should contain <font> elements.
122 family->fIsFallbackFont = true; 133 family->fIsFallbackFont = true;
123 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { 134 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) {
124 const char* name = attributes[i]; 135 const char* name = attributes[i];
125 const char* value = attributes[i+1]; 136 const char* value = attributes[i+1];
126 size_t nameLen = strlen(name); 137 size_t nameLen = strlen(name);
127 size_t valueLen = strlen(value); 138 size_t valueLen = strlen(value);
128 if (MEMEQ("name", name, nameLen)) { 139 if (MEMEQ("name", name, nameLen)) {
129 SkAutoAsciiToLC tolc(value); 140 SkAutoAsciiToLC tolc(value);
130 family->fNames.push_back().set(tolc.lc()); 141 family->fNames.push_back().set(tolc.lc());
131 family->fIsFallbackFont = false; 142 family->fIsFallbackFont = false;
132 } else if (MEMEQ("lang", name, nameLen)) { 143 } else if (MEMEQ("lang", name, nameLen)) {
133 family->fLanguage = SkLanguage(value, valueLen); 144 family->fLanguage = SkLanguage(value, valueLen);
134 } else if (MEMEQ("variant", name, nameLen)) { 145 } else if (MEMEQ("variant", name, nameLen)) {
135 // Value should be either elegant or compact.
136 if (MEMEQ("elegant", value, valueLen)) { 146 if (MEMEQ("elegant", value, valueLen)) {
137 family->fVariant = kElegant_FontVariant; 147 family->fVariant = kElegant_FontVariant;
138 } else if (MEMEQ("compact", value, valueLen)) { 148 } else if (MEMEQ("compact", value, valueLen)) {
139 family->fVariant = kCompact_FontVariant; 149 family->fVariant = kCompact_FontVariant;
140 } 150 }
141 } 151 }
142 } 152 }
143 } 153 }
144 154
145 static void XMLCALL font_file_name_handler(void* data, const char* s, int len) { 155 static void XMLCALL font_file_name_handler(void* data, const char* s, int len) {
146 FamilyData* self = static_cast<FamilyData*>(data); 156 FamilyData* self = static_cast<FamilyData*>(data);
147 self->fCurrentFontInfo->fFileName.append(s, len); 157 self->fCurrentFontInfo->fFileName.append(s, len);
148 } 158 }
149 159
150 static void font_element_handler(FamilyData* self, FontFileInfo* file, const cha r** attributes) { 160 static void font_element_handler(FamilyData* self, FontFileInfo* file, const cha r** attributes) {
151 // A <font> should have weight (integer) and style (normal, italic) attribut es. 161 // A <font> element should be contained in a <family> element.
152 // NOTE: we ignore the style. 162 // The element may have 'weight' (non-negative integer), 'style' ("normal", "italic"),
163 // and 'index' (non-negative integer) attributes.
153 // The element should contain a filename. 164 // The element should contain a filename.
154 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { 165 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) {
155 const char* name = attributes[i]; 166 const char* name = attributes[i];
156 const char* value = attributes[i+1]; 167 const char* value = attributes[i+1];
157 size_t nameLen = strlen(name); 168 size_t nameLen = strlen(name);
158 if (MEMEQ("weight", name, nameLen)) { 169 if (MEMEQ("weight", name, nameLen)) {
159 if (!parse_non_negative_integer(value, &file->fWeight)) { 170 if (!parse_non_negative_integer(value, &file->fWeight)) {
160 SkDebugf("---- Font weight %s (INVALID)", value); 171 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid weight", value);
161 } 172 }
162 } else if (MEMEQ("style", name, nameLen)) { 173 } else if (MEMEQ("style", name, nameLen)) {
163 size_t valueLen = strlen(value); 174 size_t valueLen = strlen(value);
164 if (MEMEQ("normal", value, valueLen)) { 175 if (MEMEQ("normal", value, valueLen)) {
165 file->fStyle = FontFileInfo::Style::kNormal; 176 file->fStyle = FontFileInfo::Style::kNormal;
166 } else if (MEMEQ("italic", value, valueLen)) { 177 } else if (MEMEQ("italic", value, valueLen)) {
167 file->fStyle = FontFileInfo::Style::kItalic; 178 file->fStyle = FontFileInfo::Style::kItalic;
168 } 179 }
169 } else if (MEMEQ("index", name, nameLen)) { 180 } else if (MEMEQ("index", name, nameLen)) {
170 if (!parse_non_negative_integer(value, &file->fIndex)) { 181 if (!parse_non_negative_integer(value, &file->fIndex)) {
171 SkDebugf("---- Font index %s (INVALID)", value); 182 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid index", value);
172 } 183 }
173 } 184 }
174 } 185 }
175 XML_SetCharacterDataHandler(self->fParser, font_file_name_handler); 186 XML_SetCharacterDataHandler(self->fParser, font_file_name_handler);
176 } 187 }
177 188
178 static FontFamily* find_family(FamilyData* self, const SkString& familyName) { 189 static FontFamily* find_family(FamilyData* self, const SkString& familyName) {
179 for (int i = 0; i < self->fFamilies.count(); i++) { 190 for (int i = 0; i < self->fFamilies.count(); i++) {
180 FontFamily* candidate = self->fFamilies[i]; 191 FontFamily* candidate = self->fFamilies[i];
181 for (int j = 0; j < candidate->fNames.count(); j++) { 192 for (int j = 0; j < candidate->fNames.count(); j++) {
182 if (candidate->fNames[j] == familyName) { 193 if (candidate->fNames[j] == familyName) {
183 return candidate; 194 return candidate;
184 } 195 }
185 } 196 }
186 } 197 }
187 return NULL; 198 return NULL;
188 } 199 }
189 200
190 static void alias_element_handler(FamilyData* self, const char** attributes) { 201 static void alias_element_handler(FamilyData* self, const char** attributes) {
191 // An <alias> must have name and to attributes. 202 // A <alias> element must have 'name' (string) and 'to' (string) attributes.
192 // It may have weight (integer). 203 // The element may also have a 'weight' (non-negative integer) attribute.
193 // If it *does not* have a weight, it is a variant name for a <family>. 204 // The 'name' introduces a new family name.
194 // If it *does* have a weight, it names the <font>(s) of a specific weight 205 // The 'to' specifies which (previous) <family> to alias.
195 // from a <family>. 206 // If it *does not* have a weight, 'name' is an alias for the entire 'to' <f amily>.
207 // If it *does* have a weight, 'name' is a new family consisting of the <fon t>(s) with 'weight'
208 // from the 'to' <family>.
196 209
197 SkString aliasName; 210 SkString aliasName;
198 SkString to; 211 SkString to;
199 int weight = 0; 212 int weight = 0;
200 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { 213 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) {
201 const char* name = attributes[i]; 214 const char* name = attributes[i];
202 const char* value = attributes[i+1]; 215 const char* value = attributes[i+1];
203 size_t nameLen = strlen(name); 216 size_t nameLen = strlen(name);
204 if (MEMEQ("name", name, nameLen)) { 217 if (MEMEQ("name", name, nameLen)) {
205 SkAutoAsciiToLC tolc(value); 218 SkAutoAsciiToLC tolc(value);
206 aliasName.set(tolc.lc()); 219 aliasName.set(tolc.lc());
207 } else if (MEMEQ("to", name, nameLen)) { 220 } else if (MEMEQ("to", name, nameLen)) {
208 to.set(value); 221 to.set(value);
209 } else if (MEMEQ("weight", name, nameLen)) { 222 } else if (MEMEQ("weight", name, nameLen)) {
210 if (!parse_non_negative_integer(value, &weight)) { 223 if (!parse_non_negative_integer(value, &weight)) {
211 SkDebugf("---- Font weight %s (INVALID)", value); 224 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid weight", value);
212 } 225 }
213 } 226 }
214 } 227 }
215 228
216 // Assumes that the named family is already declared 229 // Assumes that the named family is already declared
217 FontFamily* targetFamily = find_family(self, to); 230 FontFamily* targetFamily = find_family(self, to);
218 if (!targetFamily) { 231 if (!targetFamily) {
219 SkDebugf("---- Font alias target %s (NOT FOUND)", to.c_str()); 232 SK_FONTCONFIGPARSER_WARNING("'%s' alias target not found", to.c_str());
220 return; 233 return;
221 } 234 }
222 235
223 if (weight) { 236 if (weight) {
224 FontFamily* family = new FontFamily(targetFamily->fBasePath, self->fIsFa llback); 237 FontFamily* family = new FontFamily(targetFamily->fBasePath, self->fIsFa llback);
225 family->fNames.push_back().set(aliasName); 238 family->fNames.push_back().set(aliasName);
226 239
227 for (int i = 0; i < targetFamily->fFonts.count(); i++) { 240 for (int i = 0; i < targetFamily->fFonts.count(); i++) {
228 if (targetFamily->fFonts[i].fWeight == weight) { 241 if (targetFamily->fFonts[i].fWeight == weight) {
229 family->fFonts.push_back(targetFamily->fFonts[i]); 242 family->fFonts.push_back(targetFamily->fFonts[i]);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 305
293 /** 306 /**
294 * Handler for font files. This processes the attributes for language and 307 * Handler for font files. This processes the attributes for language and
295 * variants then lets textHandler handle the actual file name 308 * variants then lets textHandler handle the actual file name
296 */ 309 */
297 static void font_file_element_handler(FamilyData* self, const char** attributes) { 310 static void font_file_element_handler(FamilyData* self, const char** attributes) {
298 FontFamily& currentFamily = *self->fCurrentFamily.get(); 311 FontFamily& currentFamily = *self->fCurrentFamily.get();
299 FontFileInfo& newFileInfo = currentFamily.fFonts.push_back(); 312 FontFileInfo& newFileInfo = currentFamily.fFonts.push_back();
300 if (attributes) { 313 if (attributes) {
301 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { 314 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) {
302 const char* attributeName = attributes[i]; 315 const char* name = attributes[i];
303 const char* attributeValue = attributes[i+1]; 316 const char* value = attributes[i+1];
304 size_t nameLength = strlen(attributeName); 317 size_t nameLen = strlen(name);
305 size_t valueLength = strlen(attributeValue); 318 size_t valueLen = strlen(value);
306 if (MEMEQ("variant", attributeName, nameLength)) { 319 if (MEMEQ("variant", name, nameLen)) {
307 const FontVariant prevVariant = currentFamily.fVariant; 320 const FontVariant prevVariant = currentFamily.fVariant;
308 if (MEMEQ("elegant", attributeValue, valueLength)) { 321 if (MEMEQ("elegant", value, valueLen)) {
309 currentFamily.fVariant = kElegant_FontVariant; 322 currentFamily.fVariant = kElegant_FontVariant;
310 } else if (MEMEQ("compact", attributeValue, valueLength)) { 323 } else if (MEMEQ("compact", value, valueLen)) {
311 currentFamily.fVariant = kCompact_FontVariant; 324 currentFamily.fVariant = kCompact_FontVariant;
312 } 325 }
313 if (currentFamily.fFonts.count() > 1 && currentFamily.fVariant ! = prevVariant) { 326 if (currentFamily.fFonts.count() > 1 && currentFamily.fVariant ! = prevVariant) {
314 SkDebugf("Every font file within a family must have identica l variants"); 327 SK_FONTCONFIGPARSER_WARNING("'%s' unexpected variant found\n "
328 "Note: Every font file within a family must have identic al variants.",
329 value);
315 } 330 }
316 331
317 } else if (MEMEQ("lang", attributeName, nameLength)) { 332 } else if (MEMEQ("lang", name, nameLen)) {
318 SkLanguage prevLang = currentFamily.fLanguage; 333 SkLanguage prevLang = currentFamily.fLanguage;
319 currentFamily.fLanguage = SkLanguage(attributeValue, valueLength ); 334 currentFamily.fLanguage = SkLanguage(value, valueLen);
320 if (currentFamily.fFonts.count() > 1 && currentFamily.fLanguage != prevLang) { 335 if (currentFamily.fFonts.count() > 1 && currentFamily.fLanguage != prevLang) {
321 SkDebugf("Every font file within a family must have identica l languages"); 336 SK_FONTCONFIGPARSER_WARNING("'%s' unexpected language found\ n"
337 "Note: Every font file within a family must have identic al languages.",
338 value);
322 } 339 }
323 340
324 } else if (MEMEQ("index", attributeName, nameLength)) { 341 } else if (MEMEQ("index", name, nameLen)) {
325 if (!parse_non_negative_integer(attributeValue, &newFileInfo.fIn dex)) { 342 if (!parse_non_negative_integer(value, &newFileInfo.fIndex)) {
326 SkDebugf("---- SystemFonts index=%s (INVALID)", attributeVal ue); 343 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid index", valu e);
327 } 344 }
328 } 345 }
329 } 346 }
330 } 347 }
331 self->fCurrentFontInfo = &newFileInfo; 348 self->fCurrentFontInfo = &newFileInfo;
332 XML_SetCharacterDataHandler(self->fParser, text_handler); 349 XML_SetCharacterDataHandler(self->fParser, text_handler);
333 } 350 }
334 351
335 /** 352 /**
336 * Handler for the start of a tag. The only tags we expect are familyset, family , 353 * Handler for the start of a tag. The only tags we expect are familyset, family ,
337 * nameset, fileset, name, and file. 354 * nameset, fileset, name, and file.
338 */ 355 */
339 static void XMLCALL start_element_handler(void* data, const char* tag, const cha r** attributes) { 356 static void XMLCALL start_element_handler(void* data, const char* tag, const cha r** attributes) {
340 FamilyData* self = static_cast<FamilyData*>(data); 357 FamilyData* self = static_cast<FamilyData*>(data);
341 size_t len = strlen(tag); 358 size_t len = strlen(tag);
342 if (MEMEQ("familyset", tag, len)) { 359 if (MEMEQ("familyset", tag, len)) {
343 // The familyset tag has an optional "version" attribute with an integer value >= 0 360 // The <familyset> element has an optional 'version' (non-negative integ er) attribute.
344 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { 361 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) {
345 size_t nameLen = strlen(attributes[i]); 362 size_t nameLen = strlen(attributes[i]);
346 if (!MEMEQ("version", attributes[i], nameLen)) continue; 363 if (!MEMEQ("version", attributes[i], nameLen)) continue;
347 const char* valueString = attributes[i+1]; 364 const char* valueString = attributes[i+1];
348 int version; 365 int version;
349 if (parse_non_negative_integer(valueString, &version) && (version >= 21)) { 366 if (parse_non_negative_integer(valueString, &version) && (version >= 21)) {
350 XML_SetElementHandler(self->fParser, 367 XML_SetElementHandler(self->fParser,
351 lmpParser::start_element_handler, 368 lmpParser::start_element_handler,
352 lmpParser::end_element_handler); 369 lmpParser::end_element_handler);
353 self->fVersion = version; 370 self->fVersion = version;
354 } 371 }
355 } 372 }
356 } else if (MEMEQ("family", tag, len)) { 373 } else if (MEMEQ("family", tag, len)) {
357 self->fCurrentFamily.reset(new FontFamily(self->fBasePath, self->fIsFall back)); 374 self->fCurrentFamily.reset(new FontFamily(self->fBasePath, self->fIsFall back));
358 // The Family tag has an optional "order" attribute with an integer valu e >= 0 375 // The <family> element has an optional 'order' (non-negative integer) a ttribute.
359 // If this attribute does not exist, the default value is -1 376 // If this attribute does not exist, the default value is -1.
360 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { 377 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) {
361 const char* valueString = attributes[i+1]; 378 const char* valueString = attributes[i+1];
362 int value; 379 int value;
363 if (parse_non_negative_integer(valueString, &value)) { 380 if (parse_non_negative_integer(valueString, &value)) {
364 self->fCurrentFamily->fOrder = value; 381 self->fCurrentFamily->fOrder = value;
365 } 382 }
366 } 383 }
367 } else if (MEMEQ("nameset", tag, len)) { 384 } else if (MEMEQ("nameset", tag, len)) {
368 self->fCurrentTag = kNameSet_CurrentTag; 385 self->fCurrentTag = kNameSet_CurrentTag;
369 } else if (MEMEQ("fileset", tag, len)) { 386 } else if (MEMEQ("fileset", tag, len)) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 const XML_Char *entityName, 422 const XML_Char *entityName,
406 int is_parameter_entity, 423 int is_parameter_entity,
407 const XML_Char *value, 424 const XML_Char *value,
408 int value_length, 425 int value_length,
409 const XML_Char *base, 426 const XML_Char *base,
410 const XML_Char *systemId, 427 const XML_Char *systemId,
411 const XML_Char *publicId, 428 const XML_Char *publicId,
412 const XML_Char *notationName) 429 const XML_Char *notationName)
413 { 430 {
414 FamilyData* self = static_cast<FamilyData*>(data); 431 FamilyData* self = static_cast<FamilyData*>(data);
415 SkDebugf("Entity declaration %s found, stopping processing.", entityName); 432 SK_FONTCONFIGPARSER_WARNING("'%s' entity declaration found, stopping process ing", entityName);
416 XML_StopParser(self->fParser, XML_FALSE); 433 XML_StopParser(self->fParser, XML_FALSE);
417 } 434 }
418 435
419 static const XML_Memory_Handling_Suite sk_XML_alloc = { 436 static const XML_Memory_Handling_Suite sk_XML_alloc = {
420 sk_malloc_throw, 437 sk_malloc_throw,
421 sk_realloc_throw, 438 sk_realloc_throw,
422 sk_free 439 sk_free
423 }; 440 };
424 441
425 template<typename T> struct remove_ptr {typedef T type;}; 442 template<typename T> struct remove_ptr {typedef T type;};
426 template<typename T> struct remove_ptr<T*> {typedef T type;}; 443 template<typename T> struct remove_ptr<T*> {typedef T type;};
427 444
428 /** 445 /**
429 * This function parses the given filename and stores the results in the given 446 * This function parses the given filename and stores the results in the given
430 * families array. Returns the version of the file, negative if the file does no t exist. 447 * families array. Returns the version of the file, negative if the file does no t exist.
431 */ 448 */
432 static int parse_config_file(const char* filename, SkTDArray<FontFamily*>& famil ies, 449 static int parse_config_file(const char* filename, SkTDArray<FontFamily*>& famil ies,
433 const SkString& basePath, bool isFallback) 450 const SkString& basePath, bool isFallback)
434 { 451 {
435 SkFILEStream file(filename); 452 SkFILEStream file(filename);
436 453
437 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml) 454 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml)
438 // are optional - failure here is okay because one of these optional files m ay not exist. 455 // are optional - failure here is okay because one of these optional files m ay not exist.
439 if (!file.isValid()) { 456 if (!file.isValid()) {
440 SkDebugf("File %s could not be opened.\n", filename); 457 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "'%s' could not be opened\n", filena me);
441 return -1; 458 return -1;
442 } 459 }
443 460
444 SkAutoTCallVProc<remove_ptr<XML_Parser>::type, XML_ParserFree> parser( 461 SkAutoTCallVProc<remove_ptr<XML_Parser>::type, XML_ParserFree> parser(
445 XML_ParserCreate_MM(NULL, &sk_XML_alloc, NULL)); 462 XML_ParserCreate_MM(NULL, &sk_XML_alloc, NULL));
446 if (!parser) { 463 if (!parser) {
447 SkDebugf("Could not create XML parser.\n"); 464 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "could not create XML parser\n");
448 return -1; 465 return -1;
449 } 466 }
450 467
451 FamilyData self(parser, families, basePath, isFallback); 468 FamilyData self(parser, families, basePath, isFallback, filename);
452 XML_SetUserData(parser, &self); 469 XML_SetUserData(parser, &self);
453 470
454 // Disable entity processing, to inhibit internal entity expansion. See expa t CVE-2013-0340 471 // Disable entity processing, to inhibit internal entity expansion. See expa t CVE-2013-0340
455 XML_SetEntityDeclHandler(parser, xml_entity_decl_handler); 472 XML_SetEntityDeclHandler(parser, xml_entity_decl_handler);
456 473
457 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file. 474 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file.
458 XML_SetElementHandler(parser, jbParser::start_element_handler, jbParser::end _element_handler); 475 XML_SetElementHandler(parser, jbParser::start_element_handler, jbParser::end _element_handler);
459 476
460 // One would assume it would be faster to have a buffer on the stack and cal l XML_Parse. 477 // One would assume it would be faster to have a buffer on the stack and cal l XML_Parse.
461 // But XML_Parse will call XML_GetBuffer anyway and memmove the passed buffe r into it. 478 // But XML_Parse will call XML_GetBuffer anyway and memmove the passed buffe r into it.
462 // (Unless XML_CONTEXT_BYTES is undefined, but all users define it.) 479 // (Unless XML_CONTEXT_BYTES is undefined, but all users define it.)
463 // In debug, buffer a small odd number of bytes to detect slicing in XML_Cha racterDataHandler. 480 // In debug, buffer a small odd number of bytes to detect slicing in XML_Cha racterDataHandler.
464 static const int bufferSize = 512 SkDEBUGCODE( - 507); 481 static const int bufferSize = 512 SkDEBUGCODE( - 507);
465 bool done = false; 482 bool done = false;
466 while (!done) { 483 while (!done) {
467 void* buffer = XML_GetBuffer(parser, bufferSize); 484 void* buffer = XML_GetBuffer(parser, bufferSize);
468 if (!buffer) { 485 if (!buffer) {
469 SkDebugf("Could not buffer enough to continue.\n"); 486 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "could not buffer enough to cont inue\n");
470 return -1; 487 return -1;
471 } 488 }
472 size_t len = file.read(buffer, bufferSize); 489 size_t len = file.read(buffer, bufferSize);
473 done = file.isAtEnd(); 490 done = file.isAtEnd();
474 XML_Status status = XML_ParseBuffer(parser, len, done); 491 XML_Status status = XML_ParseBuffer(parser, len, done);
475 if (XML_STATUS_ERROR == status) { 492 if (XML_STATUS_ERROR == status) {
476 XML_Error error = XML_GetErrorCode(parser); 493 XML_Error error = XML_GetErrorCode(parser);
477 int line = XML_GetCurrentLineNumber(parser); 494 int line = XML_GetCurrentLineNumber(parser);
478 int column = XML_GetCurrentColumnNumber(parser); 495 int column = XML_GetCurrentColumnNumber(parser);
479 int index = XML_GetCurrentByteIndex(parser);
480 const XML_LChar* errorString = XML_ErrorString(error); 496 const XML_LChar* errorString = XML_ErrorString(error);
481 SkDebugf("Line: %d Column: %d (Offset: %d) Error %d: %s.\n", 497 SkDebugf(SK_FONTCONFIGPARSER_PREFIX "%s:%d:%d error %d: %s.\n",
482 line, column, index, error, errorString); 498 filename, line, column, error, errorString);
483 return -1; 499 return -1;
484 } 500 }
485 } 501 }
486 return self.fVersion; 502 return self.fVersion;
487 } 503 }
488 504
489 /** Returns the version of the system font file actually found, negative if none . */ 505 /** Returns the version of the system font file actually found, negative if none . */
490 static int append_system_font_families(SkTDArray<FontFamily*>& fontFamilies, 506 static int append_system_font_families(SkTDArray<FontFamily*>& fontFamilies,
491 const SkString& basePath) 507 const SkString& basePath)
492 { 508 {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 const char* tag = fTag.c_str(); 650 const char* tag = fTag.c_str();
635 651
636 // strip off the rightmost "-.*" 652 // strip off the rightmost "-.*"
637 const char* parentTagEnd = strrchr(tag, '-'); 653 const char* parentTagEnd = strrchr(tag, '-');
638 if (parentTagEnd == NULL) { 654 if (parentTagEnd == NULL) {
639 return SkLanguage(); 655 return SkLanguage();
640 } 656 }
641 size_t parentTagLen = parentTagEnd - tag; 657 size_t parentTagLen = parentTagEnd - tag;
642 return SkLanguage(tag, parentTagLen); 658 return SkLanguage(tag, parentTagLen);
643 } 659 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698