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 "include/core/SkTypeface.h"
12 #include "src/core/SkAdvancedTypefaceMetrics.h"
13 #include "src/core/SkLeanWindows.h"
14 #include "src/core/SkTypefaceCache.h"
15 #include "src/utils/win/SkDWrite.h"
16 #include "src/utils/win/SkHRESULT.h"
17 #include "src/utils/win/SkTScopedComPtr.h"
18 
19 #include <dwrite.h>
20 #include <dwrite_1.h>
21 #include <dwrite_2.h>
22 #include <dwrite_3.h>
23 
24 #if !defined(__MINGW32__) && WINVER < 0x0A00
25 #include "mozilla/gfx/dw-extra.h"
26 #endif
27 
28 class SkFontDescriptor;
29 struct SkScalerContextRec;
30 
get_style(IDWriteFont * font)31 static SkFontStyle get_style(IDWriteFont* font) {
32     int weight = font->GetWeight();
33     int width = font->GetStretch();
34     SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
35     switch (font->GetStyle()) {
36         case DWRITE_FONT_STYLE_NORMAL: slant = SkFontStyle::kUpright_Slant; break;
37         case DWRITE_FONT_STYLE_OBLIQUE: slant = SkFontStyle::kOblique_Slant; break;
38         case DWRITE_FONT_STYLE_ITALIC: slant = SkFontStyle::kItalic_Slant; break;
39         default: SkASSERT(false); break;
40     }
41     return SkFontStyle(weight, width, slant);
42 }
43 
44 class DWriteFontTypeface : public SkTypeface {
45 private:
46     DWriteFontTypeface(const SkFontStyle& style,
47                        IDWriteFactory* factory,
48                        IDWriteFontFace* fontFace,
49                        IDWriteFont* font = nullptr,
50                        IDWriteFontFamily* fontFamily = nullptr,
51                        IDWriteFontFileLoader* fontFileLoader = nullptr,
52                        IDWriteFontCollectionLoader* fontCollectionLoader = nullptr)
SkTypeface(style,false)53         : SkTypeface(style, false)
54         , fFactory(SkRefComPtr(factory))
55         , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
56         , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
57         , fDWriteFontFamily(SkSafeRefComPtr(fontFamily))
58         , fDWriteFont(SkSafeRefComPtr(font))
59         , fDWriteFontFace(SkRefComPtr(fontFace))
60         , fRenderingMode(DWRITE_RENDERING_MODE_DEFAULT)
61         , fGamma(2.2f)
62         , fContrast(1.0f)
63         , fClearTypeLevel(1.0f)
64     {
65         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
66             // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr.
67             // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
68             SkASSERT_RELEASE(nullptr == fDWriteFontFace1.get());
69         }
70         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace2))) {
71             SkASSERT_RELEASE(nullptr == fDWriteFontFace2.get());
72         }
73         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace4))) {
74             SkASSERT_RELEASE(nullptr == fDWriteFontFace4.get());
75         }
76         if (!SUCCEEDED(fFactory->QueryInterface(&fFactory2))) {
77             SkASSERT_RELEASE(nullptr == fFactory2.get());
78         }
79     }
80 
81 public:
82     SkTScopedComPtr<IDWriteFactory> fFactory;
83     SkTScopedComPtr<IDWriteFactory2> fFactory2;
84     SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
85     SkTScopedComPtr<IDWriteFontFileLoader> fDWriteFontFileLoader;
86     SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
87     SkTScopedComPtr<IDWriteFont> fDWriteFont;
88     SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
89     SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
90     SkTScopedComPtr<IDWriteFontFace2> fDWriteFontFace2;
91     SkTScopedComPtr<IDWriteFontFace4> fDWriteFontFace4;
92 
93     static sk_sp<DWriteFontTypeface> Make(
94         IDWriteFactory* factory,
95         IDWriteFontFace* fontFace,
96         IDWriteFont* font,
97         IDWriteFontFamily* fontFamily,
98         IDWriteFontFileLoader* fontFileLoader = nullptr,
99         IDWriteFontCollectionLoader* fontCollectionLoader = nullptr)
100     {
101         return sk_sp<DWriteFontTypeface>(
102             new DWriteFontTypeface(get_style(font), factory, fontFace, font, fontFamily,
103                                    fontFileLoader, fontCollectionLoader));
104     }
105 
Create(IDWriteFactory * factory,IDWriteFontFace * fontFace,SkFontStyle aStyle,DWRITE_RENDERING_MODE aRenderingMode,float aGamma,float aContrast,float aClearTypeLevel)106     static DWriteFontTypeface* Create(IDWriteFactory* factory,
107                                       IDWriteFontFace* fontFace,
108                                       SkFontStyle aStyle,
109                                       DWRITE_RENDERING_MODE aRenderingMode,
110                                       float aGamma,
111                                       float aContrast,
112                                       float aClearTypeLevel) {
113         DWriteFontTypeface* typeface =
114                 new DWriteFontTypeface(aStyle, factory, fontFace,
115                                        nullptr, nullptr,
116                                        nullptr, nullptr);
117         typeface->fRenderingMode = aRenderingMode;
118         typeface->fGamma = aGamma;
119         typeface->fContrast = aContrast;
120         typeface->fClearTypeLevel = aClearTypeLevel;
121         return typeface;
122     }
123 
ForceGDI()124     bool ForceGDI() const { return fRenderingMode == DWRITE_RENDERING_MODE_GDI_CLASSIC; }
GetRenderingMode()125     DWRITE_RENDERING_MODE GetRenderingMode() const { return fRenderingMode; }
GetClearTypeLevel()126     float GetClearTypeLevel() const { return fClearTypeLevel; }
127 
128 protected:
weak_dispose()129     void weak_dispose() const override {
130         if (fDWriteFontCollectionLoader.get()) {
131             HRV(fFactory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
132         }
133         if (fDWriteFontFileLoader.get()) {
134             HRV(fFactory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
135         }
136 
137         //SkTypefaceCache::Remove(this);
138         INHERITED::weak_dispose();
139     }
140 
141     sk_sp<SkTypeface> onMakeClone(const SkFontArguments&) const override;
142     std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
143     SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
144                                            const SkDescriptor*) const override;
145     void onFilterRec(SkScalerContextRec*) const override;
146     void getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const override;
147     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
148     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
149     void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
150     int onCountGlyphs() const override;
151     void getPostScriptGlyphNames(SkString*) const override;
152     int onGetUPEM() const override;
153     void onGetFamilyName(SkString* familyName) const override;
154     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
155     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
156                                      int coordinateCount) const override;
157     int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
158                                        int parameterCount) const override;
159     int onGetTableTags(SkFontTableTag tags[]) const override;
160     size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override;
161     sk_sp<SkData> onCopyTableData(SkFontTableTag) const override;
162 
163 private:
164     typedef SkTypeface INHERITED;
165     DWRITE_RENDERING_MODE fRenderingMode;
166     float fGamma;
167     float fContrast;
168     float fClearTypeLevel;
169 };
170 
171 #endif
172