OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2009-2015 Google Inc. | 2 * Copyright 2009-2015 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" |
11 #include "SkDataTable.h" | 11 #include "SkDataTable.h" |
12 #include "SkFixed.h" | 12 #include "SkFixed.h" |
13 #include "SkFontConfigInterface_direct.h" | 13 #include "SkFontConfigInterface_direct.h" |
14 #include "SkFontStyle.h" | 14 #include "SkFontStyle.h" |
15 #include "SkMutex.h" | 15 #include "SkMutex.h" |
16 #include "SkStream.h" | 16 #include "SkStream.h" |
17 #include "SkString.h" | 17 #include "SkString.h" |
18 #include "SkTArray.h" | 18 #include "SkTArray.h" |
19 #include "SkTDArray.h" | 19 #include "SkTDArray.h" |
20 #include "SkTemplates.h" | 20 #include "SkTemplates.h" |
21 #include "SkTypeface.h" | 21 #include "SkTypeface.h" |
22 #include "SkTypes.h" | 22 #include "SkTypes.h" |
23 | 23 |
24 #include <fontconfig/fontconfig.h> | 24 #include <fontconfig/fontconfig.h> |
25 #include <unistd.h> | 25 #include <unistd.h> |
26 | 26 |
| 27 #ifdef SK_DEBUG |
| 28 # include "SkTLS.h" |
| 29 #endif |
| 30 |
| 31 namespace { |
| 32 |
| 33 // Fontconfig is not threadsafe before 2.10.91. Before that, we lock with a glob
al mutex. |
| 34 // See https://bug.skia.org/1497 for background. |
| 35 SK_DECLARE_STATIC_MUTEX(gFCMutex); |
| 36 |
| 37 #ifdef SK_DEBUG |
| 38 void* CreateThreadFcLocked() { return new bool(false); } |
| 39 void DeleteThreadFcLocked(void* v) { delete static_cast<bool*>(v); } |
| 40 # define THREAD_FC_LOCKED \ |
| 41 static_cast<bool*>(SkTLS::Get(CreateThreadFcLocked, DeleteThreadFcLocked
)) |
| 42 #endif |
| 43 |
| 44 struct FCLocker { |
| 45 // Assume FcGetVersion() has always been thread safe. |
| 46 |
| 47 FCLocker() { |
| 48 if (FcGetVersion() < 21091) { |
| 49 gFCMutex.acquire(); |
| 50 } else { |
| 51 SkDEBUGCODE(bool* threadLocked = THREAD_FC_LOCKED); |
| 52 SkASSERT(false == *threadLocked); |
| 53 SkDEBUGCODE(*threadLocked = true); |
| 54 } |
| 55 } |
| 56 |
| 57 ~FCLocker() { |
| 58 AssertHeld(); |
| 59 if (FcGetVersion() < 21091) { |
| 60 gFCMutex.release(); |
| 61 } else { |
| 62 SkDEBUGCODE(*THREAD_FC_LOCKED = false); |
| 63 } |
| 64 } |
| 65 |
| 66 static void AssertHeld() { SkDEBUGCODE( |
| 67 if (FcGetVersion() < 21091) { |
| 68 gFCMutex.assertHeld(); |
| 69 } else { |
| 70 SkASSERT(true == *THREAD_FC_LOCKED); |
| 71 } |
| 72 ) } |
| 73 }; |
| 74 |
| 75 } // namespace |
| 76 |
27 size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const { | 77 size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const { |
28 size_t size = sizeof(fID) + sizeof(fTTCIndex); | 78 size_t size = sizeof(fID) + sizeof(fTTCIndex); |
29 size += sizeof(int32_t) + sizeof(int32_t) + sizeof(uint8_t); // weight, widt
h, italic | 79 size += sizeof(int32_t) + sizeof(int32_t) + sizeof(uint8_t); // weight, widt
h, italic |
30 size += sizeof(int32_t) + fString.size(); // store length+data | 80 size += sizeof(int32_t) + fString.size(); // store length+data |
31 if (addr) { | 81 if (addr) { |
32 SkWBuffer buffer(addr, size); | 82 SkWBuffer buffer(addr, size); |
33 | 83 |
34 buffer.write32(fID); | 84 buffer.write32(fID); |
35 buffer.write32(fTTCIndex); | 85 buffer.write32(fTTCIndex); |
36 buffer.write32(fString.size()); | 86 buffer.write32(fString.size()); |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 FcPatternAddInteger(pattern, FC_SLANT , slant); | 491 FcPatternAddInteger(pattern, FC_SLANT , slant); |
442 } | 492 } |
443 | 493 |
444 } // anonymous namespace | 494 } // anonymous namespace |
445 | 495 |
446 /////////////////////////////////////////////////////////////////////////////// | 496 /////////////////////////////////////////////////////////////////////////////// |
447 | 497 |
448 #define kMaxFontFamilyLength 2048 | 498 #define kMaxFontFamilyLength 2048 |
449 | 499 |
450 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { | 500 SkFontConfigInterfaceDirect::SkFontConfigInterfaceDirect() { |
451 SkAutoMutexAcquire ac(mutex_); | 501 FCLocker lock; |
452 | 502 |
453 FcInit(); | 503 FcInit(); |
454 | 504 |
455 SkDEBUGCODE(fontconfiginterface_unittest();) | 505 SkDEBUGCODE(fontconfiginterface_unittest();) |
456 } | 506 } |
457 | 507 |
458 SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { | 508 SkFontConfigInterfaceDirect::~SkFontConfigInterfaceDirect() { |
459 } | 509 } |
460 | 510 |
461 bool SkFontConfigInterfaceDirect::isAccessible(const char* filename) { | 511 bool SkFontConfigInterfaceDirect::isAccessible(const char* filename) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], | 575 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[], |
526 SkFontStyle style, | 576 SkFontStyle style, |
527 FontIdentity* outIdentity, | 577 FontIdentity* outIdentity, |
528 SkString* outFamilyName, | 578 SkString* outFamilyName, |
529 SkFontStyle* outStyle) { | 579 SkFontStyle* outStyle) { |
530 SkString familyStr(familyName ? familyName : ""); | 580 SkString familyStr(familyName ? familyName : ""); |
531 if (familyStr.size() > kMaxFontFamilyLength) { | 581 if (familyStr.size() > kMaxFontFamilyLength) { |
532 return false; | 582 return false; |
533 } | 583 } |
534 | 584 |
535 SkAutoMutexAcquire ac(mutex_); | 585 FCLocker lock; |
536 | 586 |
537 FcPattern* pattern = FcPatternCreate(); | 587 FcPattern* pattern = FcPatternCreate(); |
538 | 588 |
539 if (familyName) { | 589 if (familyName) { |
540 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); | 590 FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName); |
541 } | 591 } |
542 fcpattern_from_skfontstyle(style, pattern); | 592 fcpattern_from_skfontstyle(style, pattern); |
543 | 593 |
544 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); | 594 FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); |
545 | 595 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 int count = list.count(); | 692 int count = list.count(); |
643 for (int i = 0; i < count; ++i) { | 693 for (int i = 0; i < count; ++i) { |
644 if (!strcmp(list[i], str)) { | 694 if (!strcmp(list[i], str)) { |
645 return true; | 695 return true; |
646 } | 696 } |
647 } | 697 } |
648 return false; | 698 return false; |
649 } | 699 } |
650 | 700 |
651 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { | 701 SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() { |
652 SkAutoMutexAcquire ac(mutex_); | 702 FCLocker lock; |
653 | 703 |
654 FcPattern* pat = FcPatternCreate(); | 704 FcPattern* pat = FcPatternCreate(); |
655 SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat); | 705 SkAutoTCallVProc<FcPattern, FcPatternDestroy> autoDestroyPat(pat); |
656 if (nullptr == pat) { | 706 if (nullptr == pat) { |
657 return nullptr; | 707 return nullptr; |
658 } | 708 } |
659 | 709 |
660 FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, (char *)0); | 710 FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, (char *)0); |
661 SkAutoTCallVProc<FcObjectSet, FcObjectSetDestroy> autoDestroyOs(os); | 711 SkAutoTCallVProc<FcObjectSet, FcObjectSetDestroy> autoDestroyOs(os); |
662 if (nullptr == os) { | 712 if (nullptr == os) { |
(...skipping 13 matching lines...) Expand all Loading... |
676 const char* famName = get_name(match, FC_FAMILY); | 726 const char* famName = get_name(match, FC_FAMILY); |
677 if (famName && !find_name(names, famName)) { | 727 if (famName && !find_name(names, famName)) { |
678 *names.append() = famName; | 728 *names.append() = famName; |
679 *sizes.append() = strlen(famName) + 1; | 729 *sizes.append() = strlen(famName) + 1; |
680 } | 730 } |
681 } | 731 } |
682 | 732 |
683 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), | 733 return SkDataTable::NewCopyArrays((const void*const*)names.begin(), |
684 sizes.begin(), names.count()); | 734 sizes.begin(), names.count()); |
685 } | 735 } |
OLD | NEW |