1/*
2 * Copyright 2014 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 SkTypeface_win_dw_DEFINED
9#define SkTypeface_win_dw_DEFINED
10
11#include "SkAdvancedTypefaceMetrics.h"
12#include "SkDWrite.h"
13#include "SkHRESULT.h"
14#include "SkTScopedComPtr.h"
15#include "SkTypeface.h"
16#include "SkTypefaceCache.h"
17#include "SkTypes.h"
18
19#include <dwrite.h>
20#include <dwrite_1.h>
21
22class SkFontDescriptor;
23struct SkScalerContextRec;
24
25static SkTypeface::Style get_style(IDWriteFont* font) {
26    int style = SkTypeface::kNormal;
27    DWRITE_FONT_WEIGHT weight = font->GetWeight();
28    if (DWRITE_FONT_WEIGHT_DEMI_BOLD <= weight) {
29        style |= SkTypeface::kBold;
30    }
31    DWRITE_FONT_STYLE angle = font->GetStyle();
32    if (DWRITE_FONT_STYLE_OBLIQUE == angle || DWRITE_FONT_STYLE_ITALIC == angle) {
33        style |= SkTypeface::kItalic;
34    }
35    return static_cast<SkTypeface::Style>(style);
36}
37
38class DWriteFontTypeface : public SkTypeface {
39private:
40    DWriteFontTypeface(SkTypeface::Style style, SkFontID fontID,
41                       IDWriteFactory* factory,
42                       IDWriteFontFace* fontFace,
43                       IDWriteFont* font,
44                       IDWriteFontFamily* fontFamily,
45                       IDWriteFontFileLoader* fontFileLoader = NULL,
46                       IDWriteFontCollectionLoader* fontCollectionLoader = NULL)
47        : SkTypeface(style, fontID, false)
48        , fFactory(SkRefComPtr(factory))
49        , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
50        , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
51        , fDWriteFontFamily(SkRefComPtr(fontFamily))
52        , fDWriteFont(SkRefComPtr(font))
53        , fDWriteFontFace(SkRefComPtr(fontFace))
54    {
55        if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
56            // IUnknown::QueryInterface states that if it fails, punk will be set to NULL.
57            // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
58            SK_ALWAYSBREAK(NULL == fDWriteFontFace1.get());
59        }
60    }
61
62public:
63    SkTScopedComPtr<IDWriteFactory> fFactory;
64    SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
65    SkTScopedComPtr<IDWriteFontFileLoader> fDWriteFontFileLoader;
66    SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
67    SkTScopedComPtr<IDWriteFont> fDWriteFont;
68    SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
69    SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
70
71    static DWriteFontTypeface* Create(IDWriteFactory* factory,
72                                      IDWriteFontFace* fontFace,
73                                      IDWriteFont* font,
74                                      IDWriteFontFamily* fontFamily,
75                                      IDWriteFontFileLoader* fontFileLoader = NULL,
76                                      IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
77        SkTypeface::Style style = get_style(font);
78        SkFontID fontID = SkTypefaceCache::NewFontID();
79        return SkNEW_ARGS(DWriteFontTypeface, (style, fontID,
80                                               factory, fontFace, font, fontFamily,
81                                               fontFileLoader, fontCollectionLoader));
82    }
83
84protected:
85    virtual void weak_dispose() const SK_OVERRIDE {
86        if (fDWriteFontCollectionLoader.get()) {
87            HRV(fFactory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
88        }
89        if (fDWriteFontFileLoader.get()) {
90            HRV(fFactory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
91        }
92
93        //SkTypefaceCache::Remove(this);
94        INHERITED::weak_dispose();
95    }
96
97    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
98    virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
99    virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
100    virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
101                                SkAdvancedTypefaceMetrics::PerGlyphInfo,
102                                const uint32_t*, uint32_t) const SK_OVERRIDE;
103    virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
104    virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
105                                uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
106    virtual int onCountGlyphs() const SK_OVERRIDE;
107    virtual int onGetUPEM() const SK_OVERRIDE;
108    virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
109    virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
110    virtual size_t onGetTableData(SkFontTableTag, size_t offset,
111                                  size_t length, void* data) const SK_OVERRIDE;
112
113private:
114    typedef SkTypeface INHERITED;
115};
116
117#endif
118