1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci#include "src/utils/win/SkDWriteNTDDI_VERSION.h" 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 10cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_WIN) 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 13cb93a386Sopenharmony_ci#include "include/core/SkString.h" 14cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 15cb93a386Sopenharmony_ci#include "include/ports/SkRemotableFontMgr.h" 16cb93a386Sopenharmony_ci#include "include/private/SkMutex.h" 17cb93a386Sopenharmony_ci#include "include/private/SkTArray.h" 18cb93a386Sopenharmony_ci#include "src/ports/SkTypeface_win_dw.h" 19cb93a386Sopenharmony_ci#include "src/utils/SkUTF.h" 20cb93a386Sopenharmony_ci#include "src/utils/win/SkDWrite.h" 21cb93a386Sopenharmony_ci#include "src/utils/win/SkDWriteFontFileStream.h" 22cb93a386Sopenharmony_ci#include "src/utils/win/SkHRESULT.h" 23cb93a386Sopenharmony_ci#include "src/utils/win/SkObjBase.h" 24cb93a386Sopenharmony_ci#include "src/utils/win/SkTScopedComPtr.h" 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci#include <dwrite.h> 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ciclass SK_API SkRemotableFontMgr_DirectWrite : public SkRemotableFontMgr { 29cb93a386Sopenharmony_ciprivate: 30cb93a386Sopenharmony_ci struct DataId { 31cb93a386Sopenharmony_ci IUnknown* fLoader; // In COM only IUnknown pointers may be safely used for identity. 32cb93a386Sopenharmony_ci void* fKey; 33cb93a386Sopenharmony_ci UINT32 fKeySize; 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci DataId() { } 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci DataId(DataId&& that) : fLoader(that.fLoader), fKey(that.fKey), fKeySize(that.fKeySize) { 38cb93a386Sopenharmony_ci that.fLoader = nullptr; 39cb93a386Sopenharmony_ci that.fKey = nullptr; 40cb93a386Sopenharmony_ci SkDEBUGCODE(that.fKeySize = 0xFFFFFFFF;) 41cb93a386Sopenharmony_ci } 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci ~DataId() { 44cb93a386Sopenharmony_ci if (fLoader) { 45cb93a386Sopenharmony_ci fLoader->Release(); 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci sk_free(fKey); 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci }; 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci mutable SkTArray<DataId> fDataIdCache; 52cb93a386Sopenharmony_ci mutable SkMutex fDataIdCacheMutex; 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ci int FindOrAdd(IDWriteFontFileLoader* fontFileLoader, 55cb93a386Sopenharmony_ci const void* refKey, UINT32 refKeySize) const 56cb93a386Sopenharmony_ci { 57cb93a386Sopenharmony_ci SkTScopedComPtr<IUnknown> fontFileLoaderId; 58cb93a386Sopenharmony_ci HR_GENERAL(fontFileLoader->QueryInterface(&fontFileLoaderId), 59cb93a386Sopenharmony_ci "Failed to re-convert to IDWriteFontFileLoader.", 60cb93a386Sopenharmony_ci SkFontIdentity::kInvalidDataId); 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci SkAutoMutexExclusive ama(fDataIdCacheMutex); 63cb93a386Sopenharmony_ci int count = fDataIdCache.count(); 64cb93a386Sopenharmony_ci int i; 65cb93a386Sopenharmony_ci for (i = 0; i < count; ++i) { 66cb93a386Sopenharmony_ci const DataId& current = fDataIdCache[i]; 67cb93a386Sopenharmony_ci if (fontFileLoaderId.get() == current.fLoader && 68cb93a386Sopenharmony_ci refKeySize == current.fKeySize && 69cb93a386Sopenharmony_ci 0 == memcmp(refKey, current.fKey, refKeySize)) 70cb93a386Sopenharmony_ci { 71cb93a386Sopenharmony_ci return i; 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci DataId& added = fDataIdCache.push_back(); 75cb93a386Sopenharmony_ci added.fLoader = fontFileLoaderId.release(); // Ref is passed. 76cb93a386Sopenharmony_ci added.fKey = sk_malloc_throw(refKeySize); 77cb93a386Sopenharmony_ci memcpy(added.fKey, refKey, refKeySize); 78cb93a386Sopenharmony_ci added.fKeySize = refKeySize; 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci return i; 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_cipublic: 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci /** localeNameLength must include the null terminator. */ 87cb93a386Sopenharmony_ci SkRemotableFontMgr_DirectWrite(IDWriteFontCollection* fontCollection, 88cb93a386Sopenharmony_ci WCHAR* localeName, int localeNameLength) 89cb93a386Sopenharmony_ci : fFontCollection(SkRefComPtr(fontCollection)) 90cb93a386Sopenharmony_ci , fLocaleName(localeNameLength) 91cb93a386Sopenharmony_ci { 92cb93a386Sopenharmony_ci memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR)); 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci HRESULT FontToIdentity(IDWriteFont* font, SkFontIdentity* fontId) const { 96cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontFace> fontFace; 97cb93a386Sopenharmony_ci HRM(font->CreateFontFace(&fontFace), "Could not create font face."); 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci UINT32 numFiles; 100cb93a386Sopenharmony_ci HR(fontFace->GetFiles(&numFiles, nullptr)); 101cb93a386Sopenharmony_ci if (numFiles > 1) { 102cb93a386Sopenharmony_ci return E_FAIL; 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci // data id 106cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontFile> fontFile; 107cb93a386Sopenharmony_ci HR(fontFace->GetFiles(&numFiles, &fontFile)); 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader; 110cb93a386Sopenharmony_ci HR(fontFile->GetLoader(&fontFileLoader)); 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci const void* refKey; 113cb93a386Sopenharmony_ci UINT32 refKeySize; 114cb93a386Sopenharmony_ci HR(fontFile->GetReferenceKey(&refKey, &refKeySize)); 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci fontId->fDataId = FindOrAdd(fontFileLoader.get(), refKey, refKeySize); 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci // index 119cb93a386Sopenharmony_ci fontId->fTtcIndex = fontFace->GetIndex(); 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci // style 122cb93a386Sopenharmony_ci fontId->fFontStyle = get_style(font); 123cb93a386Sopenharmony_ci return S_OK; 124cb93a386Sopenharmony_ci } 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci SkRemotableFontIdentitySet* getIndex(int familyIndex) const override { 127cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontFamily> fontFamily; 128cb93a386Sopenharmony_ci HRNM(fFontCollection->GetFontFamily(familyIndex, &fontFamily), 129cb93a386Sopenharmony_ci "Could not get requested family."); 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci int count = fontFamily->GetFontCount(); 132cb93a386Sopenharmony_ci SkFontIdentity* fontIds; 133cb93a386Sopenharmony_ci sk_sp<SkRemotableFontIdentitySet> fontIdSet( 134cb93a386Sopenharmony_ci new SkRemotableFontIdentitySet(count, &fontIds)); 135cb93a386Sopenharmony_ci for (int fontIndex = 0; fontIndex < count; ++fontIndex) { 136cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFont> font; 137cb93a386Sopenharmony_ci HRNM(fontFamily->GetFont(fontIndex, &font), "Could not get font."); 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci HRN(FontToIdentity(font.get(), &fontIds[fontIndex])); 140cb93a386Sopenharmony_ci } 141cb93a386Sopenharmony_ci return fontIdSet.release(); 142cb93a386Sopenharmony_ci } 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci virtual SkFontIdentity matchIndexStyle(int familyIndex, 145cb93a386Sopenharmony_ci const SkFontStyle& pattern) const override 146cb93a386Sopenharmony_ci { 147cb93a386Sopenharmony_ci SkFontIdentity identity = { SkFontIdentity::kInvalidDataId }; 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontFamily> fontFamily; 150cb93a386Sopenharmony_ci HR_GENERAL(fFontCollection->GetFontFamily(familyIndex, &fontFamily), 151cb93a386Sopenharmony_ci "Could not get requested family.", 152cb93a386Sopenharmony_ci identity); 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci const DWriteStyle dwStyle(pattern); 155cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFont> font; 156cb93a386Sopenharmony_ci HR_GENERAL(fontFamily->GetFirstMatchingFont(dwStyle.fWeight, dwStyle.fWidth, 157cb93a386Sopenharmony_ci dwStyle.fSlant, &font), 158cb93a386Sopenharmony_ci "Could not match font in family.", 159cb93a386Sopenharmony_ci identity); 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ci HR_GENERAL(FontToIdentity(font.get(), &identity), nullptr, identity); 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_ci return identity; 164cb93a386Sopenharmony_ci } 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ci static HRESULT getDefaultFontFamilyName(SkSMallocWCHAR* name) { 167cb93a386Sopenharmony_ci NONCLIENTMETRICSW metrics; 168cb93a386Sopenharmony_ci metrics.cbSize = sizeof(metrics); 169cb93a386Sopenharmony_ci if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 170cb93a386Sopenharmony_ci sizeof(metrics), 171cb93a386Sopenharmony_ci &metrics, 172cb93a386Sopenharmony_ci 0)) { 173cb93a386Sopenharmony_ci return E_UNEXPECTED; 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_ci size_t len = wcsnlen_s(metrics.lfMessageFont.lfFaceName, LF_FACESIZE) + 1; 177cb93a386Sopenharmony_ci if (0 != wcsncpy_s(name->reset(len), len, metrics.lfMessageFont.lfFaceName, _TRUNCATE)) { 178cb93a386Sopenharmony_ci return E_UNEXPECTED; 179cb93a386Sopenharmony_ci } 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_ci return S_OK; 182cb93a386Sopenharmony_ci } 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_ci SkRemotableFontIdentitySet* matchName(const char familyName[]) const override { 185cb93a386Sopenharmony_ci SkSMallocWCHAR dwFamilyName; 186cb93a386Sopenharmony_ci if (nullptr == familyName) { 187cb93a386Sopenharmony_ci HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), 188cb93a386Sopenharmony_ci nullptr, SkRemotableFontIdentitySet::NewEmpty()); 189cb93a386Sopenharmony_ci } else { 190cb93a386Sopenharmony_ci HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), 191cb93a386Sopenharmony_ci nullptr, SkRemotableFontIdentitySet::NewEmpty()); 192cb93a386Sopenharmony_ci } 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_ci UINT32 index; 195cb93a386Sopenharmony_ci BOOL exists; 196cb93a386Sopenharmony_ci HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists), 197cb93a386Sopenharmony_ci "Failed while finding family by name.", 198cb93a386Sopenharmony_ci SkRemotableFontIdentitySet::NewEmpty()); 199cb93a386Sopenharmony_ci if (!exists) { 200cb93a386Sopenharmony_ci return SkRemotableFontIdentitySet::NewEmpty(); 201cb93a386Sopenharmony_ci } 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ci return this->getIndex(index); 204cb93a386Sopenharmony_ci } 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ci virtual SkFontIdentity matchNameStyle(const char familyName[], 207cb93a386Sopenharmony_ci const SkFontStyle& style) const override 208cb93a386Sopenharmony_ci { 209cb93a386Sopenharmony_ci SkFontIdentity identity = { SkFontIdentity::kInvalidDataId }; 210cb93a386Sopenharmony_ci 211cb93a386Sopenharmony_ci SkSMallocWCHAR dwFamilyName; 212cb93a386Sopenharmony_ci if (nullptr == familyName) { 213cb93a386Sopenharmony_ci HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), nullptr, identity); 214cb93a386Sopenharmony_ci } else { 215cb93a386Sopenharmony_ci HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), nullptr, identity); 216cb93a386Sopenharmony_ci } 217cb93a386Sopenharmony_ci 218cb93a386Sopenharmony_ci UINT32 index; 219cb93a386Sopenharmony_ci BOOL exists; 220cb93a386Sopenharmony_ci HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists), 221cb93a386Sopenharmony_ci "Failed while finding family by name.", 222cb93a386Sopenharmony_ci identity); 223cb93a386Sopenharmony_ci if (!exists) { 224cb93a386Sopenharmony_ci return identity; 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci 227cb93a386Sopenharmony_ci return this->matchIndexStyle(index, style); 228cb93a386Sopenharmony_ci } 229cb93a386Sopenharmony_ci 230cb93a386Sopenharmony_ci class FontFallbackRenderer : public IDWriteTextRenderer { 231cb93a386Sopenharmony_ci public: 232cb93a386Sopenharmony_ci FontFallbackRenderer(const SkRemotableFontMgr_DirectWrite* outer, UINT32 character) 233cb93a386Sopenharmony_ci : fRefCount(1), fOuter(SkSafeRef(outer)), fCharacter(character) { 234cb93a386Sopenharmony_ci fIdentity.fDataId = SkFontIdentity::kInvalidDataId; 235cb93a386Sopenharmony_ci } 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_ci virtual ~FontFallbackRenderer() { } 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_ci // IDWriteTextRenderer methods 240cb93a386Sopenharmony_ci SK_STDMETHODIMP DrawGlyphRun( 241cb93a386Sopenharmony_ci void* clientDrawingContext, 242cb93a386Sopenharmony_ci FLOAT baselineOriginX, 243cb93a386Sopenharmony_ci FLOAT baselineOriginY, 244cb93a386Sopenharmony_ci DWRITE_MEASURING_MODE measuringMode, 245cb93a386Sopenharmony_ci DWRITE_GLYPH_RUN const* glyphRun, 246cb93a386Sopenharmony_ci DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, 247cb93a386Sopenharmony_ci IUnknown* clientDrawingEffect) override 248cb93a386Sopenharmony_ci { 249cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFont> font; 250cb93a386Sopenharmony_ci HRM(fOuter->fFontCollection->GetFontFromFontFace(glyphRun->fontFace, &font), 251cb93a386Sopenharmony_ci "Could not get font from font face."); 252cb93a386Sopenharmony_ci 253cb93a386Sopenharmony_ci // It is possible that the font passed does not actually have the requested character, 254cb93a386Sopenharmony_ci // due to no font being found and getting the fallback font. 255cb93a386Sopenharmony_ci // Check that the font actually contains the requested character. 256cb93a386Sopenharmony_ci BOOL exists; 257cb93a386Sopenharmony_ci HRM(font->HasCharacter(fCharacter, &exists), "Could not find character."); 258cb93a386Sopenharmony_ci 259cb93a386Sopenharmony_ci if (exists) { 260cb93a386Sopenharmony_ci HR(fOuter->FontToIdentity(font.get(), &fIdentity)); 261cb93a386Sopenharmony_ci } 262cb93a386Sopenharmony_ci 263cb93a386Sopenharmony_ci return S_OK; 264cb93a386Sopenharmony_ci } 265cb93a386Sopenharmony_ci 266cb93a386Sopenharmony_ci SK_STDMETHODIMP DrawUnderline( 267cb93a386Sopenharmony_ci void* clientDrawingContext, 268cb93a386Sopenharmony_ci FLOAT baselineOriginX, 269cb93a386Sopenharmony_ci FLOAT baselineOriginY, 270cb93a386Sopenharmony_ci DWRITE_UNDERLINE const* underline, 271cb93a386Sopenharmony_ci IUnknown* clientDrawingEffect) override 272cb93a386Sopenharmony_ci { return E_NOTIMPL; } 273cb93a386Sopenharmony_ci 274cb93a386Sopenharmony_ci SK_STDMETHODIMP DrawStrikethrough( 275cb93a386Sopenharmony_ci void* clientDrawingContext, 276cb93a386Sopenharmony_ci FLOAT baselineOriginX, 277cb93a386Sopenharmony_ci FLOAT baselineOriginY, 278cb93a386Sopenharmony_ci DWRITE_STRIKETHROUGH const* strikethrough, 279cb93a386Sopenharmony_ci IUnknown* clientDrawingEffect) override 280cb93a386Sopenharmony_ci { return E_NOTIMPL; } 281cb93a386Sopenharmony_ci 282cb93a386Sopenharmony_ci SK_STDMETHODIMP DrawInlineObject( 283cb93a386Sopenharmony_ci void* clientDrawingContext, 284cb93a386Sopenharmony_ci FLOAT originX, 285cb93a386Sopenharmony_ci FLOAT originY, 286cb93a386Sopenharmony_ci IDWriteInlineObject* inlineObject, 287cb93a386Sopenharmony_ci BOOL isSideways, 288cb93a386Sopenharmony_ci BOOL isRightToLeft, 289cb93a386Sopenharmony_ci IUnknown* clientDrawingEffect) override 290cb93a386Sopenharmony_ci { return E_NOTIMPL; } 291cb93a386Sopenharmony_ci 292cb93a386Sopenharmony_ci // IDWritePixelSnapping methods 293cb93a386Sopenharmony_ci SK_STDMETHODIMP IsPixelSnappingDisabled( 294cb93a386Sopenharmony_ci void* clientDrawingContext, 295cb93a386Sopenharmony_ci BOOL* isDisabled) override 296cb93a386Sopenharmony_ci { 297cb93a386Sopenharmony_ci *isDisabled = FALSE; 298cb93a386Sopenharmony_ci return S_OK; 299cb93a386Sopenharmony_ci } 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_ci SK_STDMETHODIMP GetCurrentTransform( 302cb93a386Sopenharmony_ci void* clientDrawingContext, 303cb93a386Sopenharmony_ci DWRITE_MATRIX* transform) override 304cb93a386Sopenharmony_ci { 305cb93a386Sopenharmony_ci const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0}; 306cb93a386Sopenharmony_ci *transform = ident; 307cb93a386Sopenharmony_ci return S_OK; 308cb93a386Sopenharmony_ci } 309cb93a386Sopenharmony_ci 310cb93a386Sopenharmony_ci SK_STDMETHODIMP GetPixelsPerDip( 311cb93a386Sopenharmony_ci void* clientDrawingContext, 312cb93a386Sopenharmony_ci FLOAT* pixelsPerDip) override 313cb93a386Sopenharmony_ci { 314cb93a386Sopenharmony_ci *pixelsPerDip = 1.0f; 315cb93a386Sopenharmony_ci return S_OK; 316cb93a386Sopenharmony_ci } 317cb93a386Sopenharmony_ci 318cb93a386Sopenharmony_ci // IUnknown methods 319cb93a386Sopenharmony_ci SK_STDMETHODIMP_(ULONG) AddRef() override { 320cb93a386Sopenharmony_ci return InterlockedIncrement(&fRefCount); 321cb93a386Sopenharmony_ci } 322cb93a386Sopenharmony_ci 323cb93a386Sopenharmony_ci SK_STDMETHODIMP_(ULONG) Release() override { 324cb93a386Sopenharmony_ci ULONG newCount = InterlockedDecrement(&fRefCount); 325cb93a386Sopenharmony_ci if (0 == newCount) { 326cb93a386Sopenharmony_ci delete this; 327cb93a386Sopenharmony_ci } 328cb93a386Sopenharmony_ci return newCount; 329cb93a386Sopenharmony_ci } 330cb93a386Sopenharmony_ci 331cb93a386Sopenharmony_ci SK_STDMETHODIMP QueryInterface( 332cb93a386Sopenharmony_ci IID const& riid, void** ppvObject) override 333cb93a386Sopenharmony_ci { 334cb93a386Sopenharmony_ci if (__uuidof(IUnknown) == riid || 335cb93a386Sopenharmony_ci __uuidof(IDWritePixelSnapping) == riid || 336cb93a386Sopenharmony_ci __uuidof(IDWriteTextRenderer) == riid) 337cb93a386Sopenharmony_ci { 338cb93a386Sopenharmony_ci *ppvObject = this; 339cb93a386Sopenharmony_ci this->AddRef(); 340cb93a386Sopenharmony_ci return S_OK; 341cb93a386Sopenharmony_ci } 342cb93a386Sopenharmony_ci *ppvObject = nullptr; 343cb93a386Sopenharmony_ci return E_FAIL; 344cb93a386Sopenharmony_ci } 345cb93a386Sopenharmony_ci 346cb93a386Sopenharmony_ci const SkFontIdentity FallbackIdentity() { return fIdentity; } 347cb93a386Sopenharmony_ci 348cb93a386Sopenharmony_ci protected: 349cb93a386Sopenharmony_ci ULONG fRefCount; 350cb93a386Sopenharmony_ci sk_sp<const SkRemotableFontMgr_DirectWrite> fOuter; 351cb93a386Sopenharmony_ci UINT32 fCharacter; 352cb93a386Sopenharmony_ci SkFontIdentity fIdentity; 353cb93a386Sopenharmony_ci }; 354cb93a386Sopenharmony_ci 355cb93a386Sopenharmony_ci virtual SkFontIdentity matchNameStyleCharacter(const char familyName[], 356cb93a386Sopenharmony_ci const SkFontStyle& pattern, 357cb93a386Sopenharmony_ci const char* bcp47[], int bcp47Count, 358cb93a386Sopenharmony_ci SkUnichar character) const override 359cb93a386Sopenharmony_ci { 360cb93a386Sopenharmony_ci SkFontIdentity identity = { SkFontIdentity::kInvalidDataId }; 361cb93a386Sopenharmony_ci 362cb93a386Sopenharmony_ci IDWriteFactory* dwFactory = sk_get_dwrite_factory(); 363cb93a386Sopenharmony_ci if (nullptr == dwFactory) { 364cb93a386Sopenharmony_ci return identity; 365cb93a386Sopenharmony_ci } 366cb93a386Sopenharmony_ci 367cb93a386Sopenharmony_ci // TODO: use IDWriteFactory2::GetSystemFontFallback when available. 368cb93a386Sopenharmony_ci 369cb93a386Sopenharmony_ci const DWriteStyle dwStyle(pattern); 370cb93a386Sopenharmony_ci 371cb93a386Sopenharmony_ci SkSMallocWCHAR dwFamilyName; 372cb93a386Sopenharmony_ci if (nullptr == familyName) { 373cb93a386Sopenharmony_ci HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), nullptr, identity); 374cb93a386Sopenharmony_ci } else { 375cb93a386Sopenharmony_ci HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), nullptr, identity); 376cb93a386Sopenharmony_ci } 377cb93a386Sopenharmony_ci 378cb93a386Sopenharmony_ci const SkSMallocWCHAR* dwBcp47; 379cb93a386Sopenharmony_ci SkSMallocWCHAR dwBcp47Local; 380cb93a386Sopenharmony_ci if (bcp47Count < 1) { 381cb93a386Sopenharmony_ci dwBcp47 = &fLocaleName; 382cb93a386Sopenharmony_ci } else { 383cb93a386Sopenharmony_ci //TODO: support fallback stack. 384cb93a386Sopenharmony_ci HR_GENERAL(sk_cstring_to_wchar(bcp47[bcp47Count-1], &dwBcp47Local), nullptr, identity); 385cb93a386Sopenharmony_ci dwBcp47 = &dwBcp47Local; 386cb93a386Sopenharmony_ci } 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteTextFormat> fallbackFormat; 389cb93a386Sopenharmony_ci HR_GENERAL(dwFactory->CreateTextFormat(dwFamilyName, 390cb93a386Sopenharmony_ci fFontCollection.get(), 391cb93a386Sopenharmony_ci dwStyle.fWeight, 392cb93a386Sopenharmony_ci dwStyle.fSlant, 393cb93a386Sopenharmony_ci dwStyle.fWidth, 394cb93a386Sopenharmony_ci 72.0f, 395cb93a386Sopenharmony_ci *dwBcp47, 396cb93a386Sopenharmony_ci &fallbackFormat), 397cb93a386Sopenharmony_ci "Could not create text format.", 398cb93a386Sopenharmony_ci identity); 399cb93a386Sopenharmony_ci 400cb93a386Sopenharmony_ci WCHAR str[16]; 401cb93a386Sopenharmony_ci UINT32 strLen = static_cast<UINT32>( 402cb93a386Sopenharmony_ci SkUTF::ToUTF16(character, reinterpret_cast<uint16_t*>(str))); 403cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteTextLayout> fallbackLayout; 404cb93a386Sopenharmony_ci HR_GENERAL(dwFactory->CreateTextLayout(str, strLen, fallbackFormat.get(), 405cb93a386Sopenharmony_ci 200.0f, 200.0f, 406cb93a386Sopenharmony_ci &fallbackLayout), 407cb93a386Sopenharmony_ci "Could not create text layout.", 408cb93a386Sopenharmony_ci identity); 409cb93a386Sopenharmony_ci 410cb93a386Sopenharmony_ci SkTScopedComPtr<FontFallbackRenderer> fontFallbackRenderer( 411cb93a386Sopenharmony_ci new FontFallbackRenderer(this, character)); 412cb93a386Sopenharmony_ci 413cb93a386Sopenharmony_ci HR_GENERAL(fallbackLayout->Draw(nullptr, fontFallbackRenderer.get(), 50.0f, 50.0f), 414cb93a386Sopenharmony_ci "Could not draw layout with renderer.", 415cb93a386Sopenharmony_ci identity); 416cb93a386Sopenharmony_ci 417cb93a386Sopenharmony_ci return fontFallbackRenderer->FallbackIdentity(); 418cb93a386Sopenharmony_ci } 419cb93a386Sopenharmony_ci 420cb93a386Sopenharmony_ci SkStreamAsset* getData(int dataId) const override { 421cb93a386Sopenharmony_ci SkAutoMutexExclusive ama(fDataIdCacheMutex); 422cb93a386Sopenharmony_ci if (dataId >= fDataIdCache.count()) { 423cb93a386Sopenharmony_ci return nullptr; 424cb93a386Sopenharmony_ci } 425cb93a386Sopenharmony_ci const DataId& id = fDataIdCache[dataId]; 426cb93a386Sopenharmony_ci 427cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontFileLoader> loader; 428cb93a386Sopenharmony_ci HRNM(id.fLoader->QueryInterface(&loader), "QuerryInterface IDWriteFontFileLoader failed"); 429cb93a386Sopenharmony_ci 430cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontFileStream> fontFileStream; 431cb93a386Sopenharmony_ci HRNM(loader->CreateStreamFromKey(id.fKey, id.fKeySize, &fontFileStream), 432cb93a386Sopenharmony_ci "Could not create font file stream."); 433cb93a386Sopenharmony_ci 434cb93a386Sopenharmony_ci return new SkDWriteFontFileStream(fontFileStream.get()); 435cb93a386Sopenharmony_ci } 436cb93a386Sopenharmony_ci 437cb93a386Sopenharmony_ciprivate: 438cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontCollection> fFontCollection; 439cb93a386Sopenharmony_ci SkSMallocWCHAR fLocaleName; 440cb93a386Sopenharmony_ci 441cb93a386Sopenharmony_ci using INHERITED = SkRemotableFontMgr; 442cb93a386Sopenharmony_ci}; 443cb93a386Sopenharmony_ci 444cb93a386Sopenharmony_ciSkRemotableFontMgr* SkRemotableFontMgr_New_DirectWrite() { 445cb93a386Sopenharmony_ci IDWriteFactory* factory = sk_get_dwrite_factory(); 446cb93a386Sopenharmony_ci if (nullptr == factory) { 447cb93a386Sopenharmony_ci return nullptr; 448cb93a386Sopenharmony_ci } 449cb93a386Sopenharmony_ci 450cb93a386Sopenharmony_ci SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; 451cb93a386Sopenharmony_ci HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), 452cb93a386Sopenharmony_ci "Could not get system font collection."); 453cb93a386Sopenharmony_ci 454cb93a386Sopenharmony_ci WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; 455cb93a386Sopenharmony_ci WCHAR* localeName = nullptr; 456cb93a386Sopenharmony_ci int localeNameLen = 0; 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_ci // Dynamically load GetUserDefaultLocaleName function, as it is not available on XP. 459cb93a386Sopenharmony_ci SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = nullptr; 460cb93a386Sopenharmony_ci HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc); 461cb93a386Sopenharmony_ci if (nullptr == getUserDefaultLocaleNameProc) { 462cb93a386Sopenharmony_ci SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); 463cb93a386Sopenharmony_ci } else { 464cb93a386Sopenharmony_ci localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_NAME_MAX_LENGTH); 465cb93a386Sopenharmony_ci if (localeNameLen) { 466cb93a386Sopenharmony_ci localeName = localeNameStorage; 467cb93a386Sopenharmony_ci }; 468cb93a386Sopenharmony_ci } 469cb93a386Sopenharmony_ci 470cb93a386Sopenharmony_ci return new SkRemotableFontMgr_DirectWrite(sysFontCollection.get(), localeName, localeNameLen); 471cb93a386Sopenharmony_ci} 472cb93a386Sopenharmony_ci#endif//defined(SK_BUILD_FOR_WIN) 473