180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypes.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkDWriteFontFileStream.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkHRESULT.h" 1158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTemplates.h" 1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTFitsIn.h" 1358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkTScopedComPtr.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <dwrite.h> 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// SkIDWriteFontFileStream 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDWriteFontFileStream::SkDWriteFontFileStream(IDWriteFontFileStream* fontFileStream) 2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger : fFontFileStream(SkRefComPtr(fontFileStream)) 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fPos(0) 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fLockedMemory(NULL) 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fFragmentLock(NULL) { 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDWriteFontFileStream::~SkDWriteFontFileStream() { 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fFragmentLock) { 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFontFileStream->ReleaseFileFragment(fFragmentLock); 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t SkDWriteFontFileStream::read(void* buffer, size_t size) { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru HRESULT hr = S_OK; 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == buffer) { 3758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t fileSize = this->getLength(); 3858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 3958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (fPos + size > fileSize) { 4058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t skipped = fileSize - fPos; 4158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPos = fileSize; 4258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return skipped; 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 4458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPos += size; 4558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return size; 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const void* start; 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* fragmentLock; 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru hr = fFontFileStream->ReadFileFragment(&start, fPos, size, &fragmentLock); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SUCCEEDED(hr)) { 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(buffer, start, size); 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFontFileStream->ReleaseFileFragment(fragmentLock); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fPos += size; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return size; 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //The read may have failed because we asked for too much data. 6058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t fileSize = this->getLength(); 6158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (fPos + size <= fileSize) { 6258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger //This means we were within bounds, but failed for some other reason. 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t read = fileSize - fPos; 6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger hr = fFontFileStream->ReadFileFragment(&start, fPos, read, &fragmentLock); 6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (SUCCEEDED(hr)) { 6958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger memcpy(buffer, start, read); 7058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fFontFileStream->ReleaseFileFragment(fragmentLock); 7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPos = fileSize; 7258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return read; 7358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 7458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 7558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return 0; 7658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 7758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 7858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerbool SkDWriteFontFileStream::isAtEnd() const { 7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return fPos == this->getLength(); 8058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 8158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 8258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerbool SkDWriteFontFileStream::rewind() { 8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPos = 0; 8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return true; 8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkDWriteFontFileStream* SkDWriteFontFileStream::duplicate() const { 8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return SkNEW_ARGS(SkDWriteFontFileStream, (fFontFileStream.get())); 8958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 9058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergersize_t SkDWriteFontFileStream::getPosition() const { 9258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return fPos; 9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 9558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerbool SkDWriteFontFileStream::seek(size_t position) { 9658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger size_t length = this->getLength(); 9758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPos = (position > length) ? length : position; 9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return true; 9958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 10058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerbool SkDWriteFontFileStream::move(long offset) { 10258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return seek(fPos + offset); 10358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 10458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 10558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerSkDWriteFontFileStream* SkDWriteFontFileStream::fork() const { 10658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTUnref<SkDWriteFontFileStream> that(this->duplicate()); 10758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger that->seek(fPos); 10858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return that.detach(); 10958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 11058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 11158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergersize_t SkDWriteFontFileStream::getLength() const { 11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger HRESULT hr = S_OK; 11358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger UINT64 realFileSize = 0; 11458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger hr = fFontFileStream->GetFileSize(&realFileSize); 11558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!SkTFitsIn<size_t>(realFileSize)) { 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return static_cast<size_t>(realFileSize); 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerconst void* SkDWriteFontFileStream::getMemoryBase() { 12258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (fLockedMemory) { 12358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return fLockedMemory; 12458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 12558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 12658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger UINT64 fileSize; 12758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger HRNM(fFontFileStream->GetFileSize(&fileSize), "Could not get file size"); 12858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger HRNM(fFontFileStream->ReadFileFragment(&fLockedMemory, 0, fileSize, &fFragmentLock), 12958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger "Could not lock file fragment."); 13058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return fLockedMemory; 13158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// SkIDWriteFontFileStreamWrapper 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT SkDWriteFontFileStreamWrapper::Create(SkStream* stream, SkDWriteFontFileStreamWrapper** streamFontFileStream) { 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *streamFontFileStream = new SkDWriteFontFileStreamWrapper(stream); 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == streamFontFileStream) { 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_OUTOFMEMORY; 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return S_OK; 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStream* stream) 14558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger : fRefCount(1), fStream(SkRef(stream)) { 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::QueryInterface(REFIID iid, void** ppvObject) { 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *ppvObject = this; 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru AddRef(); 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return S_OK; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *ppvObject = NULL; 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_NOINTERFACE; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruULONG STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::AddRef() { 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return InterlockedIncrement(&fRefCount); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruULONG STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::Release() { 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ULONG newCount = InterlockedDecrement(&fRefCount); 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == newCount) { 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete this; 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return newCount; 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::ReadFileFragment( 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void const** fragmentStart, 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UINT64 fileOffset, 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UINT64 fragmentSize, 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void** fragmentContext) 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The loader is responsible for doing a bounds check. 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru UINT64 fileSize; 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->GetFileSize(&fileSize); 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fileOffset > fileSize || fragmentSize > fileSize - fileOffset) { 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentStart = NULL; 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentContext = NULL; 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_FAIL; 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 18658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (!SkTFitsIn<size_t>(fileOffset + fragmentSize)) { 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_FAIL; 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const void* data = fStream->getMemoryBase(); 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != data) { 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentStart = static_cast<BYTE const*>(data) + static_cast<size_t>(fileOffset); 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentContext = NULL; 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //May be called from multiple threads. 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoMutexAcquire ama(fStreamMutex); 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentStart = NULL; 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentContext = NULL; 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fStream->rewind()) { 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_FAIL; 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fStream->skip(static_cast<size_t>(fileOffset)) != fileOffset) { 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_FAIL; 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkAutoTMalloc<uint8_t> streamData(static_cast<size_t>(fragmentSize)); 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fStream->read(streamData.get(), static_cast<size_t>(fragmentSize)) != fragmentSize) { 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_FAIL; 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentStart = streamData.get(); 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fragmentContext = streamData.detach(); 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return S_OK; 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::ReleaseFileFragment(void* fragmentContext) { 22058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger sk_free(fragmentContext); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetFileSize(UINT64* fileSize) { 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *fileSize = fStream->getLength(); 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return S_OK; 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruHRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::GetLastWriteTime(UINT64* lastWriteTime) { 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The concept of last write time does not apply to this loader. 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *lastWriteTime = 0; 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return E_NOTIMPL; 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 233