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