OLD | NEW |
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 "SkBuffer.h" | 10 #include "SkBuffer.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 iden->fID = 10; | 70 iden->fID = 10; |
71 iden->fTTCIndex = 2; | 71 iden->fTTCIndex = 2; |
72 iden->fString.set("Hello world"); | 72 iden->fString.set("Hello world"); |
73 iden->fStyle = SkFontStyle(300, 6, SkFontStyle::kItalic_Slant); | 73 iden->fStyle = SkFontStyle(300, 6, SkFontStyle::kItalic_Slant); |
74 } | 74 } |
75 | 75 |
76 static void test_writeToMemory(const SkFontConfigInterface::FontIdentity& iden0, | 76 static void test_writeToMemory(const SkFontConfigInterface::FontIdentity& iden0, |
77 int initValue) { | 77 int initValue) { |
78 SkFontConfigInterface::FontIdentity iden1; | 78 SkFontConfigInterface::FontIdentity iden1; |
79 | 79 |
80 size_t size0 = iden0.writeToMemory(NULL); | 80 size_t size0 = iden0.writeToMemory(nullptr); |
81 | 81 |
82 SkAutoMalloc storage(size0); | 82 SkAutoMalloc storage(size0); |
83 memset(storage.get(), initValue, size0); | 83 memset(storage.get(), initValue, size0); |
84 | 84 |
85 size_t size1 = iden0.writeToMemory(storage.get()); | 85 size_t size1 = iden0.writeToMemory(storage.get()); |
86 SkASSERT(size0 == size1); | 86 SkASSERT(size0 == size1); |
87 | 87 |
88 SkASSERT(iden0 != iden1); | 88 SkASSERT(iden0 != iden1); |
89 size_t size2 = iden1.readFromMemory(storage.get(), size1); | 89 size_t size2 = iden1.readFromMemory(storage.get(), size1); |
90 SkASSERT(size2 == size1); | 90 SkASSERT(size2 == size1); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 virtual bool matchFamilySet(const char inFamilyName[], | 124 virtual bool matchFamilySet(const char inFamilyName[], |
125 SkString* outFamilyName, | 125 SkString* outFamilyName, |
126 SkTArray<FontIdentity>*) override; | 126 SkTArray<FontIdentity>*) override; |
127 | 127 |
128 private: | 128 private: |
129 SkMutex mutex_; | 129 SkMutex mutex_; |
130 }; | 130 }; |
131 | 131 |
132 SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface(SkBase
Mutex* mutex) { | 132 SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface(SkBase
Mutex* mutex) { |
133 SkAutoMutexAcquire ac(mutex); | 133 SkAutoMutexAcquire ac(mutex); |
134 static SkFontConfigInterfaceDirect* singleton = NULL; | 134 static SkFontConfigInterfaceDirect* singleton = nullptr; |
135 if (singleton == NULL) { | 135 if (singleton == nullptr) { |
136 singleton = new SkFontConfigInterfaceDirect; | 136 singleton = new SkFontConfigInterfaceDirect; |
137 } | 137 } |
138 return singleton; | 138 return singleton; |
139 } | 139 } |
140 | 140 |
141 /////////////////////////////////////////////////////////////////////////////// | 141 /////////////////////////////////////////////////////////////////////////////// |
142 | 142 |
143 // Returns the string from the pattern, or NULL | 143 // Returns the string from the pattern, or nullptr |
144 static const char* get_name(FcPattern* pattern, const char field[], | 144 static const char* get_name(FcPattern* pattern, const char field[], |
145 int index = 0) { | 145 int index = 0) { |
146 const char* name; | 146 const char* name; |
147 if (FcPatternGetString(pattern, field, index, | 147 if (FcPatternGetString(pattern, field, index, |
148 (FcChar8**)&name) != FcResultMatch) { | 148 (FcChar8**)&name) != FcResultMatch) { |
149 name = NULL; | 149 name = nullptr; |
150 } | 150 } |
151 return name; | 151 return name; |
152 } | 152 } |
153 | 153 |
154 /////////////////////////////////////////////////////////////////////////////// | 154 /////////////////////////////////////////////////////////////////////////////// |
155 | 155 |
156 namespace { | 156 namespace { |
157 | 157 |
158 // Equivalence classes, used to match the Liberation and other fonts | 158 // Equivalence classes, used to match the Liberation and other fonts |
159 // with their metric-compatible replacements. See the discussion in | 159 // with their metric-compatible replacements. See the discussion in |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 } | 353 } |
354 return true; | 354 return true; |
355 } | 355 } |
356 | 356 |
357 // Find matching font from |font_set| for the given font family. | 357 // Find matching font from |font_set| for the given font family. |
358 FcPattern* MatchFont(FcFontSet* font_set, | 358 FcPattern* MatchFont(FcFontSet* font_set, |
359 const char* post_config_family, | 359 const char* post_config_family, |
360 const SkString& family) { | 360 const SkString& family) { |
361 // Older versions of fontconfig have a bug where they cannot select | 361 // Older versions of fontconfig have a bug where they cannot select |
362 // only scalable fonts so we have to manually filter the results. | 362 // only scalable fonts so we have to manually filter the results. |
363 FcPattern* match = NULL; | 363 FcPattern* match = nullptr; |
364 for (int i = 0; i < font_set->nfont; ++i) { | 364 for (int i = 0; i < font_set->nfont; ++i) { |
365 FcPattern* current = font_set->fonts[i]; | 365 FcPattern* current = font_set->fonts[i]; |
366 if (valid_pattern(current)) { | 366 if (valid_pattern(current)) { |
367 match = current; | 367 match = current; |
368 break; | 368 break; |
369 } | 369 } |
370 } | 370 } |
371 | 371 |
372 if (match && !IsFallbackFontAllowed(family)) { | 372 if (match && !IsFallbackFontAllowed(family)) { |
373 bool acceptable_substitute = false; | 373 bool acceptable_substitute = false; |
374 for (int id = 0; id < 255; ++id) { | 374 for (int id = 0; id < 255; ++id) { |
375 const char* post_match_family = get_name(match, FC_FAMILY, id); | 375 const char* post_match_family = get_name(match, FC_FAMILY, id); |
376 if (!post_match_family) | 376 if (!post_match_family) |
377 break; | 377 break; |
378 acceptable_substitute = | 378 acceptable_substitute = |
379 (strcasecmp(post_config_family, post_match_family) == 0 || | 379 (strcasecmp(post_config_family, post_match_family) == 0 || |
380 // Workaround for Issue 12530: | 380 // Workaround for Issue 12530: |
381 // requested family: "Bitstream Vera Sans" | 381 // requested family: "Bitstream Vera Sans" |
382 // post_config_family: "Arial" | 382 // post_config_family: "Arial" |
383 // post_match_family: "Bitstream Vera Sans" | 383 // post_match_family: "Bitstream Vera Sans" |
384 // -> We should treat this case as a good match. | 384 // -> We should treat this case as a good match. |
385 strcasecmp(family.c_str(), post_match_family) == 0) || | 385 strcasecmp(family.c_str(), post_match_family) == 0) || |
386 IsMetricCompatibleReplacement(family.c_str(), post_match_family); | 386 IsMetricCompatibleReplacement(family.c_str(), post_match_family); |
387 if (acceptable_substitute) | 387 if (acceptable_substitute) |
388 break; | 388 break; |
389 } | 389 } |
390 if (!acceptable_substitute) | 390 if (!acceptable_substitute) |
391 return NULL; | 391 return nullptr; |
392 } | 392 } |
393 | 393 |
394 return match; | 394 return match; |
395 } | 395 } |
396 | 396 |
397 // Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|. | 397 // Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|. |
398 SkTypeface::Style GetFontStyle(FcPattern* font) { | 398 SkTypeface::Style GetFontStyle(FcPattern* font) { |
399 int resulting_bold; | 399 int resulting_bold; |
400 if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold)) | 400 if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold)) |
401 resulting_bold = FC_WEIGHT_NORMAL; | 401 resulting_bold = FC_WEIGHT_NORMAL; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 462 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
463 } | 463 } |
464 FcPatternAddInteger(pattern, FC_WEIGHT, | 464 FcPatternAddInteger(pattern, FC_WEIGHT, |
465 (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD | 465 (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD |
466 : FC_WEIGHT_NORMAL); | 466 : FC_WEIGHT_NORMAL); |
467 FcPatternAddInteger(pattern, FC_SLANT, | 467 FcPatternAddInteger(pattern, FC_SLANT, |
468 (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC | 468 (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC |
469 : FC_SLANT_ROMAN); | 469 : FC_SLANT_ROMAN); |
470 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); | 470 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); |
471 | 471 |
472 FcConfigSubstitute(NULL, pattern, FcMatchPattern); | 472 FcConfigSubstitute(nullptr, pattern, FcMatchPattern); |
473 FcDefaultSubstitute(pattern); | 473 FcDefaultSubstitute(pattern); |
474 | 474 |
475 // Font matching: | 475 // Font matching: |
476 // CSS often specifies a fallback list of families: | 476 // CSS often specifies a fallback list of families: |
477 // font-family: a, b, c, serif; | 477 // font-family: a, b, c, serif; |
478 // However, fontconfig will always do its best to find *a* font when asked | 478 // However, fontconfig will always do its best to find *a* font when asked |
479 // for something so we need a way to tell if the match which it has found is | 479 // for something so we need a way to tell if the match which it has found is |
480 // "good enough" for us. Otherwise, we can return NULL which gets piped up | 480 // "good enough" for us. Otherwise, we can return nullptr which gets piped u
p |
481 // and lets WebKit know to try the next CSS family name. However, fontconfig | 481 // and lets WebKit know to try the next CSS family name. However, fontconfig |
482 // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we | 482 // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we |
483 // wish to support that. | 483 // wish to support that. |
484 // | 484 // |
485 // Thus, if a specific family is requested we set @family_requested. Then we | 485 // Thus, if a specific family is requested we set @family_requested. Then we |
486 // record two strings: the family name after config processing and the | 486 // record two strings: the family name after config processing and the |
487 // family name after resolving. If the two are equal, it's a good match. | 487 // family name after resolving. If the two are equal, it's a good match. |
488 // | 488 // |
489 // So consider the case where a user has mapped Arial to Helvetica in their | 489 // So consider the case where a user has mapped Arial to Helvetica in their |
490 // config. | 490 // config. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 } | 572 } |
573 } | 573 } |
574 return false; | 574 return false; |
575 } | 575 } |
576 | 576 |
577 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { | 577 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { |
578 SkAutoMutexAcquire ac(mutex_); | 578 SkAutoMutexAcquire ac(mutex_); |
579 | 579 |
580 FcPattern* pat = FcPatternCreate(); | 580 FcPattern* pat = FcPatternCreate(); |
581 SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat); | 581 SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat); |
582 if (NULL == pat) { | 582 if (nullptr == pat) { |
583 return NULL; | 583 return nullptr; |
584 } | 584 } |
585 | 585 |
586 FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, (char *)0); | 586 FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, (char *)0); |
587 SkAutoTCallVProc<FcObjectSet, FcObjectSetDestroy> autoDestroyOs(os); | 587 SkAutoTCallVProc<FcObjectSet, FcObjectSetDestroy> autoDestroyOs(os); |
588 if (NULL == os) { | 588 if (nullptr == os) { |
589 return NULL; | 589 return nullptr; |
590 } | 590 } |
591 | 591 |
592 FcFontSet* fs = FcFontList(NULL, pat, os); | 592 FcFontSet* fs = FcFontList(nullptr, pat, os); |
593 SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs); | 593 SkAutoTCallVProc<FcFontSet, FcFontSetDestroy> autoDestroyFs(fs); |
594 if (NULL == fs) { | 594 if (nullptr == fs) { |
595 return NULL; | 595 return nullptr; |
596 } | 596 } |
597 | 597 |
598 SkTDArray<const char*> names; | 598 SkTDArray<const char*> names; |
599 SkTDArray<size_t> sizes; | 599 SkTDArray<size_t> sizes; |
600 for (int i = 0; i < fs->nfont; ++i) { | 600 for (int i = 0; i < fs->nfont; ++i) { |
601 FcPattern* match = fs->fonts[i]; | 601 FcPattern* match = fs->fonts[i]; |
602 const char* famName = get_name(match, FC_FAMILY); | 602 const char* famName = get_name(match, FC_FAMILY); |
603 if (famName && !find_name(names, famName)) { | 603 if (famName && !find_name(names, famName)) { |
604 *names.append() = famName; | 604 *names.append() = famName; |
605 *sizes.append() = strlen(famName) + 1; | 605 *sizes.append() = strlen(famName) + 1; |
(...skipping 17 matching lines...) Expand all Loading... |
623 | 623 |
624 SkAutoMutexAcquire ac(mutex_); | 624 SkAutoMutexAcquire ac(mutex_); |
625 | 625 |
626 FcPattern* pattern = FcPatternCreate(); | 626 FcPattern* pattern = FcPatternCreate(); |
627 | 627 |
628 if (familyName) { | 628 if (familyName) { |
629 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 629 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
630 } | 630 } |
631 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); | 631 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); |
632 | 632 |
633 FcConfigSubstitute(NULL, pattern, FcMatchPattern); | 633 FcConfigSubstitute(nullptr, pattern, FcMatchPattern); |
634 FcDefaultSubstitute(pattern); | 634 FcDefaultSubstitute(pattern); |
635 | 635 |
636 // Font matching: | 636 // Font matching: |
637 // CSS often specifies a fallback list of families: | 637 // CSS often specifies a fallback list of families: |
638 // font-family: a, b, c, serif; | 638 // font-family: a, b, c, serif; |
639 // However, fontconfig will always do its best to find *a* font when asked | 639 // However, fontconfig will always do its best to find *a* font when asked |
640 // for something so we need a way to tell if the match which it has found is | 640 // for something so we need a way to tell if the match which it has found is |
641 // "good enough" for us. Otherwise, we can return NULL which gets piped up | 641 // "good enough" for us. Otherwise, we can return nullptr which gets piped u
p |
642 // and lets WebKit know to try the next CSS family name. However, fontconfig | 642 // and lets WebKit know to try the next CSS family name. However, fontconfig |
643 // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we | 643 // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we |
644 // wish to support that. | 644 // wish to support that. |
645 // | 645 // |
646 // Thus, if a specific family is requested we set @family_requested. Then we | 646 // Thus, if a specific family is requested we set @family_requested. Then we |
647 // record two strings: the family name after config processing and the | 647 // record two strings: the family name after config processing and the |
648 // family name after resolving. If the two are equal, it's a good match. | 648 // family name after resolving. If the two are equal, it's a good match. |
649 // | 649 // |
650 // So consider the case where a user has mapped Arial to Helvetica in their | 650 // So consider the case where a user has mapped Arial to Helvetica in their |
651 // config. | 651 // config. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 } | 713 } |
714 return true; | 714 return true; |
715 | 715 |
716 //////////////////// | 716 //////////////////// |
717 | 717 |
718 int count; | 718 int count; |
719 FcPattern** match = MatchFont(font_set, post_config_family, &count); | 719 FcPattern** match = MatchFont(font_set, post_config_family, &count); |
720 if (!match) { | 720 if (!match) { |
721 FcPatternDestroy(pattern); | 721 FcPatternDestroy(pattern); |
722 FcFontSetDestroy(font_set); | 722 FcFontSetDestroy(font_set); |
723 return NULL; | 723 return nullptr; |
724 } | 724 } |
725 | 725 |
726 FcPatternDestroy(pattern); | 726 FcPatternDestroy(pattern); |
727 | 727 |
728 SkTDArray<FcPattern*> trimmedMatches; | 728 SkTDArray<FcPattern*> trimmedMatches; |
729 for (int i = 0; i < count; ++i) { | 729 for (int i = 0; i < count; ++i) { |
730 const char* justName = find_just_name(get_name(match[i], FC_FILE)); | 730 const char* justName = find_just_name(get_name(match[i], FC_FILE)); |
731 if (!is_lower(*justName)) { | 731 if (!is_lower(*justName)) { |
732 *trimmedMatches.append() = match[i]; | 732 *trimmedMatches.append() = match[i]; |
733 } | 733 } |
734 } | 734 } |
735 | 735 |
736 SkFontStyleSet_FC* sset = new SkFontStyleSet_FC
(trimmedMatches.begin(),
trimmedMatches.count()); | 736 SkFontStyleSet_FC* sset = new SkFontStyleSet_FC
(trimmedMatches.begin(),
trimmedMatches.count()); |
737 #endif | 737 #endif |
738 return false; | 738 return false; |
739 } | 739 } |
OLD | NEW |