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 SkDWrite_DEFINED
9 #define SkDWrite_DEFINED
10 
11 #include "SkTemplates.h"
12 #include "SkFontStyle.h"
13 
14 #include <dwrite.h>
15 #include <winsdkver.h>
16 
17 class SkString;
18 
19 ////////////////////////////////////////////////////////////////////////////////
20 // Factory
21 
22 #ifndef SK_HAS_DWRITE_1_H
23 #define SK_HAS_DWRITE_1_H (WINVER_MAXVER >= 0x0602)
24 #endif
25 
26 #ifndef SK_HAS_DWRITE_2_H
27 #define SK_HAS_DWRITE_2_H (WINVER_MAXVER >= 0x0603)
28 #endif
29 
30 IDWriteFactory* sk_get_dwrite_factory();
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 // String conversion
34 
35 /** Prefer to use this type to prevent template proliferation. */
36 typedef SkAutoSTMalloc<16, WCHAR> SkSMallocWCHAR;
37 
38 /** Converts a utf8 string to a WCHAR string. */
39 HRESULT sk_cstring_to_wchar(const char* skname, SkSMallocWCHAR* name);
40 
41 /** Converts a WCHAR string to a utf8 string.
42  *  @param nameLen the number of WCHARs in the name.
43  */
44 HRESULT sk_wchar_to_skstring(WCHAR* name, int nameLen, SkString* skname);
45 
46 ////////////////////////////////////////////////////////////////////////////////
47 // Locale
48 
49 void sk_get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale,
50                        SkString* skname);
51 
52 typedef int (WINAPI *SkGetUserDefaultLocaleNameProc)(LPWSTR, int);
53 HRESULT SkGetGetUserDefaultLocaleNameProc(SkGetUserDefaultLocaleNameProc* proc);
54 
55 ////////////////////////////////////////////////////////////////////////////////
56 // Table handling
57 
58 class AutoDWriteTable {
59 public:
AutoDWriteTable(IDWriteFontFace * fontFace,UINT32 beTag)60     AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFace), fExists(FALSE) {
61         // Any errors are ignored, user must check fExists anyway.
62         fontFace->TryGetFontTable(beTag,
63             reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
64     }
~AutoDWriteTable()65     ~AutoDWriteTable() {
66         if (fExists) {
67             fFontFace->ReleaseFontTable(fLock);
68         }
69     }
70 
71     const uint8_t* fData;
72     UINT32 fSize;
73     BOOL fExists;
74 private:
75     // Borrowed reference, the user must ensure the fontFace stays alive.
76     IDWriteFontFace* fFontFace;
77     void* fLock;
78 };
79 template<typename T> class AutoTDWriteTable : public AutoDWriteTable {
80 public:
81     static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2, T::TAG3);
AutoTDWriteTable(IDWriteFontFace * fontFace)82     AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { }
83 
get()84     const T* get() const { return reinterpret_cast<const T*>(fData); }
85     const T* operator->() const { return reinterpret_cast<const T*>(fData); }
86 };
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 // Style conversion
90 
91 struct DWriteStyle {
DWriteStyleDWriteStyle92     explicit DWriteStyle(const SkFontStyle& pattern) {
93         switch (pattern.slant()) {
94         case SkFontStyle::kUpright_Slant:
95             fSlant = DWRITE_FONT_STYLE_NORMAL;
96             break;
97         case SkFontStyle::kItalic_Slant:
98             fSlant = DWRITE_FONT_STYLE_ITALIC;
99             break;
100         default:
101             SkASSERT(false);
102         }
103 
104         fWeight = (DWRITE_FONT_WEIGHT)pattern.weight();
105         fWidth = (DWRITE_FONT_STRETCH)pattern.width();
106     }
107     DWRITE_FONT_STYLE fSlant;
108     DWRITE_FONT_WEIGHT fWeight;
109     DWRITE_FONT_STRETCH fWidth;
110 };
111 
112 #endif
113