Flutter Engine
The Flutter Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SkDWriteFontFileStream.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 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 */
8#if defined(SK_BUILD_FOR_WIN)
9
16
17#include <dwrite.h>
18
19using namespace skia_private;
20
21///////////////////////////////////////////////////////////////////////////////
22// SkIDWriteFontFileStream
23
24SkDWriteFontFileStream::SkDWriteFontFileStream(IDWriteFontFileStream* fontFileStream)
25 : fFontFileStream(SkRefComPtr(fontFileStream))
26 , fPos(0)
27 , fLockedMemory(nullptr)
28 , fFragmentLock(nullptr) {
29}
30
32 if (fFragmentLock) {
33 fFontFileStream->ReleaseFileFragment(fFragmentLock);
34 }
35}
36
37size_t SkDWriteFontFileStream::read(void* buffer, size_t size) {
38 HRESULT hr = S_OK;
39
40 if (nullptr == buffer) {
41 size_t fileSize = this->getLength();
42
43 if (fPos + size > fileSize) {
44 size_t skipped = fileSize - fPos;
45 fPos = fileSize;
46 return skipped;
47 } else {
48 fPos += size;
49 return size;
50 }
51 }
52
53 const void* start;
54 void* fragmentLock;
55 hr = fFontFileStream->ReadFileFragment(&start, fPos, size, &fragmentLock);
56 if (SUCCEEDED(hr)) {
57 memcpy(buffer, start, size);
58 fFontFileStream->ReleaseFileFragment(fragmentLock);
59 fPos += size;
60 return size;
61 }
62
63 //The read may have failed because we asked for too much data.
64 size_t fileSize = this->getLength();
65 if (fPos + size <= fileSize) {
66 //This means we were within bounds, but failed for some other reason.
67 return 0;
68 }
69
70 size_t read = fileSize - fPos;
71 hr = fFontFileStream->ReadFileFragment(&start, fPos, read, &fragmentLock);
72 if (SUCCEEDED(hr)) {
73 memcpy(buffer, start, read);
74 fFontFileStream->ReleaseFileFragment(fragmentLock);
75 fPos = fileSize;
76 return read;
77 }
78
79 return 0;
80}
81
83 return fPos == this->getLength();
84}
85
87 fPos = 0;
88 return true;
89}
90
91SkDWriteFontFileStream* SkDWriteFontFileStream::onDuplicate() const {
92 return new SkDWriteFontFileStream(fFontFileStream.get());
93}
94
96 return fPos;
97}
98
99bool SkDWriteFontFileStream::seek(size_t position) {
100 size_t length = this->getLength();
101 fPos = (position > length) ? length : position;
102 return true;
103}
104
106 return seek(fPos + offset);
107}
108
109SkDWriteFontFileStream* SkDWriteFontFileStream::onFork() const {
110 std::unique_ptr<SkDWriteFontFileStream> that(this->duplicate());
111 that->seek(fPos);
112 return that.release();
113}
114
116 UINT64 realFileSize = 0;
117 fFontFileStream->GetFileSize(&realFileSize);
118 if (!SkTFitsIn<size_t>(realFileSize)) {
119 return 0;
120 }
121 return static_cast<size_t>(realFileSize);
122}
123
125 if (fLockedMemory) {
126 return fLockedMemory;
127 }
128
129 UINT64 fileSize;
130 HRNM(fFontFileStream->GetFileSize(&fileSize), "Could not get file size");
131 HRNM(fFontFileStream->ReadFileFragment(&fLockedMemory, 0, fileSize, &fFragmentLock),
132 "Could not lock file fragment.");
133 return fLockedMemory;
134}
135
136///////////////////////////////////////////////////////////////////////////////
137// SkIDWriteFontFileStreamWrapper
138
140 SkDWriteFontFileStreamWrapper** streamFontFileStream)
141{
142 *streamFontFileStream = new SkDWriteFontFileStreamWrapper(stream);
143 if (nullptr == *streamFontFileStream) {
144 return E_OUTOFMEMORY;
145 }
146 return S_OK;
147}
148
149SkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStreamAsset* stream)
150 : fRefCount(1), fStream(stream) {
151}
152
154 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
155 *ppvObject = this;
156 AddRef();
157 return S_OK;
158 } else {
159 *ppvObject = nullptr;
160 return E_NOINTERFACE;
161 }
162}
163
164SK_STDMETHODIMP_(ULONG) SkDWriteFontFileStreamWrapper::AddRef() {
165 return InterlockedIncrement(&fRefCount);
166}
167
168SK_STDMETHODIMP_(ULONG) SkDWriteFontFileStreamWrapper::Release() {
169 ULONG newCount = InterlockedDecrement(&fRefCount);
170 if (0 == newCount) {
171 delete this;
172 }
173 return newCount;
174}
175
177 void const** fragmentStart,
178 UINT64 fileOffset,
179 UINT64 fragmentSize,
180 void** fragmentContext)
181{
182 // The loader is responsible for doing a bounds check.
183 UINT64 fileSize;
184 this->GetFileSize(&fileSize);
185 if (fileOffset > fileSize || fragmentSize > fileSize - fileOffset) {
186 *fragmentStart = nullptr;
187 *fragmentContext = nullptr;
188 return E_FAIL;
189 }
190
191 if (!SkTFitsIn<size_t>(fileOffset + fragmentSize)) {
192 return E_FAIL;
193 }
194
195 const void* data = fStream->getMemoryBase();
196 if (data) {
197 *fragmentStart = static_cast<BYTE const*>(data) + static_cast<size_t>(fileOffset);
198 *fragmentContext = nullptr;
199
200 } else {
201 // May be called from multiple threads.
202 SkAutoMutexExclusive ama(fStreamMutex);
203
204 *fragmentStart = nullptr;
205 *fragmentContext = nullptr;
206
207 if (!fStream->seek(static_cast<size_t>(fileOffset))) {
208 return E_FAIL;
209 }
210 AutoTMalloc<uint8_t> streamData(static_cast<size_t>(fragmentSize));
211 if (fStream->read(streamData.get(), static_cast<size_t>(fragmentSize)) != fragmentSize) {
212 return E_FAIL;
213 }
214
215 *fragmentStart = streamData.get();
216 *fragmentContext = streamData.release();
217 }
218 return S_OK;
219}
220
221SK_STDMETHODIMP_(void) SkDWriteFontFileStreamWrapper::ReleaseFileFragment(void* fragmentContext) {
222 sk_free(fragmentContext);
223}
224
226 *fileSize = fStream->getLength();
227 return S_OK;
228}
229
231 // The concept of last write time does not apply to this loader.
232 *lastWriteTime = 0;
233 return E_NOTIMPL;
234}
235
236#endif//defined(SK_BUILD_FOR_WIN)
SK_API void sk_free(void *)
#define SK_STDMETHODIMP_(type)
Definition: SkObjBase.h:23
#define SK_STDMETHODIMP
Definition: SkObjBase.h:22
static HRESULT Create(SkStreamAsset *stream, SkDWriteFontFileStreamWrapper **streamFontFileStream)
SK_STDMETHODIMP GetFileSize(UINT64 *fileSize) override
SK_STDMETHODIMP ReadFileFragment(void const **fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, void **fragmentContext) override
SK_STDMETHODIMP QueryInterface(REFIID iid, void **ppvObject) override
SK_STDMETHODIMP GetLastWriteTime(UINT64 *lastWriteTime) override
bool isAtEnd() const override
bool rewind() override
size_t read(void *buffer, size_t size) override
bool move(long offset) override
SkDWriteFontFileStream(IDWriteFontFileStream *fontFileStream)
size_t getLength() const override
bool seek(size_t position) override
const void * getMemoryBase() override
~SkDWriteFontFileStream() override
size_t getPosition() const override
std::unique_ptr< SkDWriteFontFileStream > duplicate() const
size_t length
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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
SeparatedVector2 offset
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
#define SUCCEEDED(hr)
unsigned char BYTE
Definition: windows_types.h:38
DWORD ULONG
Definition: windows_types.h:40