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