Flutter Engine
The Flutter Engine
SkFontMgr_FontConfigInterface.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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
20#include <new>
21
22using namespace skia_private;
23
24std::unique_ptr<SkStreamAsset> SkTypeface_FCI::onOpenStream(int* ttcIndex) const {
25 *ttcIndex = this->getIdentity().fTTCIndex;
26 return std::unique_ptr<SkStreamAsset>(fFCI->openStream(this->getIdentity()));
27}
28
29std::unique_ptr<SkFontData> SkTypeface_FCI::onMakeFontData() const {
31 return std::make_unique<SkFontData>(std::unique_ptr<SkStreamAsset>(fFCI->openStream(id)),
32 id.fTTCIndex, 0, nullptr, 0, nullptr, 0);
33}
34
37 this->getFamilyName(&name);
38 desc->setFamilyName(name.c_str());
39 desc->setStyle(this->fontStyle());
41 *serialize = true;
42}
43
44///////////////////////////////////////////////////////////////////////////////
45
47public:
49
50 int count() override { return 0; }
51 void getStyle(int index, SkFontStyle*, SkString* style) override { SkASSERT(false); }
52 sk_sp<SkTypeface> createTypeface(int index) override { SkASSERT(false); return nullptr; }
53 sk_sp<SkTypeface> matchStyle(const SkFontStyle& pattern) override { return nullptr; }
54};
55
56///////////////////////////////////////////////////////////////////////////////
57
59public:
60 struct Request : public SkResourceCache::Key {
61 private:
62 Request(const char* name, size_t nameLen, const SkFontStyle& style) : fStyle(style) {
63 /** Pointer to just after the last field of this class. */
64 char* content = const_cast<char*>(SkTAfter<const char>(&this->fStyle));
65
66 // No holes.
67 SkASSERT(SkTAddOffset<char>(this, sizeof(SkResourceCache::Key) + keySize) == content);
68
69 // Has a size divisible by size of uint32_t.
70 SkASSERT((content - reinterpret_cast<char*>(this)) % sizeof(uint32_t) == 0);
71
72 size_t contentLen = SkAlign4(nameLen);
74 sk_bzero(content + nameLen, contentLen - nameLen);
75 this->init(nullptr, 0, keySize + contentLen);
76 }
77 const SkFontStyle fStyle;
78 /** The sum of the sizes of the fields of this class. */
79 static const size_t keySize = sizeof(fStyle);
80
81 public:
82 static Request* Create(const char* name, const SkFontStyle& style) {
83 size_t nameLen = name ? strlen(name) : 0;
84 size_t contentLen = SkAlign4(nameLen);
85 char* storage = new char[sizeof(Request) + contentLen];
86 return new (storage) Request(name, nameLen, style);
87 }
88 void operator delete(void* storage) {
89 delete[] reinterpret_cast<char*>(storage);
90 }
91 };
92
93
94private:
95 struct Result : public SkResourceCache::Rec {
96 Result(Request* request, sk_sp<SkTypeface> typeface)
97 : fRequest(request), fFace(std::move(typeface)) {}
98 Result(Result&&) = default;
99 Result& operator=(Result&&) = default;
100
101 const Key& getKey() const override { return *fRequest; }
102 size_t bytesUsed() const override { return fRequest->size() + sizeof(fFace); }
103 const char* getCategory() const override { return "request_cache"; }
104 SkDiscardableMemory* diagnostic_only_getDiscardable() const override { return nullptr; }
105
106 std::unique_ptr<Request> fRequest;
107 sk_sp<SkTypeface> fFace;
108 };
109
110 SkResourceCache fCachedResults;
111
112public:
113 SkFontRequestCache(size_t maxSize) : fCachedResults(maxSize) {}
114
115 /** Takes ownership of request. It will be deleted when no longer needed. */
116 void add(sk_sp<SkTypeface> face, Request* request) {
117 fCachedResults.add(new Result(request, std::move(face)));
118 }
119 /** Does not take ownership of request. */
122 fCachedResults.find(*request, [](const SkResourceCache::Rec& rec, void* context) -> bool {
123 const Result& result = static_cast<const Result&>(rec);
124 sk_sp<SkTypeface>* face = static_cast<sk_sp<SkTypeface>*>(context);
125
126 *face = result.fFace;
127 return true;
128 }, &face);
129 return face;
130 }
131};
132
133///////////////////////////////////////////////////////////////////////////////
134
135static bool find_by_FontIdentity(SkTypeface* cachedTypeface, void* ctx) {
136 typedef SkFontConfigInterface::FontIdentity FontIdentity;
137 SkTypeface_FCI* cachedFCTypeface = static_cast<SkTypeface_FCI*>(cachedTypeface);
138 FontIdentity* identity = static_cast<FontIdentity*>(ctx);
139
140 return cachedFCTypeface->getIdentity() == *identity;
141}
142
143///////////////////////////////////////////////////////////////////////////////
144
145class SkFontMgr_FCI : public SkFontMgr {
147
148 mutable SkMutex fMutex;
149 mutable SkTypefaceCache fTFCache;
150
151 // The value of maxSize here is a compromise between cache hits and cache size.
152 // See https://crbug.com/424082#63 for reason for current size.
153 static const size_t kMaxSize = 1 << 15;
154 mutable SkFontRequestCache fCache;
155
156public:
158 : fFCI(std::move(fci))
159 , fCache(kMaxSize)
160 {
161 SkASSERT_RELEASE(fFCI);
162 }
163
164protected:
165 int onCountFamilies() const override {
166 SK_ABORT("Not implemented.");
167 }
168
169 void onGetFamilyName(int index, SkString* familyName) const override {
170 SK_ABORT("Not implemented.");
171 }
172
173 sk_sp<SkFontStyleSet> onCreateStyleSet(int index) const override {
174 SK_ABORT("Not implemented.");
175 }
176
177 sk_sp<SkFontStyleSet> onMatchFamily(const char familyName[]) const override {
178 SK_ABORT("Not implemented.");
179 }
180
181 sk_sp<SkTypeface> onMatchFamilyStyle(const char requestedFamilyName[],
182 const SkFontStyle& requestedStyle) const override
183 {
184 SkAutoMutexExclusive ama(fMutex);
185
186 // Check if this request is already in the request cache.
187 using Request = SkFontRequestCache::Request;
188 std::unique_ptr<Request> request(Request::Create(requestedFamilyName, requestedStyle));
189 sk_sp<SkTypeface> face = fCache.findAndRef(request.get());
190 if (face) {
191 return sk_sp<SkTypeface>(face);
192 }
193
195 SkString outFamilyName;
196 SkFontStyle outStyle;
197 if (!fFCI->matchFamilyName(requestedFamilyName, requestedStyle,
198 &identity, &outFamilyName, &outStyle))
199 {
200 return nullptr;
201 }
202
203 // Check if a typeface with this FontIdentity is already in the FontIdentity cache.
205 if (!face) {
206 face.reset(SkTypeface_FCI::Create(fFCI, identity, std::move(outFamilyName), outStyle));
207 // Add this FontIdentity to the FontIdentity cache.
208 fTFCache.add(face);
209 }
210 // Add this request to the request cache.
211 fCache.add(face, request.release());
212
213 return face;
214 }
215
217 const char* bcp47[], int bcp47Count,
218 SkUnichar character) const override {
219 SK_ABORT("Not implemented.");
220 }
221
222 sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData> data, int ttcIndex) const override {
223 return this->onMakeFromStreamIndex(SkMemoryStream::Make(std::move(data)), ttcIndex);
224 }
225
226 sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset> stream,
227 int ttcIndex) const override {
228 return this->makeFromStream(std::move(stream),
229 SkFontArguments().setCollectionIndex(ttcIndex));
230 }
231
232 sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
233 const SkFontArguments& args) const override {
234 const size_t length = stream->getLength();
235 if (!length) {
236 return nullptr;
237 }
238 if (length >= 1024 * 1024 * 1024) {
239 return nullptr; // don't accept too large fonts (>= 1GB) for safety.
240 }
241
243 }
244
245 sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override {
246 std::unique_ptr<SkStreamAsset> stream = SkStream::MakeFromFile(path);
247 return stream ? this->makeFromStream(std::move(stream), ttcIndex) : nullptr;
248 }
249
250 sk_sp<SkTypeface> onLegacyMakeTypeface(const char requestedFamilyName[],
251 SkFontStyle requestedStyle) const override {
252 return this->onMatchFamilyStyle(requestedFamilyName, requestedStyle);
253 }
254};
255
257 SkASSERT(fci);
258 return sk_make_sp<SkFontMgr_FCI>(std::move(fci));
259}
SkStrokeRec::Style fStyle
sk_bzero(glyphs, sizeof(glyphs))
static sk_sp< Effect > Create()
Definition: RefCntTest.cpp:117
#define SK_API
Definition: SkAPI.h:35
static constexpr T SkAlign4(T x)
Definition: SkAlign.h:16
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
#define SkASSERT(cond)
Definition: SkAssert.h:116
SK_API sk_sp< SkFontMgr > SkFontMgr_New_FCI(sk_sp< SkFontConfigInterface > fci)
static bool find_by_FontIdentity(SkTypeface *cachedTypeface, void *ctx)
static void * sk_careful_memcpy(void *dst, const void *src, size_t len)
Definition: SkMalloc.h:125
int32_t SkUnichar
Definition: SkTypes.h:175
virtual SkStreamAsset * openStream(const FontIdentity &)=0
virtual bool matchFamilyName(const char familyName[], SkFontStyle requested, FontIdentity *outFontIdentifier, SkString *outFamilyName, SkFontStyle *outStyle)=0
void setFactoryId(SkTypeface::FactoryId factoryId)
sk_sp< SkTypeface > onMakeFromData(sk_sp< SkData > data, int ttcIndex) const override
sk_sp< SkTypeface > onMakeFromStreamIndex(std::unique_ptr< SkStreamAsset > stream, int ttcIndex) const override
sk_sp< SkTypeface > onMatchFamilyStyle(const char requestedFamilyName[], const SkFontStyle &requestedStyle) const override
sk_sp< SkTypeface > onMakeFromFile(const char path[], int ttcIndex) const override
sk_sp< SkFontStyleSet > onMatchFamily(const char familyName[]) const override
SkFontMgr_FCI(sk_sp< SkFontConfigInterface > fci)
int onCountFamilies() const override
sk_sp< SkTypeface > onMakeFromStreamArgs(std::unique_ptr< SkStreamAsset > stream, const SkFontArguments &args) const override
sk_sp< SkFontStyleSet > onCreateStyleSet(int index) const override
void onGetFamilyName(int index, SkString *familyName) const override
sk_sp< SkTypeface > onLegacyMakeTypeface(const char requestedFamilyName[], SkFontStyle requestedStyle) const override
sk_sp< SkTypeface > onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle &, const char *bcp47[], int bcp47Count, SkUnichar character) const override
sk_sp< SkTypeface > makeFromStream(std::unique_ptr< SkStreamAsset >, int ttcIndex=0) const
Definition: SkFontMgr.cpp:127
void add(sk_sp< SkTypeface > face, Request *request)
sk_sp< SkTypeface > findAndRef(Request *request)
sk_sp< SkTypeface > createTypeface(int index) override
void getStyle(int index, SkFontStyle *, SkString *style) override
sk_sp< SkTypeface > matchStyle(const SkFontStyle &pattern) override
static std::unique_ptr< SkMemoryStream > Make(sk_sp< SkData > data)
Definition: SkStream.cpp:314
bool find(const Key &, FindVisitor, void *context)
void add(Rec *, void *payload=nullptr)
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
Definition: SkStream.cpp:922
sk_sp< SkTypeface > findByProcAndRef(FindProc proc, void *ctx) const
void add(sk_sp< SkTypeface >)
const SkFontConfigInterface::FontIdentity & getIdentity() const
void onGetFontDescriptor(SkFontDescriptor *, bool *) const override
std::unique_ptr< SkStreamAsset > onOpenStream(int *ttcIndex) const override
std::unique_ptr< SkFontData > onMakeFontData() const override
static SkTypeface_FCI * Create(sk_sp< SkFontConfigInterface > fci, const SkFontConfigInterface::FontIdentity &fi, SkString familyName, const SkFontStyle &style)
static sk_sp< SkTypeface > MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
void getFamilyName(SkString *name) const
Definition: SkTypeface.cpp:459
SkFontStyle fontStyle() const
Definition: SkTypeface.h:55
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
Definition: SkTypeface.cpp:202
SkFourByteTag FactoryId
Definition: SkTypeface.h:335
T * release()
Definition: SkRefCnt.h:324
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
int size() const
Definition: SkTArray.h:421
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
size_t length
union flutter::testing::@2836::KeyboardChange::@76 content
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
Definition: ref_ptr.h:256
static Request * Create(const char *name, const SkFontStyle &style)
void init(void *nameSpace, uint64_t sharedID, size_t dataSize)
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63