• 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 #include "SkDWrite.h"
9 #include "SkHRESULT.h"
10 #include "SkOnce.h"
11 #include "SkString.h"
12 
13 #include <dwrite.h>
14 
15 static IDWriteFactory* gDWriteFactory = NULL;
16 
release_dwrite_factory()17 static void release_dwrite_factory() {
18     if (gDWriteFactory) {
19         gDWriteFactory->Release();
20     }
21 }
22 
create_dwrite_factory(IDWriteFactory ** factory)23 static void create_dwrite_factory(IDWriteFactory** factory) {
24     typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc;
25     DWriteCreateFactoryProc dWriteCreateFactoryProc = reinterpret_cast<DWriteCreateFactoryProc>(
26         GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"));
27 
28     if (!dWriteCreateFactoryProc) {
29         HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
30         if (!IS_ERROR(hr)) {
31             hr = ERROR_PROC_NOT_FOUND;
32         }
33         HRVM(hr, "Could not get DWriteCreateFactory proc.");
34     }
35 
36     HRVM(dWriteCreateFactoryProc(DWRITE_FACTORY_TYPE_SHARED,
37                                  __uuidof(IDWriteFactory),
38                                  reinterpret_cast<IUnknown**>(factory)),
39          "Could not create DirectWrite factory.");
40     atexit(release_dwrite_factory);
41 }
42 
43 
sk_get_dwrite_factory()44 IDWriteFactory* sk_get_dwrite_factory() {
45     SK_DECLARE_STATIC_ONCE(once);
46     SkOnce(&once, create_dwrite_factory, &gDWriteFactory);
47 
48     return gDWriteFactory;
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 // String conversion
53 
54 /** Converts a utf8 string to a WCHAR string. */
sk_cstring_to_wchar(const char * skname,SkSMallocWCHAR * name)55 HRESULT sk_cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) {
56     int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, NULL, 0);
57     if (0 == wlen) {
58         HRM(HRESULT_FROM_WIN32(GetLastError()),
59             "Could not get length for wchar to utf-8 conversion.");
60     }
61     name->reset(wlen);
62     wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, name->get(), wlen);
63     if (0 == wlen) {
64         HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert wchar to utf-8.");
65     }
66     return S_OK;
67 }
68 
69 /** Converts a WCHAR string to a utf8 string. */
sk_wchar_to_skstring(WCHAR * name,int nameLen,SkString * skname)70 HRESULT sk_wchar_to_skstring(WCHAR* name, int nameLen, SkString* skname) {
71     int len = WideCharToMultiByte(CP_UTF8, 0, name, nameLen, NULL, 0, NULL, NULL);
72     if (0 == len) {
73         if (nameLen <= 0) {
74             skname->reset();
75             return S_OK;
76         }
77         HRM(HRESULT_FROM_WIN32(GetLastError()),
78             "Could not get length for utf-8 to wchar conversion.");
79     }
80     skname->resize(len);
81 
82     len = WideCharToMultiByte(CP_UTF8, 0, name, nameLen, skname->writable_str(), len, NULL, NULL);
83     if (0 == len) {
84         HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wchar.");
85     }
86     return S_OK;
87 }
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 // Locale
91 
sk_get_locale_string(IDWriteLocalizedStrings * names,const WCHAR * preferedLocale,SkString * skname)92 void sk_get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale,
93                           SkString* skname) {
94     UINT32 nameIndex = 0;
95     if (preferedLocale) {
96         // Ignore any errors and continue with index 0 if there is a problem.
97         BOOL nameExists;
98         names->FindLocaleName(preferedLocale, &nameIndex, &nameExists);
99         if (!nameExists) {
100             nameIndex = 0;
101         }
102     }
103 
104     UINT32 nameLen;
105     HRVM(names->GetStringLength(nameIndex, &nameLen), "Could not get name length.");
106 
107     SkSMallocWCHAR name(nameLen+1);
108     HRVM(names->GetString(nameIndex, name.get(), nameLen+1), "Could not get string.");
109 
110     HRV(sk_wchar_to_skstring(name.get(), nameLen, skname));
111 }
112 
SkGetGetUserDefaultLocaleNameProc(SkGetUserDefaultLocaleNameProc * proc)113 HRESULT SkGetGetUserDefaultLocaleNameProc(SkGetUserDefaultLocaleNameProc* proc) {
114     *proc = reinterpret_cast<SkGetUserDefaultLocaleNameProc>(
115         GetProcAddress(LoadLibraryW(L"Kernel32.dll"), "GetUserDefaultLocaleName")
116     );
117     if (!*proc) {
118         HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
119         if (!IS_ERROR(hr)) {
120             hr = ERROR_PROC_NOT_FOUND;
121         }
122         return hr;
123     }
124     return S_OK;
125 }
126