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 872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkFontMgr_indirect.h" 972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 1072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkDataTable.h" 1172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkFontStyle.h" 1272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkOnce.h" 1372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkStream.h" 1472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkTSearch.h" 1572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com#include "SkTypeface.h" 1672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 1772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkData; 1872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkString; 1972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 2072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comclass SkStyleSet_Indirect : public SkFontStyleSet { 2172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.compublic: 2272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com /** Takes ownership of the SkRemotableFontIdentitySet. */ 2372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkStyleSet_Indirect(const SkFontMgr_Indirect* owner, int familyIndex, 2472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkRemotableFontIdentitySet* data) 2572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com : fOwner(SkRef(owner)), fFamilyIndex(familyIndex), fData(data) 2672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com { } 2772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 2872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com virtual int count() SK_OVERRIDE { return fData->count(); } 2972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 3072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com virtual void getStyle(int index, SkFontStyle* fs, SkString* style) SK_OVERRIDE { 3172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (fs) { 3272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com *fs = fData->at(index).fFontStyle; 3372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 3472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (style) { 3572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // TODO: is this useful? Current locale? 3672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com style->reset(); 3772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 3872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 3972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 4072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { 4172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fOwner->createTypefaceFromFontId(fData->at(index)); 4272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 4372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 4472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE { 4572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (fFamilyIndex >= 0) { 4672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pattern); 4772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fOwner->createTypefaceFromFontId(id); 4872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 4972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 5072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If this SkStyleSet was created via onMatchFamily we would need a call like 5172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // fOwner->fProxy->matchNameStyle(fFamilyName, pattern); 5272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // but would not activate fonts (only consider fonts which would come back from matchName). 5372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 5472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // CSS policy sounds good. 5572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com struct Score { 5672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com int score; 5772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com int index; 5872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com }; 5972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 6072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // Width has the greatest priority. 6172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If the value of pattern.width is 5 (normal) or less, 6272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // narrower width values are checked first, then wider values. 6372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If the value of pattern.width is greater than 5 (normal), 6472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // wider values are checked first, followed by narrower values. 6572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 6672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // Italic/Oblique has the next highest priority. 6772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If italic requested and there is some italic font, use it. 6872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If oblique requested and there is some oblique font, use it. 6972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If italic requested and there is some oblique font, use it. 7072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If oblique requested and there is some italic font, use it. 7172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 7272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // Exact match. 7372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If pattern.weight < 400, weights below pattern.weight are checked 7472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // in descending order followed by weights above pattern.weight 7572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // in ascending order until a match is found. 7672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If pattern.weight > 500, weights above pattern.weight are checked 7772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // in ascending order followed by weights below pattern.weight 7872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // in descending order until a match is found. 7972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If pattern.weight is 400, 500 is checked first 8072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // and then the rule for pattern.weight < 400 is used. 8172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // If pattern.weight is 500, 400 is checked first 8272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // and then the rule for pattern.weight < 400 is used 8372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 8472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com Score maxScore = { 0, 0 }; 8572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com for (int i = 0; i < fData->count(); ++i) { 8672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const SkFontStyle& current = fData->at(i).fFontStyle; 8772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com Score currentScore = { 0, i }; 8872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 8972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // CSS stretch. (This is the width.) 9072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // This has the highest priority. 9172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (pattern.width() <= SkFontStyle::kNormal_Width) { 9272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (current.width() <= pattern.width()) { 9372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 10 - pattern.width() + current.width(); 9472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } else { 9572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 10 - current.width(); 9672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 9772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } else { 9872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (current.width() > pattern.width()) { 9972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 10 + pattern.width() - current.width(); 10072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } else { 10172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += current.width(); 10272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 10372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 10472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score *= 1002; 10572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 10672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // CSS style (italic/oblique) 10772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // Being italic trumps all valid weights which are not italic. 10872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // Note that newer specs differentiate between italic and oblique. 10972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (pattern.isItalic() && current.isItalic()) { 11072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 1001; 11172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 11272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 11372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // Synthetics (weight/style) [no stretch synthetic?] 11472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 11572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // The 'closer' to the target weight, the higher the score. 11672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // 1000 is the 'heaviest' recognized weight 11772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (pattern.weight() == current.weight()) { 11872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 1000; 11972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } else if (pattern.weight() <= 500) { 12072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (pattern.weight() >= 400 && pattern.weight() < 450) { 12172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (current.weight() >= 450 && current.weight() <= 500) { 12272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // Artificially boost the 500 weight. 12372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // TODO: determine correct number to use. 12472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 500; 12572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 12672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 12772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (current.weight() <= pattern.weight()) { 12872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 1000 - pattern.weight() + current.weight(); 12972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } else { 13072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 1000 - current.weight(); 13172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 13272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } else if (pattern.weight() > 500) { 13372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (current.weight() > pattern.weight()) { 13472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += 1000 + pattern.weight() - current.weight(); 13572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } else { 13672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com currentScore.score += current.weight(); 13772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 13872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 13972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 14072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (currentScore.score > maxScore.score) { 14172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com maxScore = currentScore; 14272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 14372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 14472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 14572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return this->createTypeface(maxScore.index); 14672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 14772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comprivate: 14872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoTUnref<const SkFontMgr_Indirect> fOwner; 14972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com int fFamilyIndex; 15072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoTUnref<SkRemotableFontIdentitySet> fData; 15172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com}; 15272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 15372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comvoid SkFontMgr_Indirect::set_up_family_names(const SkFontMgr_Indirect* self) { 15472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com self->fFamilyNames.reset(self->fProxy->getFamilyNames()); 15572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 15672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 15772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comint SkFontMgr_Indirect::onCountFamilies() const { 1581ba62629f4d8300eb5ff82a83807119032eb0c02bungeman@google.com SkOnce(&fFamilyNamesInited, &fFamilyNamesMutex, SkFontMgr_Indirect::set_up_family_names, this); 15972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fFamilyNames->count(); 16072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 16172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 16272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comvoid SkFontMgr_Indirect::onGetFamilyName(int index, SkString* familyName) const { 1631ba62629f4d8300eb5ff82a83807119032eb0c02bungeman@google.com SkOnce(&fFamilyNamesInited, &fFamilyNamesMutex, SkFontMgr_Indirect::set_up_family_names, this); 16472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (index >= fFamilyNames->count()) { 16572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com familyName->reset(); 16672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return; 16772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 16872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com familyName->set(fFamilyNames->atStr(index)); 16972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 17072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 17172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkFontStyleSet* SkFontMgr_Indirect::onCreateStyleSet(int index) const { 17272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkRemotableFontIdentitySet* set = fProxy->getIndex(index); 17372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (NULL == set) { 17472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return NULL; 17572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 17672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return SkNEW_ARGS(SkStyleSet_Indirect, (this, index, set)); 17772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 17872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 17972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkFontStyleSet* SkFontMgr_Indirect::onMatchFamily(const char familyName[]) const { 18072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return SkNEW_ARGS(SkStyleSet_Indirect, (this, -1, fProxy->matchName(familyName))); 18172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 18272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 18372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& id) const { 18472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (id.fDataId == SkFontIdentity::kInvalidDataId) { 18572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return NULL; 18672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 18772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 18872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoMutexAcquire ama(fDataCacheMutex); 18972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 19072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoTUnref<SkTypeface> dataTypeface; 19172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com int dataTypefaceIndex = 0; 19272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com for (int i = 0; i < fDataCache.count(); ++i) { 19372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const DataEntry& entry = fDataCache[i]; 19472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (entry.fDataId == id.fDataId) { 19572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (entry.fTtcIndex == id.fTtcIndex && 19672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref()) 19772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com { 19872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return entry.fTypeface; 19972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 20072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (dataTypeface.get() == NULL && 20172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com !entry.fTypeface->weak_expired() && entry.fTypeface->try_ref()) 20272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com { 20372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com dataTypeface.reset(entry.fTypeface); 20472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com dataTypefaceIndex = entry.fTtcIndex; 20572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 20672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 20772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 20872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (entry.fTypeface->weak_expired()) { 20972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com fDataCache.removeShuffle(i); 21072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com --i; 21172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 21272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 21372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 21472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // No exact match, but did find a data match. 21572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (dataTypeface.get() != NULL) { 21672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoTUnref<SkStream> stream(dataTypeface->openStream(NULL)); 21772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (stream.get() != NULL) { 21872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fImpl->createFromStream(stream.get(), dataTypefaceIndex); 21972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 22072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 22172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 22272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com // No data match, request data and add entry. 22372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoTUnref<SkStreamAsset> stream(fProxy->getData(id.fDataId)); 22472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (stream.get() == NULL) { 22572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return NULL; 22672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 22772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 22872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoTUnref<SkTypeface> typeface(fImpl->createFromStream(stream, id.fTtcIndex)); 22972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (typeface.get() == NULL) { 23072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return NULL; 23172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 23272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 23372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com DataEntry& newEntry = fDataCache.push_back(); 23472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com typeface->weak_ref(); 23572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com newEntry.fDataId = id.fDataId; 23672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com newEntry.fTtcIndex = id.fTtcIndex; 23772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com newEntry.fTypeface = typeface.get(); // weak reference passed to new entry. 23872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 23972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return typeface.detach(); 24072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 24172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 24272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onMatchFamilyStyle(const char familyName[], 24372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const SkFontStyle& fontStyle) const { 24472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontIdentity id = fProxy->matchNameStyle(familyName, fontStyle); 24572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return this->createTypefaceFromFontId(id); 24672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 24772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 24872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[], 24972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const SkFontStyle& style, 25072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const char bpc47[], 25172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com uint32_t character) const { 25272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bpc47, character); 25372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return this->createTypefaceFromFontId(id); 25472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 25572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 25672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onMatchFaceStyle(const SkTypeface* familyMember, 25772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com const SkFontStyle& fontStyle) const { 25872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkString familyName; 25972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com familyMember->getFamilyName(&familyName); 26072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return this->matchFamilyStyle(familyName.c_str(), fontStyle); 26172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 26272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 26372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onCreateFromStream(SkStream* stream, int ttcIndex) const { 26472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fImpl->createFromStream(stream, ttcIndex); 26572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 26672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 26772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onCreateFromFile(const char path[], int ttcIndex) const { 26872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fImpl->createFromFile(path, ttcIndex); 26972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 27072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 27172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onCreateFromData(SkData* data, int ttcIndex) const { 27272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return fImpl->createFromData(data, ttcIndex); 27372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 27472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 27572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.comSkTypeface* SkFontMgr_Indirect::onLegacyCreateTypeface(const char familyName[], 27672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com unsigned styleBits) const { 27772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com bool bold = SkToBool(styleBits & SkTypeface::kBold); 27872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com bool italic = SkToBool(styleBits & SkTypeface::kItalic); 27972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight 28072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com : SkFontStyle::kNormal_Weight, 28172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontStyle::kNormal_Width, 28272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com italic ? SkFontStyle::kItalic_Slant 28372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com : SkFontStyle::kUpright_Slant); 28472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 28572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkAutoTUnref<SkTypeface> face(this->matchFamilyStyle(familyName, style)); 28672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 28772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (NULL == face.get()) { 28872cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com face.reset(this->matchFamilyStyle(NULL, style)); 28972cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 29072cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 29172cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com if (NULL == face.get()) { 29272cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style); 29372cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com face.reset(this->createTypefaceFromFontId(fontId)); 29472cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com } 29572cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com 29672cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com return face.detach(); 29772cf4fcafa54cfa04c5ec7cb8eaa3acb144712ddbungeman@google.com} 298