• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 class SkFontDescriptor;
25 struct SkScalerContextRec;
26 
get_style(IDWriteFont * font)27 static SkFontStyle get_style(IDWriteFont* font) {
28     int weight = font->GetWeight();
29     int width = font->GetStretch();
30     SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
31     switch (font->GetStyle()) {
32         case DWRITE_FONT_STYLE_NORMAL: slant = SkFontStyle::kUpright_Slant; break;
33         case DWRITE_FONT_STYLE_OBLIQUE: slant = SkFontStyle::kOblique_Slant; break;
34         case DWRITE_FONT_STYLE_ITALIC: slant = SkFontStyle::kItalic_Slant; break;
35         default: SkASSERT(false); break;
36     }
37     return SkFontStyle(weight, width, slant);
38 }
39 
40 class DWriteFontTypeface : public SkTypeface {
41 public:
42     struct Loaders : public SkNVRefCnt<Loaders> {
LoadersLoaders43         Loaders(IDWriteFactory* factory,
44                   IDWriteFontFileLoader* fontFileLoader,
45                   IDWriteFontCollectionLoader* fontCollectionLoader)
46             : fFactory(SkRefComPtr(factory))
47             , fDWriteFontFileLoader(SkRefComPtr(fontFileLoader))
48             , fDWriteFontCollectionLoader(SkRefComPtr(fontCollectionLoader))
49         {}
50         Loaders(const Loaders&) = delete;
51         Loaders& operator=(const Loaders&) = delete;
52         Loaders(Loaders&&) = delete;
53         Loaders& operator=(Loaders&&) = delete;
54         ~Loaders();
55 
56         SkTScopedComPtr<IDWriteFactory> fFactory;
57         SkTScopedComPtr<IDWriteFontFileLoader> fDWriteFontFileLoader;
58         SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
59     };
60 
61 private:
DWriteFontTypeface(const SkFontStyle & style,IDWriteFactory * factory,IDWriteFontFace * fontFace,IDWriteFont * font,IDWriteFontFamily * fontFamily,sk_sp<Loaders> loaders)62     DWriteFontTypeface(const SkFontStyle& style,
63                        IDWriteFactory* factory,
64                        IDWriteFontFace* fontFace,
65                        IDWriteFont* font,
66                        IDWriteFontFamily* fontFamily,
67                        sk_sp<Loaders> loaders)
68         : SkTypeface(style, false)
69         , fFactory(SkRefComPtr(factory))
70         , fDWriteFontFamily(SkRefComPtr(fontFamily))
71         , fDWriteFont(SkRefComPtr(font))
72         , fDWriteFontFace(SkRefComPtr(fontFace))
73         , fLoaders(std::move(loaders))
74     {
75         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
76             // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr.
77             // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
78             SkASSERT_RELEASE(nullptr == fDWriteFontFace1.get());
79         }
80         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace2))) {
81             SkASSERT_RELEASE(nullptr == fDWriteFontFace2.get());
82         }
83         if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace4))) {
84             SkASSERT_RELEASE(nullptr == fDWriteFontFace4.get());
85         }
86         if (!SUCCEEDED(fFactory->QueryInterface(&fFactory2))) {
87             SkASSERT_RELEASE(nullptr == fFactory2.get());
88         }
89 
90         if (fDWriteFontFace1 && fDWriteFontFace1->IsMonospacedFont()) {
91             this->setIsFixedPitch(true);
92         }
93 
94         fIsColorFont = fFactory2 && fDWriteFontFace2 && fDWriteFontFace2->IsColorFont();
95     }
96 
97 public:
98     SkTScopedComPtr<IDWriteFactory> fFactory;
99     SkTScopedComPtr<IDWriteFactory2> fFactory2;
100     SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
101     SkTScopedComPtr<IDWriteFont> fDWriteFont;
102     SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
103     SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
104     SkTScopedComPtr<IDWriteFontFace2> fDWriteFontFace2;
105     SkTScopedComPtr<IDWriteFontFace4> fDWriteFontFace4;
106     bool fIsColorFont;
107 
Make(IDWriteFactory * factory,IDWriteFontFace * fontFace,IDWriteFont * font,IDWriteFontFamily * fontFamily,sk_sp<Loaders> loaders)108     static sk_sp<DWriteFontTypeface> Make(
109         IDWriteFactory* factory,
110         IDWriteFontFace* fontFace,
111         IDWriteFont* font,
112         IDWriteFontFamily* fontFamily,
113         sk_sp<Loaders> loaders)
114     {
115         return sk_sp<DWriteFontTypeface>(new DWriteFontTypeface(
116             get_style(font), factory, fontFace, font, fontFamily, std::move(loaders)));
117     }
118 
119 protected:
weak_dispose()120     void weak_dispose() const override {
121         fLoaders.reset();
122 
123         //SkTypefaceCache::Remove(this);
124         INHERITED::weak_dispose();
125     }
126 
127     sk_sp<SkTypeface> onMakeClone(const SkFontArguments&) const override;
128     std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
129     std::unique_ptr<SkScalerContext> onCreateScalerContext(const SkScalerContextEffects&,
130                                                            const SkDescriptor*) const override;
131     void onFilterRec(SkScalerContextRec*) const override;
132     void getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const override;
133     std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
134     void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
135     void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
136     int onCountGlyphs() const override;
137     void getPostScriptGlyphNames(SkString*) const override;
138     int onGetUPEM() const override;
139     void onGetFamilyName(SkString* familyName) const override;
140     bool onGetPostScriptName(SkString*) const override;
141     SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
142     bool onGlyphMaskNeedsCurrentColor() const override;
143     int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
144                                      int coordinateCount) const override;
145     int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
146                                        int parameterCount) const override;
147     int onGetTableTags(SkFontTableTag tags[]) const override;
148     size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override;
149     sk_sp<SkData> onCopyTableData(SkFontTableTag) const override;
150 
151 private:
152     mutable sk_sp<Loaders> fLoaders;
153     using INHERITED = SkTypeface;
154 };
155 
156 #endif
157