OLD | NEW |
(Empty) | |
| 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 |
| 17 static void create_dwrite_factory(IDWriteFactory** factory) { |
| 18 typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; |
| 19 DWriteCreateFactoryProc dWriteCreateFactoryProc = reinterpret_cast<DWriteCre
ateFactoryProc>( |
| 20 GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory")); |
| 21 |
| 22 if (!dWriteCreateFactoryProc) { |
| 23 HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); |
| 24 if (!IS_ERROR(hr)) { |
| 25 hr = ERROR_PROC_NOT_FOUND; |
| 26 } |
| 27 HRVM(hr, "Could not get DWriteCreateFactory proc."); |
| 28 } |
| 29 |
| 30 HRVM(dWriteCreateFactoryProc(DWRITE_FACTORY_TYPE_SHARED, |
| 31 __uuidof(IDWriteFactory), |
| 32 reinterpret_cast<IUnknown**>(factory)), |
| 33 "Could not create DirectWrite factory."); |
| 34 } |
| 35 |
| 36 static void release_dwrite_factory() { |
| 37 if (gDWriteFactory) { |
| 38 gDWriteFactory->Release(); |
| 39 } |
| 40 } |
| 41 |
| 42 IDWriteFactory* sk_get_dwrite_factory() { |
| 43 SK_DECLARE_STATIC_ONCE(once); |
| 44 SkOnce(&once, create_dwrite_factory, &gDWriteFactory, release_dwrite_factory
); |
| 45 |
| 46 return gDWriteFactory; |
| 47 } |
| 48 |
| 49 //////////////////////////////////////////////////////////////////////////////// |
| 50 // String conversion |
| 51 |
| 52 /** Converts a utf8 string to a WCHAR string. */ |
| 53 HRESULT sk_cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) { |
| 54 int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, NULL, 0); |
| 55 if (0 == wlen) { |
| 56 HRM(HRESULT_FROM_WIN32(GetLastError()), |
| 57 "Could not get length for wchar to utf-8 conversion."); |
| 58 } |
| 59 name->reset(wlen); |
| 60 wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, name->get(), wlen); |
| 61 if (0 == wlen) { |
| 62 HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert wchar to utf-
8."); |
| 63 } |
| 64 return S_OK; |
| 65 } |
| 66 |
| 67 /** Converts a WCHAR string to a utf8 string. */ |
| 68 HRESULT sk_wchar_to_skstring(WCHAR* name, SkString* skname) { |
| 69 int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL); |
| 70 if (0 == len) { |
| 71 HRM(HRESULT_FROM_WIN32(GetLastError()), |
| 72 "Could not get length for utf-8 to wchar conversion."); |
| 73 } |
| 74 skname->resize(len - 1); |
| 75 |
| 76 // TODO: remove after https://code.google.com/p/skia/issues/detail?id=1989 i
s fixed. |
| 77 // If we resize to 0 then the skname points to gEmptyRec (the unique empty S
kString::Rec). |
| 78 // gEmptyRec is static const and on Windows this means the value is in a rea
d only page. |
| 79 // Writing to it in the following call to WideCharToMultiByte will cause an
access violation. |
| 80 if (1 == len) { |
| 81 return S_OK; |
| 82 } |
| 83 |
| 84 len = WideCharToMultiByte(CP_UTF8, 0, name, -1, skname->writable_str(), len,
NULL, NULL); |
| 85 if (0 == len) { |
| 86 HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wcha
r."); |
| 87 } |
| 88 return S_OK; |
| 89 } |
| 90 |
| 91 //////////////////////////////////////////////////////////////////////////////// |
| 92 // Locale |
| 93 |
| 94 void sk_get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedL
ocale, |
| 95 SkString* skname) { |
| 96 UINT32 nameIndex = 0; |
| 97 if (preferedLocale) { |
| 98 // Ignore any errors and continue with index 0 if there is a problem. |
| 99 BOOL nameExists; |
| 100 names->FindLocaleName(preferedLocale, &nameIndex, &nameExists); |
| 101 if (!nameExists) { |
| 102 nameIndex = 0; |
| 103 } |
| 104 } |
| 105 |
| 106 UINT32 nameLength; |
| 107 HRVM(names->GetStringLength(nameIndex, &nameLength), "Could not get name len
gth."); |
| 108 nameLength += 1; |
| 109 |
| 110 SkSMallocWCHAR name(nameLength); |
| 111 HRVM(names->GetString(nameIndex, name.get(), nameLength), "Could not get str
ing."); |
| 112 |
| 113 HRV(sk_wchar_to_skstring(name.get(), skname)); |
| 114 } |
| 115 |
| 116 HRESULT SkGetGetUserDefaultLocaleNameProc(SkGetUserDefaultLocaleNameProc* proc)
{ |
| 117 *proc = reinterpret_cast<SkGetUserDefaultLocaleNameProc>( |
| 118 GetProcAddress(LoadLibraryW(L"Kernel32.dll"), "GetUserDefaultLocaleName"
) |
| 119 ); |
| 120 if (!*proc) { |
| 121 HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); |
| 122 if (!IS_ERROR(hr)) { |
| 123 hr = ERROR_PROC_NOT_FOUND; |
| 124 } |
| 125 return hr; |
| 126 } |
| 127 return S_OK; |
| 128 } |
OLD | NEW |