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

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

Issue 13956032: start cleanup, in prep for new fontmgr impl (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 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 | Annotate | Revision Log
« 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 2009 Google Inc. 2 * Copyright 2009 Google Inc.
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 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */ 8 /* migrated from chrome/src/skia/ext/SkFontHost_fontconfig_direct.cpp */
9 9
10 #include <string> 10 #include <string>
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 int SkFontConfigInterface::matchFamilySet(const char familyName[], 58 int SkFontConfigInterface::matchFamilySet(const char familyName[],
59 SkString* outFamilyName, 59 SkString* outFamilyName,
60 FontIdentity outIdentities[], 60 FontIdentity outIdentities[],
61 int maxCount) { 61 int maxCount) {
62 return 0; 62 return 0;
63 } 63 }
64 #endif 64 #endif
65 65
66 /////////////////////////////////////////////////////////////////////////////// 66 ///////////////////////////////////////////////////////////////////////////////
67 67
68 // Returns the string from the pattern, or NULL
69 static const char* get_name(FcPattern* pattern, const char field[],
70 int index = 0) {
71 const char* name;
72 if (FcPatternGetString(pattern, field, index,
73 (FcChar8**)&name) != FcResultMatch) {
74 name = NULL;
75 }
76 return name;
77 }
78
79 ///////////////////////////////////////////////////////////////////////////////
80
68 namespace { 81 namespace {
69 82
70 // Equivalence classes, used to match the Liberation and other fonts 83 // Equivalence classes, used to match the Liberation and other fonts
71 // with their metric-compatible replacements. See the discussion in 84 // with their metric-compatible replacements. See the discussion in
72 // GetFontEquivClass(). 85 // GetFontEquivClass().
73 enum FontEquivClass 86 enum FontEquivClass
74 { 87 {
75 OTHER, 88 OTHER,
76 SANS, 89 SANS,
77 SERIF, 90 SERIF,
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 // basic font names like "Sans", "Serif" or "Monospace". This function 244 // basic font names like "Sans", "Serif" or "Monospace". This function
232 // tells you whether a given request is for such a fallback. 245 // tells you whether a given request is for such a fallback.
233 bool IsFallbackFontAllowed(const std::string& family) { 246 bool IsFallbackFontAllowed(const std::string& family) {
234 const char* family_cstr = family.c_str(); 247 const char* family_cstr = family.c_str();
235 return family.empty() || 248 return family.empty() ||
236 strcasecmp(family_cstr, "sans") == 0 || 249 strcasecmp(family_cstr, "sans") == 0 ||
237 strcasecmp(family_cstr, "serif") == 0 || 250 strcasecmp(family_cstr, "serif") == 0 ||
238 strcasecmp(family_cstr, "monospace") == 0; 251 strcasecmp(family_cstr, "monospace") == 0;
239 } 252 }
240 253
254 static bool valid_pattern(FcPattern* pattern) {
255 FcBool is_scalable;
256 if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) != FcResultMatch
257 || !is_scalable) {
258 return false;
259 }
260
261 // fontconfig can also return fonts which are unreadable
262 const char* c_filename = get_name(pattern, FC_FILE);
263 if (!c_filename) {
264 return false;
265 }
266 if (access(c_filename, R_OK) != 0) {
267 return false;
268 }
269 return true;
270 }
271
241 // Find matching font from |font_set| for the given font family. 272 // Find matching font from |font_set| for the given font family.
242 FcPattern* MatchFont(FcFontSet* font_set, 273 FcPattern* MatchFont(FcFontSet* font_set,
243 FcChar8* post_config_family, 274 const char* post_config_family,
244 const std::string& family) { 275 const std::string& family) {
245 // Older versions of fontconfig have a bug where they cannot select 276 // Older versions of fontconfig have a bug where they cannot select
246 // only scalable fonts so we have to manually filter the results. 277 // only scalable fonts so we have to manually filter the results.
247 FcPattern* match = NULL; 278 FcPattern* match = NULL;
248 for (int i = 0; i < font_set->nfont; ++i) { 279 for (int i = 0; i < font_set->nfont; ++i) {
249 FcPattern* current = font_set->fonts[i]; 280 FcPattern* current = font_set->fonts[i];
250 FcBool is_scalable; 281 if (valid_pattern(current)) {
251 282 match = current;
252 if (FcPatternGetBool(current, FC_SCALABLE, 0, 283 break;
253 &is_scalable) != FcResultMatch ||
254 !is_scalable) {
255 continue;
256 } 284 }
257
258 // fontconfig can also return fonts which are unreadable
259 FcChar8* c_filename;
260 if (FcPatternGetString(current, FC_FILE, 0, &c_filename) != FcResultMatch)
261 continue;
262
263 if (access(reinterpret_cast<char*>(c_filename), R_OK) != 0)
264 continue;
265
266 match = current;
267 break;
268 } 285 }
269 286
270 if (match && !IsFallbackFontAllowed(family)) { 287 if (match && !IsFallbackFontAllowed(family)) {
271 bool acceptable_substitute = false; 288 bool acceptable_substitute = false;
272 for (int id = 0; id < 255; ++id) { 289 for (int id = 0; id < 255; ++id) {
273 FcChar8* post_match_family; 290 const char* post_match_family = get_name(match, FC_FAMILY, id);
274 if (FcPatternGetString(match, FC_FAMILY, id, &post_match_family) != 291 if (!post_match_family)
275 FcResultMatch)
276 break; 292 break;
277 acceptable_substitute = 293 acceptable_substitute =
278 (strcasecmp(reinterpret_cast<char*>(post_config_family), 294 (strcasecmp(post_config_family, post_match_family) == 0 ||
279 reinterpret_cast<char*>(post_match_family)) == 0 ||
280 // Workaround for Issue 12530: 295 // Workaround for Issue 12530:
281 // requested family: "Bitstream Vera Sans" 296 // requested family: "Bitstream Vera Sans"
282 // post_config_family: "Arial" 297 // post_config_family: "Arial"
283 // post_match_family: "Bitstream Vera Sans" 298 // post_match_family: "Bitstream Vera Sans"
284 // -> We should treat this case as a good match. 299 // -> We should treat this case as a good match.
285 strcasecmp(family.c_str(), 300 strcasecmp(family.c_str(), post_match_family) == 0) ||
286 reinterpret_cast<char*>(post_match_family)) == 0) || 301 IsMetricCompatibleReplacement(family.c_str(), post_match_family);
287 IsMetricCompatibleReplacement(family.c_str(),
288 reinterpret_cast<char*>(post_match_family));
289 if (acceptable_substitute) 302 if (acceptable_substitute)
290 break; 303 break;
291 } 304 }
292 if (!acceptable_substitute) 305 if (!acceptable_substitute)
293 return NULL; 306 return NULL;
294 } 307 }
295 308
296 return match; 309 return match;
297 } 310 }
298 311
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 // post_match_family: "Helvetica" 404 // post_match_family: "Helvetica"
392 // -> good match 405 // -> good match
393 // 406 //
394 // and for a missing font: 407 // and for a missing font:
395 // requested family: "Monaco" 408 // requested family: "Monaco"
396 // post_config_family: "Monaco" 409 // post_config_family: "Monaco"
397 // post_match_family: "Times New Roman" 410 // post_match_family: "Times New Roman"
398 // -> BAD match 411 // -> BAD match
399 // 412 //
400 // However, we special-case fallback fonts; see IsFallbackFontAllowed(). 413 // However, we special-case fallback fonts; see IsFallbackFontAllowed().
401 FcChar8* post_config_family; 414
402 FcPatternGetString(pattern, FC_FAMILY, 0, &post_config_family); 415 const char* post_config_family = get_name(pattern, FC_FAMILY);
416 if (!post_config_family) {
417 return false;
418 }
403 419
404 FcResult result; 420 FcResult result;
405 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result); 421 FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
406 if (!font_set) { 422 if (!font_set) {
407 FcPatternDestroy(pattern); 423 FcPatternDestroy(pattern);
408 return false; 424 return false;
409 } 425 }
410 426
411 FcPattern* match = MatchFont(font_set, post_config_family, familyStr); 427 FcPattern* match = MatchFont(font_set, post_config_family, familyStr);
412 if (!match) { 428 if (!match) {
413 FcPatternDestroy(pattern); 429 FcPatternDestroy(pattern);
414 FcFontSetDestroy(font_set); 430 FcFontSetDestroy(font_set);
415 return false; 431 return false;
416 } 432 }
417 433
418 FcPatternDestroy(pattern); 434 FcPatternDestroy(pattern);
419 435
420 // From here out we just extract our results from 'match' 436 // From here out we just extract our results from 'match'
421 437
422 if (FcPatternGetString(match, FC_FAMILY, 0, &post_config_family) != FcResult Match) { 438 post_config_family = get_name(match, FC_FAMILY);
439 if (!post_config_family) {
423 FcFontSetDestroy(font_set); 440 FcFontSetDestroy(font_set);
424 return false; 441 return false;
425 } 442 }
426 443
427 FcChar8* c_filename; 444 const char* c_filename = get_name(match, FC_FILE);
428 if (FcPatternGetString(match, FC_FILE, 0, &c_filename) != FcResultMatch) { 445 if (!c_filename) {
429 FcFontSetDestroy(font_set); 446 FcFontSetDestroy(font_set);
430 return false; 447 return false;
431 } 448 }
432 449
433 int face_index; 450 int face_index;
434 if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) { 451 if (FcPatternGetInteger(match, FC_INDEX, 0, &face_index) != FcResultMatch) {
435 FcFontSetDestroy(font_set); 452 FcFontSetDestroy(font_set);
436 return false; 453 return false;
437 } 454 }
438 455
439 FcFontSetDestroy(font_set); 456 FcFontSetDestroy(font_set);
440 457
441 if (outIdentity) { 458 if (outIdentity) {
442 outIdentity->fTTCIndex = face_index; 459 outIdentity->fTTCIndex = face_index;
443 outIdentity->fString.set((const char*)c_filename); 460 outIdentity->fString.set(c_filename);
444 } 461 }
445 if (outFamilyName) { 462 if (outFamilyName) {
446 outFamilyName->set((const char*)post_config_family); 463 outFamilyName->set(post_config_family);
447 } 464 }
448 if (outStyle) { 465 if (outStyle) {
449 *outStyle = GetFontStyle(match); 466 *outStyle = GetFontStyle(match);
450 } 467 }
451 return true; 468 return true;
452 } 469 }
453 470
454 SkStream* SkFontConfigInterfaceDirect::openStream(const FontIdentity& identity) { 471 SkStream* SkFontConfigInterfaceDirect::openStream(const FontIdentity& identity) {
455 return SkStream::NewFromFile(identity.fString.c_str()); 472 return SkStream::NewFromFile(identity.fString.c_str());
456 } 473 }
457 474
458 /////////////////////////////////////////////////////////////////////////////// 475 ///////////////////////////////////////////////////////////////////////////////
459 476
460 static const char* get_name(FcPattern* pattern, const char field[]) {
461 const char* name;
462 if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch ) {
463 name = "";
464 }
465 return name;
466 }
467
468 static bool find_name(const SkTDArray<const char*>& list, const char* str) { 477 static bool find_name(const SkTDArray<const char*>& list, const char* str) {
469 int count = list.count(); 478 int count = list.count();
470 for (int i = 0; i < count; ++i) { 479 for (int i = 0; i < count; ++i) {
471 if (!strcmp(list[i], str)) { 480 if (!strcmp(list[i], str)) {
472 return true; 481 return true;
473 } 482 }
474 } 483 }
475 return false; 484 return false;
476 } 485 }
477 486
478 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { 487 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() {
479 FcPattern* pat = FcPatternCreate(); 488 FcPattern* pat = FcPatternCreate();
480 FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, (char *) 0); 489 FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, (char *) 0);
481 if (NULL == os) { 490 if (NULL == os) {
482 return NULL; 491 return NULL;
483 } 492 }
484 FcFontSet* fs = FcFontList(NULL, pat, os); 493 FcFontSet* fs = FcFontList(NULL, pat, os);
485 if (NULL == fs) { 494 if (NULL == fs) {
486 FcObjectSetDestroy(os); 495 FcObjectSetDestroy(os);
487 return NULL; 496 return NULL;
488 } 497 }
489 498
490 SkTDArray<const char*> names; 499 SkTDArray<const char*> names;
491 SkTDArray<size_t> sizes; 500 SkTDArray<size_t> sizes;
492 for (int i = 0; i < fs->nfont; ++i) { 501 for (int i = 0; i < fs->nfont; ++i) {
493 FcPattern* match = fs->fonts[i]; 502 FcPattern* match = fs->fonts[i];
494 const char* famName = get_name(match, FC_FAMILY); 503 const char* famName = get_name(match, FC_FAMILY);
495 if (!find_name(names, famName)) { 504 if (famName && !find_name(names, famName)) {
496 *names.append() = famName; 505 *names.append() = famName;
497 *sizes.append() = strlen(famName) + 1; 506 *sizes.append() = strlen(famName) + 1;
498 } 507 }
499 } 508 }
500 509
501 FcFontSetDestroy(fs); 510 FcFontSetDestroy(fs);
502 FcObjectSetDestroy(os); 511 FcObjectSetDestroy(os);
503 FcPatternDestroy(pat); 512 FcPatternDestroy(pat);
504 513
505 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), 514 return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
506 sizes.begin(), names.count()); 515 sizes.begin(), names.count());
507 } 516 }
508 517
509 bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[], 518 bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[],
510 SkString* outFamilyName, 519 SkString* outFamilyName,
511 SkTArray<FontIdentity>* ids) { 520 SkTArray<FontIdentity>* ids) {
512 return false; 521 return false;
513 } 522 }
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