| 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 |