diff options
Diffstat (limited to 'gfx/skia/skia/src/utils/win/SkDWrite.cpp')
-rw-r--r-- | gfx/skia/skia/src/utils/win/SkDWrite.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/utils/win/SkDWrite.cpp b/gfx/skia/skia/src/utils/win/SkDWrite.cpp new file mode 100644 index 0000000000..30460fe5f6 --- /dev/null +++ b/gfx/skia/skia/src/utils/win/SkDWrite.cpp @@ -0,0 +1,138 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "include/core/SkTypes.h" +#if defined(SK_BUILD_FOR_WIN) + +#include "include/core/SkString.h" +#include "include/private/base/SkOnce.h" +#include "src/utils/win/SkDWrite.h" +#include "src/utils/win/SkHRESULT.h" + +#include <dwrite.h> + +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wcast-function-type" +#endif + +static IDWriteFactory* gDWriteFactory = nullptr; + +static void release_dwrite_factory() { + if (gDWriteFactory) { + gDWriteFactory->Release(); + } +} + +static void create_dwrite_factory(IDWriteFactory** factory) { + typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; + DWriteCreateFactoryProc dWriteCreateFactoryProc = reinterpret_cast<DWriteCreateFactoryProc>( + GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory")); + + if (!dWriteCreateFactoryProc) { + HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); + if (!IS_ERROR(hr)) { + hr = ERROR_PROC_NOT_FOUND; + } + HRVM(hr, "Could not get DWriteCreateFactory proc."); + } + + HRVM(dWriteCreateFactoryProc(DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast<IUnknown**>(factory)), + "Could not create DirectWrite factory."); + atexit(release_dwrite_factory); +} + + +IDWriteFactory* sk_get_dwrite_factory() { + static SkOnce once; + once(create_dwrite_factory, &gDWriteFactory); + return gDWriteFactory; +} + +//////////////////////////////////////////////////////////////////////////////// +// String conversion + +/** Converts a utf8 string to a WCHAR string. */ +HRESULT sk_cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) { + int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, nullptr, 0); + if (0 == wlen) { + HRM(HRESULT_FROM_WIN32(GetLastError()), + "Could not get length for wchar to utf-8 conversion."); + } + name->reset(wlen); + wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, name->get(), wlen); + if (0 == wlen) { + HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert wchar to utf-8."); + } + return S_OK; +} + +/** Converts a WCHAR string to a utf8 string. */ +HRESULT sk_wchar_to_skstring(WCHAR* name, int nameLen, SkString* skname) { + int len = WideCharToMultiByte(CP_UTF8, 0, name, nameLen, nullptr, 0, nullptr, nullptr); + if (0 == len) { + if (nameLen <= 0) { + skname->reset(); + return S_OK; + } + HRM(HRESULT_FROM_WIN32(GetLastError()), + "Could not get length for utf-8 to wchar conversion."); + } + skname->resize(len); + + len = WideCharToMultiByte(CP_UTF8, 0, name, nameLen, skname->data(), len, nullptr, nullptr); + if (0 == len) { + HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wchar."); + } + return S_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// Locale + +HRESULT sk_get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale, + SkString* skname) { + UINT32 nameIndex = 0; + if (preferedLocale) { + // Ignore any errors and continue with index 0 if there is a problem. + BOOL nameExists = FALSE; + (void)names->FindLocaleName(preferedLocale, &nameIndex, &nameExists); + if (!nameExists) { + nameIndex = 0; + } + } + + UINT32 nameLen; + HRM(names->GetStringLength(nameIndex, &nameLen), "Could not get name length."); + + SkSMallocWCHAR name(nameLen + 1); + HRM(names->GetString(nameIndex, name.get(), nameLen + 1), "Could not get string."); + + HR(sk_wchar_to_skstring(name.get(), nameLen, skname)); + return S_OK; +} + +HRESULT SkGetGetUserDefaultLocaleNameProc(SkGetUserDefaultLocaleNameProc* proc) { + *proc = reinterpret_cast<SkGetUserDefaultLocaleNameProc>( + GetProcAddress(LoadLibraryW(L"Kernel32.dll"), "GetUserDefaultLocaleName") + ); + if (!*proc) { + HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); + if (!IS_ERROR(hr)) { + hr = ERROR_PROC_NOT_FOUND; + } + return hr; + } + return S_OK; +} + +#if defined(__clang__) + #pragma clang diagnostic pop +#endif + +#endif//defined(SK_BUILD_FOR_WIN) |