blob: 98889b6abdf5e6ef93723f211fab0c9f5fb28d5b [file] [log] [blame]
bungeman@google.com72cf4fc2014-03-21 22:48:32 +00001/*
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
bungemanf20488b2015-07-29 11:49:40 -07008#include "SkFontMgr.h"
9#include "SkFontMgr_indirect.h"
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000010#include "SkFontStyle.h"
bungemanf20488b2015-07-29 11:49:40 -070011#include "SkMutex.h"
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000012#include "SkOnce.h"
bungemanf20488b2015-07-29 11:49:40 -070013#include "SkRefCnt.h"
14#include "SkRemotableFontMgr.h"
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000015#include "SkStream.h"
bungemanf20488b2015-07-29 11:49:40 -070016#include "SkString.h"
17#include "SkTArray.h"
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000018#include "SkTypeface.h"
bungemanf20488b2015-07-29 11:49:40 -070019#include "SkTypes.h"
20#include "SkTemplates.h"
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000021
22class SkData;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000023
24class SkStyleSet_Indirect : public SkFontStyleSet {
25public:
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
mtklein36352bf2015-03-25 18:17:31 -070032 int count() override { return fData->count(); }
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000033
mtklein36352bf2015-03-25 18:17:31 -070034 void getStyle(int index, SkFontStyle* fs, SkString* style) override {
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000035 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
mtklein36352bf2015-03-25 18:17:31 -070044 SkTypeface* createTypeface(int index) override {
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000045 return fOwner->createTypefaceFromFontId(fData->at(index));
46 }
47
mtklein36352bf2015-03-25 18:17:31 -070048 SkTypeface* matchStyle(const SkFontStyle& pattern) override {
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000049 if (fFamilyIndex >= 0) {
50 SkFontIdentity id = fOwner->fProxy->matchIndexStyle(fFamilyIndex, pattern);
51 return fOwner->createTypefaceFromFontId(id);
52 }
53
bungeman147ea2f2015-11-12 09:50:08 -080054 return this->matchStyleCSS3(pattern);
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000055 }
56private:
Hal Canary67b39de2016-11-07 11:47:44 -050057 sk_sp<const SkFontMgr_Indirect> fOwner;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000058 int fFamilyIndex;
Hal Canary67b39de2016-11-07 11:47:44 -050059 sk_sp<SkRemotableFontIdentitySet> fData;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000060};
61
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000062int SkFontMgr_Indirect::onCountFamilies() const {
Herb Derby9adfef82017-01-20 16:07:52 -050063 return 0;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000064}
65
66void SkFontMgr_Indirect::onGetFamilyName(int index, SkString* familyName) const {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040067 SK_ABORT("Not implemented");
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000068}
69
70SkFontStyleSet* SkFontMgr_Indirect::onCreateStyleSet(int index) const {
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040071 SK_ABORT("Not implemented");
Herb Derby9adfef82017-01-20 16:07:52 -050072 return nullptr;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000073}
74
75SkFontStyleSet* SkFontMgr_Indirect::onMatchFamily(const char familyName[]) const {
halcanary385fe4d2015-08-26 13:07:48 -070076 return new SkStyleSet_Indirect(this, -1, fProxy->matchName(familyName));
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000077}
78
79SkTypeface* SkFontMgr_Indirect::createTypefaceFromFontId(const SkFontIdentity& id) const {
80 if (id.fDataId == SkFontIdentity::kInvalidDataId) {
halcanary96fcdcc2015-08-27 07:41:13 -070081 return nullptr;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000082 }
83
84 SkAutoMutexAcquire ama(fDataCacheMutex);
85
Hal Canary67b39de2016-11-07 11:47:44 -050086 sk_sp<SkTypeface> dataTypeface;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000087 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 }
halcanary96fcdcc2015-08-27 07:41:13 -070096 if (dataTypeface.get() == nullptr &&
bungeman@google.com72cf4fc2014-03-21 22:48:32 +000097 !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.
halcanary96fcdcc2015-08-27 07:41:13 -0700111 if (dataTypeface.get() != nullptr) {
Ben Wagner145dbcd2016-11-03 14:40:50 -0400112 std::unique_ptr<SkStreamAsset> stream(dataTypeface->openStream(nullptr));
halcanary96fcdcc2015-08-27 07:41:13 -0700113 if (stream.get() != nullptr) {
Mike Reed59227392017-09-26 09:46:08 -0400114 return fImpl->makeFromStream(std::move(stream), dataTypefaceIndex).release();
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000115 }
116 }
117
118 // No data match, request data and add entry.
Ben Wagner145dbcd2016-11-03 14:40:50 -0400119 std::unique_ptr<SkStreamAsset> stream(fProxy->getData(id.fDataId));
halcanary96fcdcc2015-08-27 07:41:13 -0700120 if (stream.get() == nullptr) {
121 return nullptr;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000122 }
123
Mike Reed59227392017-09-26 09:46:08 -0400124 sk_sp<SkTypeface> typeface(fImpl->makeFromStream(std::move(stream), id.fTtcIndex));
halcanary96fcdcc2015-08-27 07:41:13 -0700125 if (typeface.get() == nullptr) {
126 return nullptr;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000127 }
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
mtklein18300a32016-03-16 13:53:35 -0700135 return typeface.release();
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000136}
137
138SkTypeface* 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
144SkTypeface* SkFontMgr_Indirect::onMatchFamilyStyleCharacter(const char familyName[],
145 const SkFontStyle& style,
bungemanc20386e2014-10-23 07:08:05 -0700146 const char* bcp47[],
147 int bcp47Count,
148 SkUnichar character) const {
149 SkFontIdentity id = fProxy->matchNameStyleCharacter(familyName, style, bcp47,
150 bcp47Count, character);
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000151 return this->createTypefaceFromFontId(id);
152}
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000153
154SkTypeface* 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
Mike Reed59227392017-09-26 09:46:08 -0400161sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
162 int ttcIndex) const {
163 return fImpl->makeFromStream(std::move(stream), ttcIndex);
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000164}
165
Mike Reed59227392017-09-26 09:46:08 -0400166sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromFile(const char path[], int ttcIndex) const {
167 return fImpl->makeFromFile(path, ttcIndex);
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000168}
169
Mike Reed59227392017-09-26 09:46:08 -0400170sk_sp<SkTypeface> SkFontMgr_Indirect::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
171 return fImpl->makeFromData(std::move(data), ttcIndex);
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000172}
173
Mike Reed59227392017-09-26 09:46:08 -0400174sk_sp<SkTypeface> SkFontMgr_Indirect::onLegacyMakeTypeface(const char familyName[],
175 SkFontStyle style) const {
Hal Canary67b39de2016-11-07 11:47:44 -0500176 sk_sp<SkTypeface> face(this->matchFamilyStyle(familyName, style));
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000177
halcanary96fcdcc2015-08-27 07:41:13 -0700178 if (nullptr == face.get()) {
179 face.reset(this->matchFamilyStyle(nullptr, style));
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000180 }
181
halcanary96fcdcc2015-08-27 07:41:13 -0700182 if (nullptr == face.get()) {
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000183 SkFontIdentity fontId = this->fProxy->matchIndexStyle(0, style);
184 face.reset(this->createTypefaceFromFontId(fontId));
185 }
186
Mike Reed59227392017-09-26 09:46:08 -0400187 return face;
bungeman@google.com72cf4fc2014-03-21 22:48:32 +0000188}