Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
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
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
SkDWriteFontFileStream * onDuplicate() const 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
SkDWriteFontFileStream * onFork() 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
static const uint8_t buffer[]
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 data
Definition switches.h:41
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
Point offset
#define SUCCEEDED(hr)
unsigned char BYTE
DWORD ULONG