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 */
7
8#ifndef SkDWriteFontFileStream_DEFINED
9#define SkDWriteFontFileStream_DEFINED
10
11#include "SkTypes.h"
12
13#include "SkMutex.h"
14#include "SkStream.h"
15#include "SkTScopedComPtr.h"
16
17#include <dwrite.h>
18
19/**
20 *  An SkStream backed by an IDWriteFontFileStream.
21 *  This allows Skia code to read an IDWriteFontFileStream.
22 */
23class SkDWriteFontFileStream : public SkStreamMemory {
24public:
25    explicit SkDWriteFontFileStream(IDWriteFontFileStream* fontFileStream);
26    ~SkDWriteFontFileStream() override;
27
28    size_t read(void* buffer, size_t size) override;
29    bool isAtEnd() const override;
30    bool rewind() override;
31    size_t getPosition() const override;
32    bool seek(size_t position) override;
33    bool move(long offset) override;
34    size_t getLength() const override;
35    const void* getMemoryBase() override;
36
37    std::unique_ptr<SkDWriteFontFileStream> duplicate() const {
38        return std::unique_ptr<SkDWriteFontFileStream>(this->onDuplicate());
39    }
40    std::unique_ptr<SkDWriteFontFileStream> fork() const {
41        return std::unique_ptr<SkDWriteFontFileStream>(this->onFork());
42    }
43
44private:
45    SkDWriteFontFileStream* onDuplicate() const override;
46    SkDWriteFontFileStream* onFork() const override;
47
48    SkTScopedComPtr<IDWriteFontFileStream> fFontFileStream;
49    size_t fPos;
50    const void* fLockedMemory;
51    void* fFragmentLock;
52};
53
54/**
55 *  An IDWriteFontFileStream backed by an SkStream.
56 *  This allows DirectWrite to read an SkStream.
57 */
58class SkDWriteFontFileStreamWrapper : public IDWriteFontFileStream {
59public:
60    // IUnknown methods
61    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
62    virtual ULONG STDMETHODCALLTYPE AddRef();
63    virtual ULONG STDMETHODCALLTYPE Release();
64
65    // IDWriteFontFileStream methods
66    virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(
67        void const** fragmentStart,
68        UINT64 fileOffset,
69        UINT64 fragmentSize,
70        void** fragmentContext);
71
72    virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
73    virtual HRESULT STDMETHODCALLTYPE GetFileSize(UINT64* fileSize);
74    virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(UINT64* lastWriteTime);
75
76    static HRESULT Create(SkStreamAsset* stream,
77                          SkDWriteFontFileStreamWrapper** streamFontFileStream);
78
79private:
80    explicit SkDWriteFontFileStreamWrapper(SkStreamAsset* stream);
81    virtual ~SkDWriteFontFileStreamWrapper() { }
82
83    ULONG fRefCount;
84    std::unique_ptr<SkStreamAsset> fStream;
85    SkMutex fStreamMutex;
86};
87#endif
88