OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkTypes.h" | 8 #include "SkTypes.h" |
9 #include "SkDWriteFontFileStream.h" | 9 #include "SkDWriteFontFileStream.h" |
10 #include "SkHRESULT.h" | 10 #include "SkHRESULT.h" |
| 11 #include "SkTScopedComPtr.h" |
11 | 12 |
12 #include <dwrite.h> | 13 #include <dwrite.h> |
13 #include <limits> | 14 #include <limits> |
14 | 15 |
15 /////////////////////////////////////////////////////////////////////////////// | 16 /////////////////////////////////////////////////////////////////////////////// |
16 // SkIDWriteFontFileStream | 17 // SkIDWriteFontFileStream |
17 | 18 |
18 SkDWriteFontFileStream::SkDWriteFontFileStream(IDWriteFontFileStream* fontFileSt
ream) | 19 SkDWriteFontFileStream::SkDWriteFontFileStream(IDWriteFontFileStream* fontFileSt
ream) |
19 : fFontFileStream(fontFileStream) | 20 : fFontFileStream(SkRefComPtr(fontFileStream)) |
20 , fPos(0) | 21 , fPos(0) |
21 , fLockedMemory(NULL) | 22 , fLockedMemory(NULL) |
22 , fFragmentLock(NULL) { | 23 , fFragmentLock(NULL) { |
23 fontFileStream->AddRef(); | |
24 } | 24 } |
25 | 25 |
26 SkDWriteFontFileStream::~SkDWriteFontFileStream() { | 26 SkDWriteFontFileStream::~SkDWriteFontFileStream() { |
27 if (fFragmentLock) { | 27 if (fFragmentLock) { |
28 fFontFileStream->ReleaseFileFragment(fFragmentLock); | 28 fFontFileStream->ReleaseFileFragment(fFragmentLock); |
29 } | 29 } |
30 } | 30 } |
31 | 31 |
32 const void* SkDWriteFontFileStream::getMemoryBase() { | |
33 if (fLockedMemory) { | |
34 return fLockedMemory; | |
35 } | |
36 | |
37 UINT64 fileSize; | |
38 HRNM(fFontFileStream->GetFileSize(&fileSize), "Could not get file size"); | |
39 HRNM(fFontFileStream->ReadFileFragment(&fLockedMemory, 0, fileSize, &fFragme
ntLock), | |
40 "Could not lock file fragment."); | |
41 return fLockedMemory; | |
42 } | |
43 | |
44 bool SkDWriteFontFileStream::rewind() { | |
45 fPos = 0; | |
46 return true; | |
47 } | |
48 | |
49 size_t SkDWriteFontFileStream::read(void* buffer, size_t size) { | 32 size_t SkDWriteFontFileStream::read(void* buffer, size_t size) { |
50 HRESULT hr = S_OK; | 33 HRESULT hr = S_OK; |
51 | 34 |
52 if (NULL == buffer) { | 35 if (NULL == buffer) { |
53 UINT64 realFileSize = 0; | 36 size_t fileSize = this->getLength(); |
54 hr = fFontFileStream->GetFileSize(&realFileSize); | 37 |
55 if (realFileSize > (std::numeric_limits<size_t>::max)()) { | 38 if (fPos + size > fileSize) { |
56 return 0; | 39 size_t skipped = fileSize - fPos; |
57 } | 40 fPos = fileSize; |
58 size_t fileSize = static_cast<size_t>(realFileSize); | 41 return skipped; |
59 if (size == 0) { | |
60 return fileSize; | |
61 } else { | 42 } else { |
62 if (fPos + size > fileSize) { | 43 fPos += size; |
63 size_t skipped = fileSize - fPos; | 44 return size; |
64 fPos = fileSize; | |
65 return skipped; | |
66 } else { | |
67 fPos += size; | |
68 return size; | |
69 } | |
70 } | 45 } |
71 } | 46 } |
72 | 47 |
73 const void* start; | 48 const void* start; |
74 void* fragmentLock; | 49 void* fragmentLock; |
75 hr = fFontFileStream->ReadFileFragment(&start, fPos, size, &fragmentLock); | 50 hr = fFontFileStream->ReadFileFragment(&start, fPos, size, &fragmentLock); |
76 if (SUCCEEDED(hr)) { | 51 if (SUCCEEDED(hr)) { |
77 memcpy(buffer, start, size); | 52 memcpy(buffer, start, size); |
78 fFontFileStream->ReleaseFileFragment(fragmentLock); | 53 fFontFileStream->ReleaseFileFragment(fragmentLock); |
79 fPos += size; | 54 fPos += size; |
80 return size; | 55 return size; |
81 } | 56 } |
82 | 57 |
83 //The read may have failed because we asked for too much data. | 58 //The read may have failed because we asked for too much data. |
| 59 size_t fileSize = this->getLength(); |
| 60 if (fPos + size <= fileSize) { |
| 61 //This means we were within bounds, but failed for some other reason. |
| 62 return 0; |
| 63 } |
| 64 |
| 65 size_t read = fileSize - fPos; |
| 66 hr = fFontFileStream->ReadFileFragment(&start, fPos, read, &fragmentLock); |
| 67 if (SUCCEEDED(hr)) { |
| 68 memcpy(buffer, start, read); |
| 69 fFontFileStream->ReleaseFileFragment(fragmentLock); |
| 70 fPos = fileSize; |
| 71 return read; |
| 72 } |
| 73 |
| 74 return 0; |
| 75 } |
| 76 |
| 77 bool SkDWriteFontFileStream::atEnd() const { |
| 78 return fPos == this->getLength(); |
| 79 } |
| 80 |
| 81 bool SkDWriteFontFileStream::rewind() { |
| 82 fPos = 0; |
| 83 return true; |
| 84 } |
| 85 |
| 86 SkDWriteFontFileStream* SkDWriteFontFileStream::duplicate() const { |
| 87 return SkNEW_ARGS(SkDWriteFontFileStream, (fFontFileStream.get())); |
| 88 } |
| 89 |
| 90 size_t SkDWriteFontFileStream::getPosition() const { |
| 91 return fPos; |
| 92 } |
| 93 |
| 94 bool SkDWriteFontFileStream::seek(size_t position) { |
| 95 size_t length = this->getLength(); |
| 96 fPos = (position > length) ? length : position; |
| 97 return true; |
| 98 } |
| 99 |
| 100 bool SkDWriteFontFileStream::move(long offset) { |
| 101 return seek(fPos + offset); |
| 102 } |
| 103 |
| 104 SkDWriteFontFileStream* SkDWriteFontFileStream::fork() const { |
| 105 SkAutoTUnref<SkDWriteFontFileStream> that(this->duplicate()); |
| 106 that->seek(fPos); |
| 107 return that.detach(); |
| 108 } |
| 109 |
| 110 size_t SkDWriteFontFileStream::getLength() const { |
| 111 HRESULT hr = S_OK; |
84 UINT64 realFileSize = 0; | 112 UINT64 realFileSize = 0; |
85 hr = fFontFileStream->GetFileSize(&realFileSize); | 113 hr = fFontFileStream->GetFileSize(&realFileSize); |
86 if (realFileSize > (std::numeric_limits<size_t>::max)()) { | 114 if (realFileSize > (std::numeric_limits<size_t>::max)()) { |
87 return 0; | 115 return 0; |
88 } | 116 } |
89 size_t fileSize = static_cast<size_t>(realFileSize); | 117 return static_cast<size_t>(realFileSize); |
90 if (fPos + size > fileSize) { | |
91 size_t read = fileSize - fPos; | |
92 hr = fFontFileStream->ReadFileFragment(&start, fPos, read, &fragmentLock
); | |
93 if (SUCCEEDED(hr)) { | |
94 memcpy(buffer, start, read); | |
95 fFontFileStream->ReleaseFileFragment(fragmentLock); | |
96 fPos = fileSize; | |
97 return read; | |
98 } | |
99 return 0; | |
100 } else { | |
101 //This means we were within bounds, but failed for some other reason. | |
102 return 0; | |
103 } | |
104 } | 118 } |
105 | 119 |
| 120 const void* SkDWriteFontFileStream::getMemoryBase() { |
| 121 if (fLockedMemory) { |
| 122 return fLockedMemory; |
| 123 } |
| 124 |
| 125 UINT64 fileSize; |
| 126 HRNM(fFontFileStream->GetFileSize(&fileSize), "Could not get file size"); |
| 127 HRNM(fFontFileStream->ReadFileFragment(&fLockedMemory, 0, fileSize, &fFragme
ntLock), |
| 128 "Could not lock file fragment."); |
| 129 return fLockedMemory; |
| 130 } |
106 | 131 |
107 /////////////////////////////////////////////////////////////////////////////// | 132 /////////////////////////////////////////////////////////////////////////////// |
108 // SkIDWriteFontFileStreamWrapper | 133 // SkIDWriteFontFileStreamWrapper |
109 | 134 |
110 HRESULT SkDWriteFontFileStreamWrapper::Create(SkStream* stream, SkDWriteFontFile
StreamWrapper** streamFontFileStream) { | 135 HRESULT SkDWriteFontFileStreamWrapper::Create(SkStream* stream, SkDWriteFontFile
StreamWrapper** streamFontFileStream) { |
111 *streamFontFileStream = new SkDWriteFontFileStreamWrapper(stream); | 136 *streamFontFileStream = new SkDWriteFontFileStreamWrapper(stream); |
112 if (NULL == streamFontFileStream) { | 137 if (NULL == streamFontFileStream) { |
113 return E_OUTOFMEMORY; | 138 return E_OUTOFMEMORY; |
114 } | 139 } |
115 return S_OK; | 140 return S_OK; |
116 } | 141 } |
117 | 142 |
118 SkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStream* stream) | 143 SkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStream* stream) |
119 : fRefCount(1), fStream(stream) { | 144 : fRefCount(1), fStream(SkRef(stream)) { |
120 stream->ref(); | |
121 } | 145 } |
122 | 146 |
123 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::QueryInterface(REFIID i
id, void** ppvObject) { | 147 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::QueryInterface(REFIID i
id, void** ppvObject) { |
124 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { | 148 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { |
125 *ppvObject = this; | 149 *ppvObject = this; |
126 AddRef(); | 150 AddRef(); |
127 return S_OK; | 151 return S_OK; |
128 } else { | 152 } else { |
129 *ppvObject = NULL; | 153 *ppvObject = NULL; |
130 return E_NOINTERFACE; | 154 return E_NOINTERFACE; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 | 197 |
174 *fragmentStart = NULL; | 198 *fragmentStart = NULL; |
175 *fragmentContext = NULL; | 199 *fragmentContext = NULL; |
176 | 200 |
177 if (!fStream->rewind()) { | 201 if (!fStream->rewind()) { |
178 return E_FAIL; | 202 return E_FAIL; |
179 } | 203 } |
180 if (fStream->skip(static_cast<size_t>(fileOffset)) != fileOffset) { | 204 if (fStream->skip(static_cast<size_t>(fileOffset)) != fileOffset) { |
181 return E_FAIL; | 205 return E_FAIL; |
182 } | 206 } |
183 SkAutoTDeleteArray<uint8_t> streamData(new uint8_t[static_cast<size_t>(f
ragmentSize)]); | 207 SkAutoTMalloc<uint8_t> streamData(static_cast<size_t>(fragmentSize)); |
184 if (fStream->read(streamData.get(), static_cast<size_t>(fragmentSize)) !
= fragmentSize) { | 208 if (fStream->read(streamData.get(), static_cast<size_t>(fragmentSize)) !
= fragmentSize) { |
185 return E_FAIL; | 209 return E_FAIL; |
186 } | 210 } |
187 | 211 |
188 *fragmentStart = streamData.get(); | 212 *fragmentStart = streamData.get(); |
189 *fragmentContext = streamData.detach(); | 213 *fragmentContext = streamData.detach(); |
190 } | 214 } |
191 return S_OK; | 215 return S_OK; |
192 } | 216 } |
193 | 217 |
194 void STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::ReleaseFileFragment(void*
fragmentContext) { | 218 void STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::ReleaseFileFragment(void*
fragmentContext) { |
195 if (NULL == fragmentContext) { | 219 sk_free(fragmentContext); |
196 return; | |
197 } | |
198 delete [] fragmentContext; | |
199 } | 220 } |
200 | 221 |
201 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetFileSize(UINT64* fil
eSize) { | 222 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetFileSize(UINT64* fil
eSize) { |
202 *fileSize = fStream->getLength(); | 223 *fileSize = fStream->getLength(); |
203 return S_OK; | 224 return S_OK; |
204 } | 225 } |
205 | 226 |
206 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetLastWriteTime(UINT64
* lastWriteTime) { | 227 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetLastWriteTime(UINT64
* lastWriteTime) { |
207 // The concept of last write time does not apply to this loader. | 228 // The concept of last write time does not apply to this loader. |
208 *lastWriteTime = 0; | 229 *lastWriteTime = 0; |
209 return E_NOTIMPL; | 230 return E_NOTIMPL; |
210 } | 231 } |
OLD | NEW |