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
95 public:
96 SkTScopedComPtr<IDWriteFactory> fFactory;
97 SkTScopedComPtr<IDWriteFactory2> fFactory2;
98 SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
99 SkTScopedComPtr<IDWriteFont> fDWriteFont;
100 SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
101 SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
102 SkTScopedComPtr<IDWriteFontFace2> fDWriteFontFace2;
103 SkTScopedComPtr<IDWriteFontFace4> fDWriteFontFace4;
104
Make(IDWriteFactory * factory,IDWriteFontFace * fontFace,IDWriteFont * font,IDWriteFontFamily * fontFamily,sk_sp<Loaders> loaders)105 static sk_sp<DWriteFontTypeface> Make(
106 IDWriteFactory* factory,
107 IDWriteFontFace* fontFace,
108 IDWriteFont* font,
109 IDWriteFontFamily* fontFamily,
110 sk_sp<Loaders> loaders)
111 {
112 return sk_sp<DWriteFontTypeface>(new DWriteFontTypeface(
113 get_style(font), factory, fontFace, font, fontFamily, std::move(loaders)));
114 }
115
116 protected:
weak_dispose()117 void weak_dispose() const override {
118 fLoaders.reset();
119
120 //SkTypefaceCache::Remove(this);
121 INHERITED::weak_dispose();
122 }
123
124 sk_sp<SkTypeface> onMakeClone(const SkFontArguments&) const override;
125 std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override;
126 std::unique_ptr<SkScalerContext> onCreateScalerContext(const SkScalerContextEffects&,
127 const SkDescriptor*) const override;
128 void onFilterRec(SkScalerContextRec*) const override;
129 void getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const override;
130 std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
131 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
132 void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
133 int onCountGlyphs() const override;
134 void getPostScriptGlyphNames(SkString*) const override;
135 int onGetUPEM() const override;
136 void onGetFamilyName(SkString* familyName) const override;
137 bool onGetPostScriptName(SkString*) const override;
138 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
onGlyphMaskNeedsCurrentColor()139 bool onGlyphMaskNeedsCurrentColor() const override { return false; }
140 int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
141 int coordinateCount) const override;
142 int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
143 int parameterCount) const override;
144 int onGetTableTags(SkFontTableTag tags[]) const override;
145 size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override;
146 sk_sp<SkData> onCopyTableData(SkFontTableTag) const override;
147
148 private:
149 mutable sk_sp<Loaders> fLoaders;
150 using INHERITED = SkTypeface;
151 };
152
153 #endif
154