| Index: src/ports/SkFontHost_win_dw.cpp
|
| ===================================================================
|
| --- src/ports/SkFontHost_win_dw.cpp (revision 13875)
|
| +++ src/ports/SkFontHost_win_dw.cpp (working copy)
|
| @@ -10,6 +10,7 @@
|
|
|
| #include "SkAdvancedTypefaceMetrics.h"
|
| #include "SkColorFilter.h"
|
| +#include "SkDWrite.h"
|
| #include "SkDWriteFontFileStream.h"
|
| #include "SkDWriteGeometrySink.h"
|
| #include "SkDescriptor.h"
|
| @@ -42,79 +43,8 @@
|
| SkMask::kLCD32_Format == rec.fMaskFormat;
|
| }
|
|
|
| -/** Prefer to use this type to prevent template proliferation. */
|
| -typedef SkAutoSTMalloc<16, WCHAR> SkSMallocWCHAR;
|
| -
|
| -/** Converts a utf8 string to a WCHAR string. */
|
| -static HRESULT cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) {
|
| - int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, NULL, 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. */
|
| -static HRESULT wchar_to_skstring(WCHAR* name, SkString* skname) {
|
| - int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
|
| - if (0 == len) {
|
| - HRM(HRESULT_FROM_WIN32(GetLastError()),
|
| - "Could not get length for utf-8 to wchar conversion.");
|
| - }
|
| - skname->resize(len - 1);
|
| -
|
| - // TODO: remove after https://code.google.com/p/skia/issues/detail?id=1989 is fixed.
|
| - // If we resize to 0 then the skname points to gEmptyRec (the unique empty SkString::Rec).
|
| - // gEmptyRec is static const and on Windows this means the value is in a read only page.
|
| - // Writing to it in the following call to WideCharToMultiByte will cause an access violation.
|
| - if (1 == len) {
|
| - return S_OK;
|
| - }
|
| -
|
| - len = WideCharToMultiByte(CP_UTF8, 0, name, -1, skname->writable_str(), len, NULL, NULL);
|
| - if (0 == len) {
|
| - HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wchar.");
|
| - }
|
| - return S_OK;
|
| -}
|
| -
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -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.");
|
| -}
|
| -
|
| -static IDWriteFactory* get_dwrite_factory() {
|
| - static IDWriteFactory* gDWriteFactory = NULL;
|
| - SK_DECLARE_STATIC_ONCE(once);
|
| - SkOnce(&once, create_dwrite_factory, &gDWriteFactory);
|
| -
|
| - return gDWriteFactory;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| class StreamFontFileLoader;
|
|
|
| class SkFontMgr_DirectWrite : public SkFontMgr {
|
| @@ -215,7 +145,7 @@
|
| };
|
|
|
| const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) {
|
| - IDWriteFactory* factory = get_dwrite_factory();
|
| + IDWriteFactory* factory = sk_get_dwrite_factory();
|
| SkASSERT(factory != NULL);
|
|
|
| if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) {
|
| @@ -560,16 +490,19 @@
|
| fontFileLoader, fontCollectionLoader));
|
| }
|
|
|
| - ~DWriteFontTypeface() {
|
| +protected:
|
| + virtual void weak_dispose() const SK_OVERRIDE {
|
| if (fDWriteFontCollectionLoader.get() == NULL) return;
|
|
|
| - IDWriteFactory* factory = get_dwrite_factory();
|
| + IDWriteFactory* factory = sk_get_dwrite_factory();
|
| SkASSERT(factory != NULL);
|
| HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
|
| HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
|
| +
|
| + //SkTypefaceCache::Remove(this);
|
| + INHERITED::weak_dispose();
|
| }
|
|
|
| -protected:
|
| virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
|
| virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
|
| virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
|
| @@ -585,6 +518,9 @@
|
| virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
|
| virtual size_t onGetTableData(SkFontTableTag, size_t offset,
|
| size_t length, void* data) const SK_OVERRIDE;
|
| +
|
| +private:
|
| + typedef SkTypeface INHERITED;
|
| };
|
|
|
| class SkScalerContext_DW : public SkScalerContext {
|
| @@ -816,7 +752,7 @@
|
| run.isSideways = FALSE;
|
| run.glyphOffsets = &offset;
|
|
|
| - IDWriteFactory* factory = get_dwrite_factory();
|
| + IDWriteFactory* factory = sk_get_dwrite_factory();
|
| SkASSERT(factory != NULL);
|
|
|
| const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
|
| @@ -1067,7 +1003,7 @@
|
| HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+1));
|
|
|
| SkString utf8FamilyName;
|
| - HRV(wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName));
|
| + HRV(sk_wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName));
|
|
|
| desc->setFamilyName(utf8FamilyName.c_str());
|
| *isLocalStream = SkToBool(fDWriteFontFileLoader.get());
|
| @@ -1177,7 +1113,7 @@
|
| SkSMallocWCHAR wString(stringLength);
|
| HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could not get string.");
|
|
|
| - HRB(wchar_to_skstring(wString.get(), &localizedString->fString));
|
| + HRB(sk_wchar_to_skstring(wString.get(), &localizedString->fString));
|
|
|
| // Locale
|
| UINT32 localeLength;
|
| @@ -1187,7 +1123,7 @@
|
| SkSMallocWCHAR wLocale(localeLength);
|
| HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Could not get locale.");
|
|
|
| - HRB(wchar_to_skstring(wLocale.get(), &localizedString->fLanguage));
|
| + HRB(sk_wchar_to_skstring(wLocale.get(), &localizedString->fLanguage));
|
|
|
| ++fIndex;
|
| return true;
|
| @@ -1292,7 +1228,7 @@
|
| };
|
|
|
| static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) {
|
| - IDWriteFactory* factory = get_dwrite_factory();
|
| + IDWriteFactory* factory = sk_get_dwrite_factory();
|
| if (NULL == factory) {
|
| return NULL;
|
| }
|
| @@ -1531,7 +1467,7 @@
|
| wFamilyName[familyNameLength] = L' ';
|
| hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNameLength + 1);
|
|
|
| - hr = wchar_to_skstring(wFamilyName.get(), &info->fFontName);
|
| + hr = sk_wchar_to_skstring(wFamilyName.get(), &info->fFontName);
|
|
|
| if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
|
| populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode));
|
| @@ -1648,28 +1584,6 @@
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -static void 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;
|
| - names->FindLocaleName(preferedLocale, &nameIndex, &nameExists);
|
| - if (!nameExists) {
|
| - nameIndex = 0;
|
| - }
|
| - }
|
| -
|
| - UINT32 nameLength;
|
| - HRVM(names->GetStringLength(nameIndex, &nameLength), "Could not get name length.");
|
| - nameLength += 1;
|
| -
|
| - SkSMallocWCHAR name(nameLength);
|
| - HRVM(names->GetString(nameIndex, name.get(), nameLength), "Could not get string.");
|
| -
|
| - HRV(wchar_to_skstring(name.get(), skname));
|
| -}
|
| -
|
| SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont(
|
| IDWriteFontFace* fontFace,
|
| IDWriteFont* font,
|
| @@ -1698,7 +1612,7 @@
|
| SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
|
| HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names.");
|
|
|
| - get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
|
| + sk_get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
|
| }
|
|
|
| SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const {
|
| @@ -1710,7 +1624,7 @@
|
|
|
| SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) const {
|
| SkSMallocWCHAR dwFamilyName;
|
| - HRN(cstring_to_wchar(familyName, &dwFamilyName));
|
| + HRN(sk_cstring_to_wchar(familyName, &dwFamilyName));
|
|
|
| UINT32 index;
|
| BOOL exists;
|
| @@ -1785,7 +1699,7 @@
|
| SkTScopedComPtr<IDWriteFontFamily> fontFamily;
|
| if (familyName) {
|
| SkSMallocWCHAR wideFamilyName;
|
| - if (SUCCEEDED(cstring_to_wchar(familyName, &wideFamilyName))) {
|
| + if (SUCCEEDED(sk_cstring_to_wchar(familyName, &wideFamilyName))) {
|
| this->getByFamilyName(wideFamilyName, &fontFamily);
|
| }
|
| }
|
| @@ -1855,7 +1769,7 @@
|
| if (styleName) {
|
| SkTScopedComPtr<IDWriteLocalizedStrings> faceNames;
|
| if (SUCCEEDED(font->GetFaceNames(&faceNames))) {
|
| - get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), styleName);
|
| + sk_get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), styleName);
|
| }
|
| }
|
| }
|
| @@ -1879,7 +1793,7 @@
|
| SkTScopedComPtr<IDWriteFont> font;
|
| // TODO: perhaps use GetMatchingFonts and get the least simulated?
|
| HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
|
| - "Could not match font in family.");
|
| + "Could not match font in family.");
|
|
|
| SkTScopedComPtr<IDWriteFontFace> fontFace;
|
| HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
|
| @@ -1890,23 +1804,8 @@
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| -typedef decltype(GetUserDefaultLocaleName)* GetUserDefaultLocaleNameProc;
|
| -static HRESULT GetGetUserDefaultLocaleNameProc(GetUserDefaultLocaleNameProc* proc) {
|
| - *proc = reinterpret_cast<GetUserDefaultLocaleNameProc>(
|
| - 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;
|
| -}
|
| -
|
| SkFontMgr* SkFontMgr_New_DirectWrite() {
|
| - IDWriteFactory* factory = get_dwrite_factory();
|
| + IDWriteFactory* factory = sk_get_dwrite_factory();
|
| if (NULL == factory) {
|
| return NULL;
|
| }
|
| @@ -1920,8 +1819,8 @@
|
| int localeNameLen = 0;
|
|
|
| // Dynamically load GetUserDefaultLocaleName function, as it is not available on XP.
|
| - GetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL;
|
| - HRESULT hr = GetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc);
|
| + SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL;
|
| + HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc);
|
| if (NULL == getUserDefaultLocaleNameProc) {
|
| SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName.");
|
| } else {
|
| @@ -1933,3 +1832,12 @@
|
|
|
| return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeName, localeNameLen));
|
| }
|
| +
|
| +#include "SkFontMgr_indirect.h"
|
| +SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) {
|
| + SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite());
|
| + if (impl.get() == NULL) {
|
| + return NULL;
|
| + }
|
| + return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy));
|
| +}
|
|
|