| 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 "SkFontMgr_android_parser.h" | 8 #include "SkFontMgr_android_parser.h" |
| 9 #include "SkStream.h" | 9 #include "SkStream.h" |
| 10 #include "SkTDArray.h" | 10 #include "SkTDArray.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 * | 44 * |
| 45 * If the 'familyset' 'version' attribute is 21 or higher the LMP parser is used
, otherwise the JB. | 45 * If the 'familyset' 'version' attribute is 21 or higher the LMP parser is used
, otherwise the JB. |
| 46 */ | 46 */ |
| 47 | 47 |
| 48 struct FamilyData; | 48 struct FamilyData; |
| 49 | 49 |
| 50 struct TagHandler { | 50 struct TagHandler { |
| 51 /** Called at the start tag. | 51 /** Called at the start tag. |
| 52 * Called immediately after the parent tag retuns this handler from a call
to 'tag'. | 52 * Called immediately after the parent tag retuns this handler from a call
to 'tag'. |
| 53 * Allows setting up for handling the tag content and processing attributes
. | 53 * Allows setting up for handling the tag content and processing attributes
. |
| 54 * If NULL, will not be called. | 54 * If nullptr, will not be called. |
| 55 */ | 55 */ |
| 56 void (*start)(FamilyData* data, const char* tag, const char** attributes); | 56 void (*start)(FamilyData* data, const char* tag, const char** attributes); |
| 57 | 57 |
| 58 /** Called at the end tag. | 58 /** Called at the end tag. |
| 59 * Allows post-processing of any accumulated information. | 59 * Allows post-processing of any accumulated information. |
| 60 * This will be the last call made in relation to the current tag. | 60 * This will be the last call made in relation to the current tag. |
| 61 * If NULL, will not be called. | 61 * If nullptr, will not be called. |
| 62 */ | 62 */ |
| 63 void (*end)(FamilyData* data, const char* tag); | 63 void (*end)(FamilyData* data, const char* tag); |
| 64 | 64 |
| 65 /** Called when a nested tag is encountered. | 65 /** Called when a nested tag is encountered. |
| 66 * This is responsible for determining how to handle the tag. | 66 * This is responsible for determining how to handle the tag. |
| 67 * If the tag is not recognized, return NULL to skip the tag. | 67 * If the tag is not recognized, return nullptr to skip the tag. |
| 68 * If NULL, all nested tags will be skipped. | 68 * If nullptr, all nested tags will be skipped. |
| 69 */ | 69 */ |
| 70 const TagHandler* (*tag)(FamilyData* data, const char* tag, const char** att
ributes); | 70 const TagHandler* (*tag)(FamilyData* data, const char* tag, const char** att
ributes); |
| 71 | 71 |
| 72 /** The character handler for this tag. | 72 /** The character handler for this tag. |
| 73 * This is only active for character data contained directly in this tag (n
ot sub-tags). | 73 * This is only active for character data contained directly in this tag (n
ot sub-tags). |
| 74 * The first parameter will be castable to a FamilyData*. | 74 * The first parameter will be castable to a FamilyData*. |
| 75 * If NULL, any character data in this tag will be ignored. | 75 * If nullptr, any character data in this tag will be ignored. |
| 76 */ | 76 */ |
| 77 XML_CharacterDataHandler chars; | 77 XML_CharacterDataHandler chars; |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 /** Represents the current parsing state. */ | 80 /** Represents the current parsing state. */ |
| 81 struct FamilyData { | 81 struct FamilyData { |
| 82 FamilyData(XML_Parser parser, SkTDArray<FontFamily*>& families, | 82 FamilyData(XML_Parser parser, SkTDArray<FontFamily*>& families, |
| 83 const SkString& basePath, bool isFallback, const char* filename, | 83 const SkString& basePath, bool isFallback, const char* filename, |
| 84 const TagHandler* topLevelHandler) | 84 const TagHandler* topLevelHandler) |
| 85 : fParser(parser) | 85 : fParser(parser) |
| 86 , fFamilies(families) | 86 , fFamilies(families) |
| 87 , fCurrentFamily(NULL) | 87 , fCurrentFamily(nullptr) |
| 88 , fCurrentFontInfo(NULL) | 88 , fCurrentFontInfo(nullptr) |
| 89 , fVersion(0) | 89 , fVersion(0) |
| 90 , fBasePath(basePath) | 90 , fBasePath(basePath) |
| 91 , fIsFallback(isFallback) | 91 , fIsFallback(isFallback) |
| 92 , fFilename(filename) | 92 , fFilename(filename) |
| 93 , fDepth(1) | 93 , fDepth(1) |
| 94 , fSkip(0) | 94 , fSkip(0) |
| 95 , fHandler(&topLevelHandler, 1) | 95 , fHandler(&topLevelHandler, 1) |
| 96 { }; | 96 { }; |
| 97 | 97 |
| 98 XML_Parser fParser; // The expat parser doing the work
, owned by caller | 98 XML_Parser fParser; // The expat parser doing the work
, owned by caller |
| 99 SkTDArray<FontFamily*>& fFamilies; // The array to append families, o
wned by caller | 99 SkTDArray<FontFamily*>& fFamilies; // The array to append families, o
wned by caller |
| 100 SkAutoTDelete<FontFamily> fCurrentFamily; // The family being created, owned
by this | 100 SkAutoTDelete<FontFamily> fCurrentFamily; // The family being created, owned
by this |
| 101 FontFileInfo* fCurrentFontInfo; // The fontInfo being created, own
ed by fCurrentFamily | 101 FontFileInfo* fCurrentFontInfo; // The fontInfo being created, own
ed by fCurrentFamily |
| 102 int fVersion; // The version of the file parsed. | 102 int fVersion; // The version of the file parsed. |
| 103 const SkString& fBasePath; // The current base path. | 103 const SkString& fBasePath; // The current base path. |
| 104 const bool fIsFallback; // Indicates the file being parsed
is a fallback file | 104 const bool fIsFallback; // Indicates the file being parsed
is a fallback file |
| 105 const char* fFilename; // The name of the file currently
being parsed. | 105 const char* fFilename; // The name of the file currently
being parsed. |
| 106 | 106 |
| 107 int fDepth; // The current element depth of th
e parse. | 107 int fDepth; // The current element depth of th
e parse. |
| 108 int fSkip; // The depth to stop skipping, 0 i
f not skipping. | 108 int fSkip; // The depth to stop skipping, 0 i
f not skipping. |
| 109 SkTDArray<const TagHandler*> fHandler; // The stack of current tag handle
rs. | 109 SkTDArray<const TagHandler*> fHandler; // The stack of current tag handle
rs. |
| 110 }; | 110 }; |
| 111 | 111 |
| 112 static bool memeq(const char* s1, const char* s2, size_t n1, size_t n2) { | 112 static bool memeq(const char* s1, const char* s2, size_t n1, size_t n2) { |
| 113 return n1 == n2 && 0 == memcmp(s1, s2, n1); | 113 return n1 == n2 && 0 == memcmp(s1, s2, n1); |
| 114 } | 114 } |
| 115 #define MEMEQ(c, s, n) memeq(c, s, sizeof(c) - 1, n) | 115 #define MEMEQ(c, s, n) memeq(c, s, sizeof(c) - 1, n) |
| 116 | 116 |
| 117 #define ATTS_NON_NULL(a, i) (a[i] != NULL && a[i+1] != NULL) | 117 #define ATTS_NON_NULL(a, i) (a[i] != nullptr && a[i+1] != nullptr) |
| 118 | 118 |
| 119 #define SK_FONTMGR_ANDROID_PARSER_PREFIX "[SkFontMgr Android Parser] " | 119 #define SK_FONTMGR_ANDROID_PARSER_PREFIX "[SkFontMgr Android Parser] " |
| 120 | 120 |
| 121 #define SK_FONTCONFIGPARSER_WARNING(message, ...) SkDebugf( \ | 121 #define SK_FONTCONFIGPARSER_WARNING(message, ...) SkDebugf( \ |
| 122 SK_FONTMGR_ANDROID_PARSER_PREFIX "%s:%d:%d: warning: " message "\n", \ | 122 SK_FONTMGR_ANDROID_PARSER_PREFIX "%s:%d:%d: warning: " message "\n", \ |
| 123 self->fFilename, \ | 123 self->fFilename, \ |
| 124 XML_GetCurrentLineNumber(self->fParser), \ | 124 XML_GetCurrentLineNumber(self->fParser), \ |
| 125 XML_GetCurrentColumnNumber(self->fParser), \ | 125 XML_GetCurrentColumnNumber(self->fParser), \ |
| 126 ##__VA_ARGS__); | 126 ##__VA_ARGS__); |
| 127 | 127 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 } else { | 171 } else { |
| 172 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid axis tag", v
alue); | 172 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid axis tag", v
alue); |
| 173 } | 173 } |
| 174 } else if (MEMEQ("stylevalue", name, nameLen)) { | 174 } else if (MEMEQ("stylevalue", name, nameLen)) { |
| 175 if (!parse_fixed<16>(value, &axis.fValue)) { | 175 if (!parse_fixed<16>(value, &axis.fValue)) { |
| 176 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid axis styleva
lue", value); | 176 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid axis styleva
lue", value); |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 }, | 180 }, |
| 181 /*end*/NULL, | 181 /*end*/nullptr, |
| 182 /*tag*/NULL, | 182 /*tag*/nullptr, |
| 183 /*chars*/NULL, | 183 /*chars*/nullptr, |
| 184 }; | 184 }; |
| 185 | 185 |
| 186 static const TagHandler fontHandler = { | 186 static const TagHandler fontHandler = { |
| 187 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { | 187 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { |
| 188 // 'weight' (non-negative integer) [default 0] | 188 // 'weight' (non-negative integer) [default 0] |
| 189 // 'style' ("normal", "italic") [default "auto"] | 189 // 'style' ("normal", "italic") [default "auto"] |
| 190 // 'index' (non-negative integer) [default 0] | 190 // 'index' (non-negative integer) [default 0] |
| 191 // The character data should be a filename. | 191 // The character data should be a filename. |
| 192 FontFileInfo& file = self->fCurrentFamily->fFonts.push_back(); | 192 FontFileInfo& file = self->fCurrentFamily->fFonts.push_back(); |
| 193 self->fCurrentFontInfo = &file; | 193 self->fCurrentFontInfo = &file; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 214 } | 214 } |
| 215 }, | 215 }, |
| 216 /*end*/[](FamilyData* self, const char* tag) { | 216 /*end*/[](FamilyData* self, const char* tag) { |
| 217 trim_string(&self->fCurrentFontInfo->fFileName); | 217 trim_string(&self->fCurrentFontInfo->fFileName); |
| 218 }, | 218 }, |
| 219 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 219 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 220 size_t len = strlen(tag); | 220 size_t len = strlen(tag); |
| 221 if (MEMEQ("axis", tag, len)) { | 221 if (MEMEQ("axis", tag, len)) { |
| 222 return &axisHandler; | 222 return &axisHandler; |
| 223 } | 223 } |
| 224 return NULL; | 224 return nullptr; |
| 225 }, | 225 }, |
| 226 /*chars*/[](void* data, const char* s, int len) { | 226 /*chars*/[](void* data, const char* s, int len) { |
| 227 FamilyData* self = static_cast<FamilyData*>(data); | 227 FamilyData* self = static_cast<FamilyData*>(data); |
| 228 self->fCurrentFontInfo->fFileName.append(s, len); | 228 self->fCurrentFontInfo->fFileName.append(s, len); |
| 229 } | 229 } |
| 230 }; | 230 }; |
| 231 | 231 |
| 232 static const TagHandler familyHandler = { | 232 static const TagHandler familyHandler = { |
| 233 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { | 233 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { |
| 234 // 'name' (string) [optional] | 234 // 'name' (string) [optional] |
| (...skipping 23 matching lines...) Expand all Loading... |
| 258 } | 258 } |
| 259 }, | 259 }, |
| 260 /*end*/[](FamilyData* self, const char* tag) { | 260 /*end*/[](FamilyData* self, const char* tag) { |
| 261 *self->fFamilies.append() = self->fCurrentFamily.detach(); | 261 *self->fFamilies.append() = self->fCurrentFamily.detach(); |
| 262 }, | 262 }, |
| 263 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 263 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 264 size_t len = strlen(tag); | 264 size_t len = strlen(tag); |
| 265 if (MEMEQ("font", tag, len)) { | 265 if (MEMEQ("font", tag, len)) { |
| 266 return &fontHandler; | 266 return &fontHandler; |
| 267 } | 267 } |
| 268 return NULL; | 268 return nullptr; |
| 269 }, | 269 }, |
| 270 /*chars*/NULL, | 270 /*chars*/nullptr, |
| 271 }; | 271 }; |
| 272 | 272 |
| 273 static FontFamily* find_family(FamilyData* self, const SkString& familyName) { | 273 static FontFamily* find_family(FamilyData* self, const SkString& familyName) { |
| 274 for (int i = 0; i < self->fFamilies.count(); i++) { | 274 for (int i = 0; i < self->fFamilies.count(); i++) { |
| 275 FontFamily* candidate = self->fFamilies[i]; | 275 FontFamily* candidate = self->fFamilies[i]; |
| 276 for (int j = 0; j < candidate->fNames.count(); j++) { | 276 for (int j = 0; j < candidate->fNames.count(); j++) { |
| 277 if (candidate->fNames[j] == familyName) { | 277 if (candidate->fNames[j] == familyName) { |
| 278 return candidate; | 278 return candidate; |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 } | 281 } |
| 282 return NULL; | 282 return nullptr; |
| 283 } | 283 } |
| 284 | 284 |
| 285 static const TagHandler aliasHandler = { | 285 static const TagHandler aliasHandler = { |
| 286 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { | 286 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { |
| 287 // 'name' (string) introduces a new family name. | 287 // 'name' (string) introduces a new family name. |
| 288 // 'to' (string) specifies which (previous) family to alias | 288 // 'to' (string) specifies which (previous) family to alias |
| 289 // 'weight' (non-negative integer) [optional] | 289 // 'weight' (non-negative integer) [optional] |
| 290 // If it *does not* have a weight, 'name' is an alias for the entire 'to
' family. | 290 // If it *does not* have a weight, 'name' is an alias for the entire 'to
' family. |
| 291 // If it *does* have a weight, 'name' is a new family consisting of | 291 // If it *does* have a weight, 'name' is a new family consisting of |
| 292 // the font(s) with 'weight' from the 'to' family. | 292 // the font(s) with 'weight' from the 'to' family. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 for (int i = 0; i < targetFamily->fFonts.count(); i++) { | 324 for (int i = 0; i < targetFamily->fFonts.count(); i++) { |
| 325 if (targetFamily->fFonts[i].fWeight == weight) { | 325 if (targetFamily->fFonts[i].fWeight == weight) { |
| 326 family->fFonts.push_back(targetFamily->fFonts[i]); | 326 family->fFonts.push_back(targetFamily->fFonts[i]); |
| 327 } | 327 } |
| 328 } | 328 } |
| 329 *self->fFamilies.append() = family; | 329 *self->fFamilies.append() = family; |
| 330 } else { | 330 } else { |
| 331 targetFamily->fNames.push_back().set(aliasName); | 331 targetFamily->fNames.push_back().set(aliasName); |
| 332 } | 332 } |
| 333 }, | 333 }, |
| 334 /*end*/NULL, | 334 /*end*/nullptr, |
| 335 /*tag*/NULL, | 335 /*tag*/nullptr, |
| 336 /*chars*/NULL, | 336 /*chars*/nullptr, |
| 337 }; | 337 }; |
| 338 | 338 |
| 339 static const TagHandler familySetHandler = { | 339 static const TagHandler familySetHandler = { |
| 340 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { }, | 340 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { }, |
| 341 /*end*/NULL, | 341 /*end*/nullptr, |
| 342 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 342 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 343 size_t len = strlen(tag); | 343 size_t len = strlen(tag); |
| 344 if (MEMEQ("family", tag, len)) { | 344 if (MEMEQ("family", tag, len)) { |
| 345 return &familyHandler; | 345 return &familyHandler; |
| 346 } else if (MEMEQ("alias", tag, len)) { | 346 } else if (MEMEQ("alias", tag, len)) { |
| 347 return &aliasHandler; | 347 return &aliasHandler; |
| 348 } | 348 } |
| 349 return NULL; | 349 return nullptr; |
| 350 }, | 350 }, |
| 351 /*chars*/NULL, | 351 /*chars*/nullptr, |
| 352 }; | 352 }; |
| 353 | 353 |
| 354 } // lmpParser | 354 } // lmpParser |
| 355 | 355 |
| 356 namespace jbParser { | 356 namespace jbParser { |
| 357 | 357 |
| 358 static const TagHandler fileHandler = { | 358 static const TagHandler fileHandler = { |
| 359 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { | 359 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { |
| 360 // 'variant' ("elegant", "compact") [default "default"] | 360 // 'variant' ("elegant", "compact") [default "default"] |
| 361 // 'lang' (string) [default ""] | 361 // 'lang' (string) [default ""] |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 393 |
| 394 } else if (MEMEQ("index", name, nameLen)) { | 394 } else if (MEMEQ("index", name, nameLen)) { |
| 395 if (!parse_non_negative_integer(value, &newFileInfo.fIndex))
{ | 395 if (!parse_non_negative_integer(value, &newFileInfo.fIndex))
{ |
| 396 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid index",
value); | 396 SK_FONTCONFIGPARSER_WARNING("'%s' is an invalid index",
value); |
| 397 } | 397 } |
| 398 } | 398 } |
| 399 } | 399 } |
| 400 } | 400 } |
| 401 self->fCurrentFontInfo = &newFileInfo; | 401 self->fCurrentFontInfo = &newFileInfo; |
| 402 }, | 402 }, |
| 403 /*end*/NULL, | 403 /*end*/nullptr, |
| 404 /*tag*/NULL, | 404 /*tag*/nullptr, |
| 405 /*chars*/[](void* data, const char* s, int len) { | 405 /*chars*/[](void* data, const char* s, int len) { |
| 406 FamilyData* self = static_cast<FamilyData*>(data); | 406 FamilyData* self = static_cast<FamilyData*>(data); |
| 407 self->fCurrentFontInfo->fFileName.append(s, len); | 407 self->fCurrentFontInfo->fFileName.append(s, len); |
| 408 } | 408 } |
| 409 }; | 409 }; |
| 410 | 410 |
| 411 static const TagHandler fileSetHandler = { | 411 static const TagHandler fileSetHandler = { |
| 412 /*start*/NULL, | 412 /*start*/nullptr, |
| 413 /*end*/NULL, | 413 /*end*/nullptr, |
| 414 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 414 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 415 size_t len = strlen(tag); | 415 size_t len = strlen(tag); |
| 416 if (MEMEQ("file", tag, len)) { | 416 if (MEMEQ("file", tag, len)) { |
| 417 return &fileHandler; | 417 return &fileHandler; |
| 418 } | 418 } |
| 419 return NULL; | 419 return nullptr; |
| 420 }, | 420 }, |
| 421 /*chars*/NULL, | 421 /*chars*/nullptr, |
| 422 }; | 422 }; |
| 423 | 423 |
| 424 static const TagHandler nameHandler = { | 424 static const TagHandler nameHandler = { |
| 425 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { | 425 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { |
| 426 // The character data should be a name for the font. | 426 // The character data should be a name for the font. |
| 427 self->fCurrentFamily->fNames.push_back(); | 427 self->fCurrentFamily->fNames.push_back(); |
| 428 }, | 428 }, |
| 429 /*end*/NULL, | 429 /*end*/nullptr, |
| 430 /*tag*/NULL, | 430 /*tag*/nullptr, |
| 431 /*chars*/[](void* data, const char* s, int len) { | 431 /*chars*/[](void* data, const char* s, int len) { |
| 432 FamilyData* self = static_cast<FamilyData*>(data); | 432 FamilyData* self = static_cast<FamilyData*>(data); |
| 433 SkAutoAsciiToLC tolc(s, len); | 433 SkAutoAsciiToLC tolc(s, len); |
| 434 self->fCurrentFamily->fNames.back().append(tolc.lc(), len); | 434 self->fCurrentFamily->fNames.back().append(tolc.lc(), len); |
| 435 } | 435 } |
| 436 }; | 436 }; |
| 437 | 437 |
| 438 static const TagHandler nameSetHandler = { | 438 static const TagHandler nameSetHandler = { |
| 439 /*start*/NULL, | 439 /*start*/nullptr, |
| 440 /*end*/NULL, | 440 /*end*/nullptr, |
| 441 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 441 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 442 size_t len = strlen(tag); | 442 size_t len = strlen(tag); |
| 443 if (MEMEQ("name", tag, len)) { | 443 if (MEMEQ("name", tag, len)) { |
| 444 return &nameHandler; | 444 return &nameHandler; |
| 445 } | 445 } |
| 446 return NULL; | 446 return nullptr; |
| 447 }, | 447 }, |
| 448 /*chars*/NULL, | 448 /*chars*/nullptr, |
| 449 }; | 449 }; |
| 450 | 450 |
| 451 static const TagHandler familyHandler = { | 451 static const TagHandler familyHandler = { |
| 452 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { | 452 /*start*/[](FamilyData* self, const char* tag, const char** attributes) { |
| 453 self->fCurrentFamily.reset(new FontFamily(self->fBasePath, self->fIsFall
back)); | 453 self->fCurrentFamily.reset(new FontFamily(self->fBasePath, self->fIsFall
back)); |
| 454 // 'order' (non-negative integer) [default -1] | 454 // 'order' (non-negative integer) [default -1] |
| 455 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { | 455 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { |
| 456 const char* value = attributes[i+1]; | 456 const char* value = attributes[i+1]; |
| 457 parse_non_negative_integer(value, &self->fCurrentFamily->fOrder); | 457 parse_non_negative_integer(value, &self->fCurrentFamily->fOrder); |
| 458 } | 458 } |
| 459 }, | 459 }, |
| 460 /*end*/[](FamilyData* self, const char* tag) { | 460 /*end*/[](FamilyData* self, const char* tag) { |
| 461 *self->fFamilies.append() = self->fCurrentFamily.detach(); | 461 *self->fFamilies.append() = self->fCurrentFamily.detach(); |
| 462 }, | 462 }, |
| 463 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 463 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 464 size_t len = strlen(tag); | 464 size_t len = strlen(tag); |
| 465 if (MEMEQ("nameset", tag, len)) { | 465 if (MEMEQ("nameset", tag, len)) { |
| 466 return &nameSetHandler; | 466 return &nameSetHandler; |
| 467 } else if (MEMEQ("fileset", tag, len)) { | 467 } else if (MEMEQ("fileset", tag, len)) { |
| 468 return &fileSetHandler; | 468 return &fileSetHandler; |
| 469 } | 469 } |
| 470 return NULL; | 470 return nullptr; |
| 471 }, | 471 }, |
| 472 /*chars*/NULL, | 472 /*chars*/nullptr, |
| 473 }; | 473 }; |
| 474 | 474 |
| 475 static const TagHandler familySetHandler = { | 475 static const TagHandler familySetHandler = { |
| 476 /*start*/NULL, | 476 /*start*/nullptr, |
| 477 /*end*/NULL, | 477 /*end*/nullptr, |
| 478 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 478 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 479 size_t len = strlen(tag); | 479 size_t len = strlen(tag); |
| 480 if (MEMEQ("family", tag, len)) { | 480 if (MEMEQ("family", tag, len)) { |
| 481 return &familyHandler; | 481 return &familyHandler; |
| 482 } | 482 } |
| 483 return NULL; | 483 return nullptr; |
| 484 }, | 484 }, |
| 485 /*chars*/NULL, | 485 /*chars*/nullptr, |
| 486 }; | 486 }; |
| 487 | 487 |
| 488 } // namespace jbParser | 488 } // namespace jbParser |
| 489 | 489 |
| 490 static const TagHandler topLevelHandler = { | 490 static const TagHandler topLevelHandler = { |
| 491 /*start*/NULL, | 491 /*start*/nullptr, |
| 492 /*end*/NULL, | 492 /*end*/nullptr, |
| 493 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { | 493 /*tag*/[](FamilyData* self, const char* tag, const char** attributes) -> con
st TagHandler* { |
| 494 size_t len = strlen(tag); | 494 size_t len = strlen(tag); |
| 495 if (MEMEQ("familyset", tag, len)) { | 495 if (MEMEQ("familyset", tag, len)) { |
| 496 // 'version' (non-negative integer) [default 0] | 496 // 'version' (non-negative integer) [default 0] |
| 497 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { | 497 for (size_t i = 0; ATTS_NON_NULL(attributes, i); i += 2) { |
| 498 const char* name = attributes[i]; | 498 const char* name = attributes[i]; |
| 499 size_t nameLen = strlen(name); | 499 size_t nameLen = strlen(name); |
| 500 if (MEMEQ("version", name, nameLen)) { | 500 if (MEMEQ("version", name, nameLen)) { |
| 501 const char* value = attributes[i+1]; | 501 const char* value = attributes[i+1]; |
| 502 if (parse_non_negative_integer(value, &self->fVersion)) { | 502 if (parse_non_negative_integer(value, &self->fVersion)) { |
| 503 if (self->fVersion >= 21) { | 503 if (self->fVersion >= 21) { |
| 504 return &lmpParser::familySetHandler; | 504 return &lmpParser::familySetHandler; |
| 505 } | 505 } |
| 506 } | 506 } |
| 507 } | 507 } |
| 508 } | 508 } |
| 509 return &jbParser::familySetHandler; | 509 return &jbParser::familySetHandler; |
| 510 } | 510 } |
| 511 return NULL; | 511 return nullptr; |
| 512 }, | 512 }, |
| 513 /*chars*/NULL, | 513 /*chars*/nullptr, |
| 514 }; | 514 }; |
| 515 | 515 |
| 516 static void XMLCALL start_element_handler(void *data, const char *tag, const cha
r **attributes) { | 516 static void XMLCALL start_element_handler(void *data, const char *tag, const cha
r **attributes) { |
| 517 FamilyData* self = static_cast<FamilyData*>(data); | 517 FamilyData* self = static_cast<FamilyData*>(data); |
| 518 | 518 |
| 519 if (!self->fSkip) { | 519 if (!self->fSkip) { |
| 520 const TagHandler* parent = self->fHandler.top(); | 520 const TagHandler* parent = self->fHandler.top(); |
| 521 const TagHandler* child = parent->tag ? parent->tag(self, tag, attribute
s) : NULL; | 521 const TagHandler* child = parent->tag ? parent->tag(self, tag, attribute
s) : nullptr; |
| 522 if (child) { | 522 if (child) { |
| 523 if (child->start) { | 523 if (child->start) { |
| 524 child->start(self, tag, attributes); | 524 child->start(self, tag, attributes); |
| 525 } | 525 } |
| 526 self->fHandler.push(child); | 526 self->fHandler.push(child); |
| 527 XML_SetCharacterDataHandler(self->fParser, child->chars); | 527 XML_SetCharacterDataHandler(self->fParser, child->chars); |
| 528 } else { | 528 } else { |
| 529 SK_FONTCONFIGPARSER_WARNING("'%s' tag not recognized, skipping", tag
); | 529 SK_FONTCONFIGPARSER_WARNING("'%s' tag not recognized, skipping", tag
); |
| 530 XML_SetCharacterDataHandler(self->fParser, NULL); | 530 XML_SetCharacterDataHandler(self->fParser, nullptr); |
| 531 self->fSkip = self->fDepth; | 531 self->fSkip = self->fDepth; |
| 532 } | 532 } |
| 533 } | 533 } |
| 534 | 534 |
| 535 ++self->fDepth; | 535 ++self->fDepth; |
| 536 } | 536 } |
| 537 | 537 |
| 538 static void XMLCALL end_element_handler(void* data, const char* tag) { | 538 static void XMLCALL end_element_handler(void* data, const char* tag) { |
| 539 FamilyData* self = static_cast<FamilyData*>(data); | 539 FamilyData* self = static_cast<FamilyData*>(data); |
| 540 --self->fDepth; | 540 --self->fDepth; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 SkFILEStream file(filename); | 590 SkFILEStream file(filename); |
| 591 | 591 |
| 592 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac
k_fonts.xml) | 592 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac
k_fonts.xml) |
| 593 // are optional - failure here is okay because one of these optional files m
ay not exist. | 593 // are optional - failure here is okay because one of these optional files m
ay not exist. |
| 594 if (!file.isValid()) { | 594 if (!file.isValid()) { |
| 595 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' could not be opened\n",
filename); | 595 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' could not be opened\n",
filename); |
| 596 return -1; | 596 return -1; |
| 597 } | 597 } |
| 598 | 598 |
| 599 SkAutoTCallVProc<remove_ptr<XML_Parser>::type, XML_ParserFree> parser( | 599 SkAutoTCallVProc<remove_ptr<XML_Parser>::type, XML_ParserFree> parser( |
| 600 XML_ParserCreate_MM(NULL, &sk_XML_alloc, NULL)); | 600 XML_ParserCreate_MM(nullptr, &sk_XML_alloc, nullptr)); |
| 601 if (!parser) { | 601 if (!parser) { |
| 602 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "could not create XML parser\n
"); | 602 SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "could not create XML parser\n
"); |
| 603 return -1; | 603 return -1; |
| 604 } | 604 } |
| 605 | 605 |
| 606 FamilyData self(parser, families, basePath, isFallback, filename, &topLevelH
andler); | 606 FamilyData self(parser, families, basePath, isFallback, filename, &topLevelH
andler); |
| 607 XML_SetUserData(parser, &self); | 607 XML_SetUserData(parser, &self); |
| 608 | 608 |
| 609 // Disable entity processing, to inhibit internal entity expansion. See expa
t CVE-2013-0340 | 609 // Disable entity processing, to inhibit internal entity expansion. See expa
t CVE-2013-0340 |
| 610 XML_SetEntityDeclHandler(parser, xml_entity_decl_handler); | 610 XML_SetEntityDeclHandler(parser, xml_entity_decl_handler); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 static void append_fallback_font_families_for_locale(SkTDArray<FontFamily*>& fal
lbackFonts, | 662 static void append_fallback_font_families_for_locale(SkTDArray<FontFamily*>& fal
lbackFonts, |
| 663 const char* dir, | 663 const char* dir, |
| 664 const SkString& basePath) | 664 const SkString& basePath) |
| 665 { | 665 { |
| 666 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) | 666 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) |
| 667 // The framework is beyond Android 4.2 and can therefore skip this function | 667 // The framework is beyond Android 4.2 and can therefore skip this function |
| 668 return; | 668 return; |
| 669 #endif | 669 #endif |
| 670 | 670 |
| 671 SkAutoTCallIProc<DIR, closedir> fontDirectory(opendir(dir)); | 671 SkAutoTCallIProc<DIR, closedir> fontDirectory(opendir(dir)); |
| 672 if (NULL == fontDirectory) { | 672 if (nullptr == fontDirectory) { |
| 673 return; | 673 return; |
| 674 } | 674 } |
| 675 | 675 |
| 676 for (struct dirent* dirEntry; (dirEntry = readdir(fontDirectory));) { | 676 for (struct dirent* dirEntry; (dirEntry = readdir(fontDirectory));) { |
| 677 // The size of the prefix and suffix. | 677 // The size of the prefix and suffix. |
| 678 static const size_t fixedLen = sizeof(LOCALE_FALLBACK_FONTS_PREFIX) - 1 | 678 static const size_t fixedLen = sizeof(LOCALE_FALLBACK_FONTS_PREFIX) - 1 |
| 679 + sizeof(LOCALE_FALLBACK_FONTS_SUFFIX) - 1; | 679 + sizeof(LOCALE_FALLBACK_FONTS_SUFFIX) - 1; |
| 680 | 680 |
| 681 // The size of the prefix, suffix, and a minimum valid language code | 681 // The size of the prefix, suffix, and a minimum valid language code |
| 682 static const size_t minSize = fixedLen + 2; | 682 static const size_t minSize = fixedLen + 2; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 basePath); | 782 basePath); |
| 783 } | 783 } |
| 784 } | 784 } |
| 785 | 785 |
| 786 SkLanguage SkLanguage::getParent() const { | 786 SkLanguage SkLanguage::getParent() const { |
| 787 SkASSERT(!fTag.isEmpty()); | 787 SkASSERT(!fTag.isEmpty()); |
| 788 const char* tag = fTag.c_str(); | 788 const char* tag = fTag.c_str(); |
| 789 | 789 |
| 790 // strip off the rightmost "-.*" | 790 // strip off the rightmost "-.*" |
| 791 const char* parentTagEnd = strrchr(tag, '-'); | 791 const char* parentTagEnd = strrchr(tag, '-'); |
| 792 if (parentTagEnd == NULL) { | 792 if (parentTagEnd == nullptr) { |
| 793 return SkLanguage(); | 793 return SkLanguage(); |
| 794 } | 794 } |
| 795 size_t parentTagLen = parentTagEnd - tag; | 795 size_t parentTagLen = parentTagEnd - tag; |
| 796 return SkLanguage(tag, parentTagLen); | 796 return SkLanguage(tag, parentTagLen); |
| 797 } | 797 } |
| OLD | NEW |