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 "SkLeanWindows.h"
15 #include "SkTScopedComPtr.h"
16 #include "SkTypeface.h"
17 #include "SkTypefaceCache.h"
18 
19 #include <dwrite.h>
20 #include <dwrite_1.h>
21 #include <dwrite_2.h>
22 
23 class SkFontDescriptor;
24 struct SkScalerContextRec;
25 
get_style(IDWriteFont * font)26 static SkFontStyle get_style(IDWriteFont* font) {
27     int weight = font->GetWeight();
28     int width = font->GetStretch();
29     SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
30     switch (font->GetStyle()) {
31         case DWRITE_FONT_STYLE_NORMAL: slant = SkFontStyle::kUpright_Slant; break;
32         case DWRITE_FONT_STYLE_OBLIQUE: slant = SkFontStyle::kOblique_Slant; break;
33         case DWRITE_FONT_STYLE_ITALIC: slant = SkFontStyle::kItalic_Slant; break;
34         default: SkASSERT(false); break;
35     }
36     return SkFontStyle(weight, width, slant);
37 }
38 
39 class DWriteFontTypeface : public SkTypeface {
40 private:
41     DWriteFontTypeface(const SkFontStyle& style,
42                        IDWriteFactory* factory,
43                        IDWriteFontFace* fontFace,
44                        IDWriteFont* font,
45                        IDWriteFontFamily* fontFamily,
46                        IDWriteFontFileLoader* fontFileLoader = nullptr,
47                        IDWriteFontCollectionLoader* fontCollectionLoader = nullptr)
SkTypeface(style,false)48         : SkTypeface(style, false)
49         , fFactory(SkRefComPtr(factory))
50         , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
51         , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
52         , fDWriteFontFamily(SkRefComPtr(fontFamily))
53         , fDWriteFont(SkRefComPtr(font))
54         , fDWriteFontFace(SkRefComPtr(fontFace))
55     {
56         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
57             // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr.
58             // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
59             SkASSERT_RELEASE(nullptr == fDWriteFontFace1.get());
60         }
61         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace2))) {
62             SkASSERT_RELEASE(nullptr == fDWriteFontFace2.get());
63         }
64         if (!SUCCEEDED(fFactory->QueryInterface(&fFactory2))) {
65             SkASSERT_RELEASE(nullptr == fFactory2.get());
66         }
67     }
68 
69 public:
70     SkTScopedComPtr<IDWriteFactory> fFactory;
71     SkTScopedComPtr<IDWriteFactory2> fFactory2;
72     SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
73     SkTScopedComPtr<IDWriteFontFileLoader> fDWriteFontFileLoader;
74     SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
75     SkTScopedComPtr<IDWriteFont> fDWriteFont;
76     SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
77     SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
78     SkTScopedComPtr<IDWriteFontFace2> fDWriteFontFace2;
79 
80     static DWriteFontTypeface* Create(IDWriteFactory* factory,
81                                       IDWriteFontFace* fontFace,
82                                       IDWriteFont* font,
83                                       IDWriteFontFamily* fontFamily,
84                                       IDWriteFontFileLoader* fontFileLoader = nullptr,
85                                       IDWriteFontCollectionLoader* fontCollectionLoader = nullptr) {
86         return new DWriteFontTypeface(get_style(font), factory, fontFace, font, fontFamily,
87                                       fontFileLoader, fontCollectionLoader);
88     }
89 
90 protected:
weak_dispose()91     void weak_dispose() const override {
92         if (fDWriteFontCollectionLoader.get()) {
93             HRV(fFactory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
94         }
95         if (fDWriteFontFileLoader.get()) {
96             HRV(fFactory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
97         }
98 
99         //SkTypefaceCache::Remove(this);
100         INHERITED::weak_dispose();
101     }
102 
103     SkStreamAsset* onOpenStream(int* ttcIndex) const override;
104     SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
105                                            const SkDescriptor*) const override;
106     void onFilterRec(SkScalerContextRec*) const override;
107     SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
108                                 PerGlyphInfo, const uint32_t*, uint32_t) const override;
109     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
110     int onCharsToGlyphs(const void* chars, Encoding encoding,
111                         uint16_t glyphs[], int glyphCount) const override;
112     int onCountGlyphs() const override;
113     int onGetUPEM() const override;
114     void onGetFamilyName(SkString* familyName) const override;
115     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],int coordinateCount)116     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
117                                      int coordinateCount) const override
118     {
119         return -1;
120     }
121     int onGetTableTags(SkFontTableTag tags[]) const override;
122     size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override;
123 
124 private:
125     typedef SkTypeface INHERITED;
126 };
127 
128 #endif
129