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 15static IDWriteFactory* gDWriteFactory = NULL; 16 17static void release_dwrite_factory() { 18 if (gDWriteFactory) { 19 gDWriteFactory->Release(); 20 } 21} 22 23static 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 44IDWriteFactory* 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. */ 55HRESULT 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. */ 70HRESULT 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 92void 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 113HRESULT 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