172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com/* 272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com * Copyright 2014 Google Inc. 372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com * 472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com * Use of this source code is governed by a BSD-style license that can be 572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com * found in the LICENSE file. 672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com */ 772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 8f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkFontMgr.h" 9f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkFontMgr_indirect.h" 1072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkFontStyle.h" 11f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkMutex.h" 1272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkOnce.h" 13f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkRefCnt.h" 14f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkRemotableFontMgr.h" 1572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkStream.h" 16f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkString.h" 17f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTArray.h" 1872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkTypeface.h" 19f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTypes.h" 20f20488b4f2139e6ca09fee7e39b731dd8ab467dbbungeman#include "SkTemplates.h" 2172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 2272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkData; 2372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 2472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkStyleSet_Indirect : public SkFontStyleSet { 2572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.compublic: 2672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com /** Takes ownership of the SkRemotableFontIdentitySet. */ 2772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkStyleSet_Indirect(const SkFontMgr_Indirect* owner, int familyIndex, 2872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkRemotableFontIdentitySet* data) 2972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com : fOwner(SkRef(owner)), fFamilyIndex(familyIndex), fData(data) 3072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com { } 3172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 3236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein int count() override { return fData->count(); } 3372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 3436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getStyle(int index, SkFontStyle* fs, SkString* style) override { 3572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (fs) { 3672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com *fs = fData->at(index).fFontStyle; 3772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 3872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (style) { 3972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // TODO: is this useful? Current locale? 4072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com style->reset(); 4172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 4272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 4372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 4436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* createTypeface(int index) override { 4572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fOwner->createTypefaceFromFontId(fData->at(index)); 4672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 4772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 4836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkTypeface* matchStyle(const SkFontStyle& pattern) override { 4972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (fFamilyIndex >= 0) { 5072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pattern); 5172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fOwner->createTypefaceFromFontId(id); 5272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 5372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 54147ea2fb7ad9adeeb52fe5549f7ba20953296f6fbungeman return this->matchStyleCSS3(pattern); 5572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 5672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comprivate: 5767b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<const SkFontMgr_Indirect> fOwner; 5872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com int fFamilyIndex; 5967b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkRemotableFontIdentitySet> fData; 6072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com}; 6172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 6272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comint SkFontMgr_Indirect::onCountFamilies() const { 639adfef8680c22ce8980031b4bcb9f1fadd066a80Herb Derby return 0; 6472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 6572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 6672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comvoid SkFontMgr_Indirect::onGetFamilyName(int index, SkString* familyName) const { 67b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner SK_ABORT("Not implemented"); 6872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 6972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 7072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkFontStyleSet* SkFontMgr_Indirect::onCreateStyleSet(int index) const { 71b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner SK_ABORT("Not implemented"); 729adfef8680c22ce8980031b4bcb9f1fadd066a80Herb Derby return nullptr; 7372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 7472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 7572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkFontStyleSet* SkFontMgr_Indirect::onMatchFamily(const char familyName[]) const { 76385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SkStyleSet_Indirect(this, -1, fProxy->matchName(familyName)); 7772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 7872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 7972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& id) const { 8072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (id.fDataId == SkFontIdentity::kInvalidDataId) { 8196fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 8272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 8372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 8472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoMutexAcquire ama(fDataCacheMutex); 8572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 8667b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkTypeface> dataTypeface; 8772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com int dataTypefaceIndex = 0; 8872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com for (int i = 0; i < fDataCache.count(); ++i) { 8972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const DataEntry& entry = fDataCache[i]; 9072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (entry.fDataId == id.fDataId) { 9172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (entry.fTtcIndex == id.fTtcIndex && 9272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref()) 9372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com { 9472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return entry.fTypeface; 9572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 9696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (dataTypeface.get() == nullptr && 9772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref()) 9872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com { 9972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com dataTypeface.reset(entry.fTypeface); 10072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com dataTypefaceIndex = entry.fTtcIndex; 10172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 10272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 10372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 10472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (entry.fTypeface->weak_expired()) { 10572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com fDataCache.removeShuffle(i); 10672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com --i; 10772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 10872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 10972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 11072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // No exact match, but did find a data match. 11196fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (dataTypeface.get() != nullptr) { 112145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner std::unique_ptr<SkStreamAsset> stream(dataTypeface->openStream(nullptr)); 11396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (stream.get() != nullptr) { 114592273965a7fc7fc403252e420d15f6555b8f25dMike Reed return fImpl->makeFromStream(std::move(stream), dataTypefaceIndex).release(); 11572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 11672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 11772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 11872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // No data match, request data and add entry. 119145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner std::unique_ptr<SkStreamAsset> stream(fProxy->getData(id.fDataId)); 12096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (stream.get() == nullptr) { 12196fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 12272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 12372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 124592273965a7fc7fc403252e420d15f6555b8f25dMike Reed sk_sp<SkTypeface> typeface(fImpl->makeFromStream(std::move(stream), id.fTtcIndex)); 12596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (typeface.get() == nullptr) { 12696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 12772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 12872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 12972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com DataEntry& newEntry = fDataCache.push_back(); 13072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com typeface->weak_ref(); 13172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com newEntry.fDataId = id.fDataId; 13272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com newEntry.fTtcIndex = id.fTtcIndex; 13372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com newEntry.fTypeface = typeface.get(); // weak reference passed to new entry. 13472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 13518300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein return typeface.release(); 13672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 13772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 13872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onMatchFamilyStyle(const char familyName[], 13972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const SkFontStyle& fontStyle) const { 14072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontIdentity id = fProxy->matchNameStyle(familyName, fontStyle); 14172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return this->createTypefaceFromFontId(id); 14272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 14372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 14472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[], 14572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const SkFontStyle& style, 146c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman const char* bcp47[], 147c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman int bcp47Count, 148c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman SkUnichar character) const { 149c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47, 150c20386e3937d3d398ac9b35f9c7d997e972ade98bungeman bcp47Count, character); 15172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return this->createTypefaceFromFontId(id); 15272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 15372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 15472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onMatchFaceStyle(const SkTypeface* familyMember, 15572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const SkFontStyle& fontStyle) const { 15672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkString familyName; 15772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com familyMember->getFamilyName(&familyName); 15872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return this->matchFamilyStyle(familyName.c_str(), fontStyle); 15972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 16072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 161592273965a7fc7fc403252e420d15f6555b8f25dMike Reedsk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream, 162592273965a7fc7fc403252e420d15f6555b8f25dMike Reed int ttcIndex) const { 163592273965a7fc7fc403252e420d15f6555b8f25dMike Reed return fImpl->makeFromStream(std::move(stream), ttcIndex); 16472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 16572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 166592273965a7fc7fc403252e420d15f6555b8f25dMike Reedsk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromFile(const char path[], int ttcIndex) const { 167592273965a7fc7fc403252e420d15f6555b8f25dMike Reed return fImpl->makeFromFile(path, ttcIndex); 16872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 16972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 170592273965a7fc7fc403252e420d15f6555b8f25dMike Reedsk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const { 171592273965a7fc7fc403252e420d15f6555b8f25dMike Reed return fImpl->makeFromData(std::move(data), ttcIndex); 17272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 17372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 174592273965a7fc7fc403252e420d15f6555b8f25dMike Reedsk_sp<SkTypeface> SkFontMgr_Indirect::onLegacyMakeTypeface(const char familyName[], 175592273965a7fc7fc403252e420d15f6555b8f25dMike Reed SkFontStyle style) const { 17667b39de70fb5d10caebfc75f418754186e5226c3Hal Canary sk_sp<SkTypeface> face(this->matchFamilyStyle(familyName, style)); 17772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 17896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == face.get()) { 17996fcdcc219d2a0d3579719b84b28bede76efba64halcanary face.reset(this->matchFamilyStyle(nullptr, style)); 18072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 18172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 18296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == face.get()) { 18372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style); 18472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com face.reset(this->createTypefaceFromFontId(fontId)); 18572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 18672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 187592273965a7fc7fc403252e420d15f6555b8f25dMike Reed return face; 18872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 189