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