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