1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkFontMgr.h" 9 #include "SkFontMgr_indirect.h" 10 #include "SkFontStyle.h" 11 #include "SkMutex.h" 12 #include "SkOnce.h" 13 #include "SkRefCnt.h" 14 #include "SkRemotableFontMgr.h" 15 #include "SkStream.h" 16 #include "SkString.h" 17 #include "SkTArray.h" 18 #include "SkTypeface.h" 19 #include "SkTypes.h" 20 #include "SkTemplates.h" 21 22 class SkData; 23 24 class SkStyleSet_Indirect : public SkFontStyleSet { 25 public: 26 /** Takes ownership of the SkRemotableFontIdentitySet. */ 27 SkStyleSet_Indirect(const SkFontMgr_Indirect* owner, int familyIndex, 28 SkRemotableFontIdentitySet* data) 29 : fOwner(SkRef(owner)), fFamilyIndex(familyIndex), fData(data) 30 { } 31 32 int count() override { return fData->count(); } 33 34 void getStyle(int index, SkFontStyle* fs, SkString* style) override { 35 if (fs) { 36 *fs = fData->at(index).fFontStyle; 37 } 38 if (style) { 39 // TODO: is this useful? Current locale? 40 style->reset(); 41 } 42 } 43 44 SkTypeface* createTypeface(int index) override { 45 return fOwner->createTypefaceFromFontId(fData->at(index)); 46 } 47 48 SkTypeface* matchStyle(const SkFontStyle& pattern) override { 49 if (fFamilyIndex >= 0) { 50 SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pattern); 51 return fOwner->createTypefaceFromFontId(id); 52 } 53 54 return this->matchStyleCSS3(pattern); 55 } 56 private: 57 sk_sp<const SkFontMgr_Indirect> fOwner; 58 int fFamilyIndex; 59 sk_sp<SkRemotableFontIdentitySet> fData; 60 }; 61 62 int SkFontMgr_Indirect::onCountFamilies() const { 63 return 0; 64 } 65 66 void SkFontMgr_Indirect::onGetFamilyName(int index, SkString* familyName) const { 67 SK_ABORT("Not implemented"); 68 } 69 70 SkFontStyleSet* SkFontMgr_Indirect::onCreateStyleSet(int index) const { 71 SK_ABORT("Not implemented"); 72 return nullptr; 73 } 74 75 SkFontStyleSet* SkFontMgr_Indirect::onMatchFamily(const char familyName[]) const { 76 return new SkStyleSet_Indirect(this, -1, fProxy->matchName(familyName)); 77 } 78 79 SkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& id) const { 80 if (id.fDataId == SkFontIdentity::kInvalidDataId) { 81 return nullptr; 82 } 83 84 SkAutoMutexAcquire ama(fDataCacheMutex); 85 86 sk_sp<SkTypeface> dataTypeface; 87 int dataTypefaceIndex = 0; 88 for (int i = 0; i < fDataCache.count(); ++i) { 89 const DataEntry& entry = fDataCache[i]; 90 if (entry.fDataId == id.fDataId) { 91 if (entry.fTtcIndex == id.fTtcIndex && 92 !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref()) 93 { 94 return entry.fTypeface; 95 } 96 if (dataTypeface.get() == nullptr && 97 !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref()) 98 { 99 dataTypeface.reset(entry.fTypeface); 100 dataTypefaceIndex = entry.fTtcIndex; 101 } 102 } 103 104 if (entry.fTypeface->weak_expired()) { 105 fDataCache.removeShuffle(i); 106 --i; 107 } 108 } 109 110 // No exact match, but did find a data match. 111 if (dataTypeface.get() != nullptr) { 112 std::unique_ptr<SkStreamAsset> stream(dataTypeface->openStream(nullptr)); 113 if (stream.get() != nullptr) { 114 return fImpl->makeFromStream(std::move(stream), dataTypefaceIndex).release(); 115 } 116 } 117 118 // No data match, request data and add entry. 119 std::unique_ptr<SkStreamAsset> stream(fProxy->getData(id.fDataId)); 120 if (stream.get() == nullptr) { 121 return nullptr; 122 } 123 124 sk_sp<SkTypeface> typeface(fImpl->makeFromStream(std::move(stream), id.fTtcIndex)); 125 if (typeface.get() == nullptr) { 126 return nullptr; 127 } 128 129 DataEntry& newEntry = fDataCache.push_back(); 130 typeface->weak_ref(); 131 newEntry.fDataId = id.fDataId; 132 newEntry.fTtcIndex = id.fTtcIndex; 133 newEntry.fTypeface = typeface.get(); // weak reference passed to new entry. 134 135 return typeface.release(); 136 } 137 138 SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyle(const char familyName[], 139 const SkFontStyle& fontStyle) const { 140 SkFontIdentity id = fProxy->matchNameStyle(familyName, fontStyle); 141 return this->createTypefaceFromFontId(id); 142 } 143 144 SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[], 145 const SkFontStyle& style, 146 const char* bcp47[], 147 int bcp47Count, 148 SkUnichar character) const { 149 SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47, 150 bcp47Count, character); 151 return this->createTypefaceFromFontId(id); 152 } 153 154 SkTypeface* SkFontMgr_Indirect::onMatchFaceStyle(const SkTypeface* familyMember, 155 const SkFontStyle& fontStyle) const { 156 SkString familyName; 157 familyMember->getFamilyName(&familyName); 158 return this->matchFamilyStyle(familyName.c_str(), fontStyle); 159 } 160 161 sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, 162 int ttcIndex) const { 163 return fImpl->makeFromStream(std::move(stream), ttcIndex); 164 } 165 166 sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromFile(const char path[], int ttcIndex) const { 167 return fImpl->makeFromFile(path, ttcIndex); 168 } 169 170 sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const { 171 return fImpl->makeFromData(std::move(data), ttcIndex); 172 } 173 174 sk_sp<SkTypeface> SkFontMgr_Indirect::onLegacyMakeTypeface(const char familyName[], 175 SkFontStyle style) const { 176 sk_sp<SkTypeface> face(this->matchFamilyStyle(familyName, style)); 177 178 if (nullptr == face.get()) { 179 face.reset(this->matchFamilyStyle(nullptr, style)); 180 } 181 182 if (nullptr == face.get()) { 183 SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style); 184 face.reset(this->createTypefaceFromFontId(fontId)); 185 } 186 187 return face; 188 } 189