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

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

Issue 889943005: Do not leak FamilyData in Android SkFontMgr. (Closed) Base URL: https://skia.googlesource.com/skia.git@android2
Patch Set: Created 5 years, 10 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 "SkTDArray.h" 9 #include "SkTDArray.h"
10 #include "SkTSearch.h" 10 #include "SkTSearch.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 * can read these variables that are relevant to the current parsing. 51 * can read these variables that are relevant to the current parsing.
52 */ 52 */
53 struct FamilyData { 53 struct FamilyData {
54 FamilyData(XML_Parser parserRef, SkTDArray<FontFamily*> &familiesRef) : 54 FamilyData(XML_Parser parserRef, SkTDArray<FontFamily*> &familiesRef) :
55 parser(parserRef), 55 parser(parserRef),
56 families(familiesRef), 56 families(familiesRef),
57 currentFamily(NULL), 57 currentFamily(NULL),
58 currentFontInfo(NULL), 58 currentFontInfo(NULL),
59 currentTag(NO_TAG) {}; 59 currentTag(NO_TAG) {};
60 60
61 XML_Parser parser; // The expat parser doing the work, owned by caller 61 XML_Parser parser; // The expat parser doing the work, owned by caller
62 SkTDArray<FontFamily*>& families; // The array to append families, owned by caller 62 SkTDArray<FontFamily*>& families; // The array to append families, ow ned by caller
mtklein 2015/01/30 23:07:41 Who cleans up things we add here?
bungeman-skia 2015/01/30 23:14:56 This is completely owned by the caller (this is th
63 FontFamily* currentFamily; // The current family being created, owne d by this 63 SkAutoTDelete<FontFamily> currentFamily; // The family being created, owned by this
mtklein 2015/01/30 23:07:41 So, uh.... we were just never deleting this? I ca
bungeman-skia 2015/01/30 23:14:56 This is the 'working' FontFamily. When we finish b
64 FontFileInfo* currentFontInfo; // The current fontInfo being created, ow ned by currentFamily 64 FontFileInfo* currentFontInfo; // The fontInfo being created, owne d by currentFamily
65 int currentTag; // A flag to indicate whether we're in na meset/fileset tags 65 int currentTag; // Flag to indicate when we're in n ameset/fileset tags
66 }; 66 };
67 67
68 /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def */ 68 /** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-nega tive-def */
69 template <typename T> static bool parseNonNegativeInteger(const char* s, T* valu e) { 69 template <typename T> static bool parseNonNegativeInteger(const char* s, T* valu e) {
70 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer); 70 SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer);
71 const T nMax = std::numeric_limits<T>::max() / 10; 71 const T nMax = std::numeric_limits<T>::max() / 10;
72 const T dMax = std::numeric_limits<T>::max() - (nMax * 10); 72 const T dMax = std::numeric_limits<T>::max() - (nMax * 10);
73 T n = 0; 73 T n = 0;
74 for (; *s; ++s) { 74 for (; *s; ++s) {
75 // Check if digit 75 // Check if digit
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 182 }
183 183
184 // Assumes that the named family is already declared 184 // Assumes that the named family is already declared
185 FontFamily* targetFamily = findFamily(familyData, to.c_str()); 185 FontFamily* targetFamily = findFamily(familyData, to.c_str());
186 if (!targetFamily) { 186 if (!targetFamily) {
187 SkDebugf("---- Font alias target %s (NOT FOUND)", to.c_str()); 187 SkDebugf("---- Font alias target %s (NOT FOUND)", to.c_str());
188 return; 188 return;
189 } 189 }
190 190
191 if (weight) { 191 if (weight) {
192 FontFamily* family = new FontFamily(); 192 FontFamily* family = new FontFamily();
mtklein 2015/01/30 23:07:41 E.g. I'm curious who calls delete on this family.
bungeman-skia 2015/01/30 23:14:56 This is added to the set of families being appende
193 family->fNames.push_back().set(aliasName); 193 family->fNames.push_back().set(aliasName);
194 194
195 for (int i = 0; i < targetFamily->fFonts.count(); i++) { 195 for (int i = 0; i < targetFamily->fFonts.count(); i++) {
196 if (targetFamily->fFonts[i].fWeight == weight) { 196 if (targetFamily->fFonts[i].fWeight == weight) {
197 family->fFonts.push_back(targetFamily->fFonts[i]); 197 family->fFonts.push_back(targetFamily->fFonts[i]);
198 } 198 }
199 } 199 }
200 *familyData->families.append() = family; 200 *familyData->families.append() = family;
201 } else { 201 } else {
202 targetFamily->fNames.push_back().set(aliasName); 202 targetFamily->fNames.push_back().set(aliasName);
203 } 203 }
204 } 204 }
205 205
206 void startElementHandler(void* data, const char* tag, const char** attributes) { 206 void startElementHandler(void* data, const char* tag, const char** attributes) {
207 FamilyData* familyData = (FamilyData*) data; 207 FamilyData* familyData = (FamilyData*) data;
208 size_t len = strlen(tag); 208 size_t len = strlen(tag);
209 if (len == 6 && !strncmp(tag, "family", len)) { 209 if (len == 6 && !strncmp(tag, "family", len)) {
210 familyData->currentFamily = new FontFamily(); 210 familyData->currentFamily.reset(new FontFamily());
211 familyElementHandler(familyData->currentFamily, attributes); 211 familyElementHandler(familyData->currentFamily, attributes);
212 } else if (len == 4 && !strncmp(tag, "font", len)) { 212 } else if (len == 4 && !strncmp(tag, "font", len)) {
213 FontFileInfo* file = &familyData->currentFamily->fFonts.push_back(); 213 FontFileInfo* file = &familyData->currentFamily->fFonts.push_back();
214 familyData->currentFontInfo = file; 214 familyData->currentFontInfo = file;
215 fontElementHandler(familyData->parser, file, attributes); 215 fontElementHandler(familyData->parser, file, attributes);
216 } else if (len == 5 && !strncmp(tag, "alias", len)) { 216 } else if (len == 5 && !strncmp(tag, "alias", len)) {
217 aliasElementHandler(familyData, attributes); 217 aliasElementHandler(familyData, attributes);
218 } 218 }
219 } 219 }
220 220
221 void endElementHandler(void* data, const char* tag) { 221 void endElementHandler(void* data, const char* tag) {
222 FamilyData* familyData = (FamilyData*) data; 222 FamilyData* familyData = (FamilyData*) data;
223 size_t len = strlen(tag); 223 size_t len = strlen(tag);
224 if (len == 6 && strncmp(tag, "family", len) == 0) { 224 if (len == 6 && strncmp(tag, "family", len) == 0) {
225 *familyData->families.append() = familyData->currentFamily; 225 *familyData->families.append() = familyData->currentFamily.detach();
226 familyData->currentFamily = NULL;
227 } else if (len == 4 && !strncmp(tag, "font", len)) { 226 } else if (len == 4 && !strncmp(tag, "font", len)) {
228 XML_SetCharacterDataHandler(familyData->parser, NULL); 227 XML_SetCharacterDataHandler(familyData->parser, NULL);
229 } 228 }
230 } 229 }
231 230
232 } // lmpParser 231 } // lmpParser
233 232
234 namespace jbParser { 233 namespace jbParser {
235 234
236 /** 235 /**
237 * Handler for arbitrary text. This is used to parse the text inside each name 236 * Handler for arbitrary text. This is used to parse the text inside each name
238 * or file tag. The resulting strings are put into the fNames or FontFileInfo ar rays. 237 * or file tag. The resulting strings are put into the fNames or FontFileInfo ar rays.
239 */ 238 */
240 static void textHandler(void* data, const char* s, int len) { 239 static void textHandler(void* data, const char* s, int len) {
241 FamilyData* familyData = (FamilyData*) data; 240 FamilyData* familyData = (FamilyData*) data;
242 // Make sure we're in the right state to store this name information 241 // Make sure we're in the right state to store this name information
243 if (familyData->currentFamily && 242 if (familyData->currentFamily.get() &&
244 (familyData->currentTag == NAMESET_TAG || familyData->currentTag == FILESET_TAG)) { 243 (familyData->currentTag == NAMESET_TAG || familyData->currentTag == FILESET_TAG)) {
245 switch (familyData->currentTag) { 244 switch (familyData->currentTag) {
246 case NAMESET_TAG: { 245 case NAMESET_TAG: {
247 SkAutoAsciiToLC tolc(s, len); 246 SkAutoAsciiToLC tolc(s, len);
248 familyData->currentFamily->fNames.push_back().set(tolc.lc(), len); 247 familyData->currentFamily->fNames.push_back().set(tolc.lc(), len);
249 break; 248 break;
250 } 249 }
251 case FILESET_TAG: 250 case FILESET_TAG:
252 if (familyData->currentFontInfo) { 251 if (familyData->currentFontInfo) {
253 familyData->currentFontInfo->fFileName.set(s, len); 252 familyData->currentFontInfo->fFileName.set(s, len);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue; 326 if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue;
328 const char* valueString = atts[i+1]; 327 const char* valueString = atts[i+1];
329 int version; 328 int version;
330 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) { 329 if (parseNonNegativeInteger(valueString, &version) && (version >= 21 )) {
331 XML_SetElementHandler(familyData->parser, 330 XML_SetElementHandler(familyData->parser,
332 lmpParser::startElementHandler, 331 lmpParser::startElementHandler,
333 lmpParser::endElementHandler); 332 lmpParser::endElementHandler);
334 } 333 }
335 } 334 }
336 } else if (len == 6 && strncmp(tag, "family", len) == 0) { 335 } else if (len == 6 && strncmp(tag, "family", len) == 0) {
337 familyData->currentFamily = new FontFamily(); 336 familyData->currentFamily.reset(new FontFamily());
338 // The Family tag has an optional "order" attribute with an integer valu e >= 0 337 // The Family tag has an optional "order" attribute with an integer valu e >= 0
339 // If this attribute does not exist, the default value is -1 338 // If this attribute does not exist, the default value is -1
340 for (size_t i = 0; atts[i] != NULL && 339 for (size_t i = 0; atts[i] != NULL &&
341 atts[i+1] != NULL; i += 2) { 340 atts[i+1] != NULL; i += 2) {
342 const char* valueString = atts[i+1]; 341 const char* valueString = atts[i+1];
343 int value; 342 int value;
344 if (parseNonNegativeInteger(valueString, &value)) { 343 if (parseNonNegativeInteger(valueString, &value)) {
345 familyData->currentFamily->fOrder = value; 344 familyData->currentFamily->fOrder = value;
346 } 345 }
347 } 346 }
(...skipping 12 matching lines...) Expand all
360 359
361 /** 360 /**
362 * Handler for the end of tags. We only care about family, nameset, fileset, 361 * Handler for the end of tags. We only care about family, nameset, fileset,
363 * name, and file. 362 * name, and file.
364 */ 363 */
365 static void endElementHandler(void* data, const char* tag) { 364 static void endElementHandler(void* data, const char* tag) {
366 FamilyData* familyData = (FamilyData*) data; 365 FamilyData* familyData = (FamilyData*) data;
367 size_t len = strlen(tag); 366 size_t len = strlen(tag);
368 if (len == 6 && strncmp(tag, "family", len)== 0) { 367 if (len == 6 && strncmp(tag, "family", len)== 0) {
369 // Done parsing a Family - store the created currentFamily in the famili es array 368 // Done parsing a Family - store the created currentFamily in the famili es array
370 *familyData->families.append() = familyData->currentFamily; 369 *familyData->families.append() = familyData->currentFamily.detach();
371 familyData->currentFamily = NULL;
372 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) { 370 } else if (len == 7 && strncmp(tag, "nameset", len) == 0) {
373 familyData->currentTag = NO_TAG; 371 familyData->currentTag = NO_TAG;
374 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) { 372 } else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
375 familyData->currentTag = NO_TAG; 373 familyData->currentTag = NO_TAG;
376 } else if ((len == 4 && 374 } else if ((len == 4 &&
377 strncmp(tag, "name", len) == 0 && 375 strncmp(tag, "name", len) == 0 &&
378 familyData->currentTag == NAMESET_TAG) || 376 familyData->currentTag == NAMESET_TAG) ||
379 (len == 4 && 377 (len == 4 &&
380 strncmp(tag, "file", len) == 0 && 378 strncmp(tag, "file", len) == 0 &&
381 familyData->currentTag == FILESET_TAG)) { 379 familyData->currentTag == FILESET_TAG)) {
(...skipping 12 matching lines...) Expand all
394 392
395 FILE* file = fopen(filename, "r"); 393 FILE* file = fopen(filename, "r");
396 394
397 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml) 395 // Some of the files we attempt to parse (in particular, /vendor/etc/fallbac k_fonts.xml)
398 // are optional - failure here is okay because one of these optional files m ay not exist. 396 // are optional - failure here is okay because one of these optional files m ay not exist.
399 if (NULL == file) { 397 if (NULL == file) {
400 return; 398 return;
401 } 399 }
402 400
403 XML_Parser parser = XML_ParserCreate(NULL); 401 XML_Parser parser = XML_ParserCreate(NULL);
404 FamilyData* familyData = new FamilyData(parser, families); 402 FamilyData familyData(parser, families);
405 XML_SetUserData(parser, familyData); 403 XML_SetUserData(parser, &familyData);
406 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file. 404 // Start parsing oldschool; switch these in flight if we detect a newer vers ion of the file.
407 XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endEl ementHandler); 405 XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endEl ementHandler);
408 406
409 char buffer[512]; 407 char buffer[512];
410 bool done = false; 408 bool done = false;
411 while (!done) { 409 while (!done) {
412 fgets(buffer, sizeof(buffer), file); 410 fgets(buffer, sizeof(buffer), file);
413 size_t len = strlen(buffer); 411 size_t len = strlen(buffer);
414 if (feof(file) != 0) { 412 if (feof(file) != 0) {
415 done = true; 413 done = true;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 const char* tag = fTag.c_str(); 552 const char* tag = fTag.c_str();
555 553
556 // strip off the rightmost "-.*" 554 // strip off the rightmost "-.*"
557 const char* parentTagEnd = strrchr(tag, '-'); 555 const char* parentTagEnd = strrchr(tag, '-');
558 if (parentTagEnd == NULL) { 556 if (parentTagEnd == NULL) {
559 return SkLanguage(); 557 return SkLanguage();
560 } 558 }
561 size_t parentTagLen = parentTagEnd - tag; 559 size_t parentTagLen = parentTagEnd - tag;
562 return SkLanguage(tag, parentTagLen); 560 return SkLanguage(tag, parentTagLen);
563 } 561 }
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