Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: src/ports/SkFontMgr_win_dw.cpp

Issue 314193002: Split SkFontHost_win_dw. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove unneeded includes. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ports/SkFontHost_win_dw.cpp ('k') | src/ports/SkScalerContext_win_dw.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "SkDWriteFontFileStream.h"
10 #include "SkFontMgr.h"
11 #include "SkHRESULT.h"
12 #include "SkStream.h"
13 #include "SkTScopedComPtr.h"
14 #include "SkThread.h"
15 #include "SkTypeface.h"
16 #include "SkTypefaceCache.h"
17 #include "SkTypeface_win_dw.h"
18 #include "SkTypes.h"
19
20 #include <dwrite.h>
21
22 ////////////////////////////////////////////////////////////////////////////////
23
24 class StreamFontFileLoader : public IDWriteFontFileLoader {
25 public:
26 // IUnknown methods
27 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t);
28 virtual ULONG STDMETHODCALLTYPE AddRef();
29 virtual ULONG STDMETHODCALLTYPE Release();
30
31 // IDWriteFontFileLoader methods
32 virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(
33 void const* fontFileReferenceKey,
34 UINT32 fontFileReferenceKeySize,
35 IDWriteFontFileStream** fontFileStream);
36
37 static HRESULT Create(SkStream* stream, StreamFontFileLoader** streamFontFil eLoader) {
38 *streamFontFileLoader = new StreamFontFileLoader(stream);
39 if (NULL == streamFontFileLoader) {
40 return E_OUTOFMEMORY;
41 }
42 return S_OK;
43 }
44
45 SkAutoTUnref<SkStream> fStream;
46
47 private:
48 StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(SkRef(stream) ) { }
49
50 ULONG fRefCount;
51 };
52
53 HRESULT StreamFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) {
54 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
55 *ppvObject = this;
56 AddRef();
57 return S_OK;
58 } else {
59 *ppvObject = NULL;
60 return E_NOINTERFACE;
61 }
62 }
63
64 ULONG StreamFontFileLoader::AddRef() {
65 return InterlockedIncrement(&fRefCount);
66 }
67
68 ULONG StreamFontFileLoader::Release() {
69 ULONG newCount = InterlockedDecrement(&fRefCount);
70 if (0 == newCount) {
71 delete this;
72 }
73 return newCount;
74 }
75
76 HRESULT StreamFontFileLoader::CreateStreamFromKey(
77 void const* fontFileReferenceKey,
78 UINT32 fontFileReferenceKeySize,
79 IDWriteFontFileStream** fontFileStream)
80 {
81 SkTScopedComPtr<SkDWriteFontFileStreamWrapper> stream;
82 HR(SkDWriteFontFileStreamWrapper::Create(fStream, &stream));
83 *fontFileStream = stream.release();
84 return S_OK;
85 }
86
87 ////////////////////////////////////////////////////////////////////////////////
88
89 class StreamFontFileEnumerator : public IDWriteFontFileEnumerator {
90 public:
91 // IUnknown methods
92 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t);
93 virtual ULONG STDMETHODCALLTYPE AddRef();
94 virtual ULONG STDMETHODCALLTYPE Release();
95
96 // IDWriteFontFileEnumerator methods
97 virtual HRESULT STDMETHODCALLTYPE MoveNext(BOOL* hasCurrentFile);
98 virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(IDWriteFontFile** fontF ile);
99
100 static HRESULT Create(IDWriteFactory* factory, IDWriteFontFileLoader* fontFi leLoader,
101 StreamFontFileEnumerator** streamFontFileEnumerator) {
102 *streamFontFileEnumerator = new StreamFontFileEnumerator(factory, fontFi leLoader);
103 if (NULL == streamFontFileEnumerator) {
104 return E_OUTOFMEMORY;
105 }
106 return S_OK;
107 }
108 private:
109 StreamFontFileEnumerator(IDWriteFactory* factory, IDWriteFontFileLoader* fon tFileLoader);
110 ULONG fRefCount;
111
112 SkTScopedComPtr<IDWriteFactory> fFactory;
113 SkTScopedComPtr<IDWriteFontFile> fCurrentFile;
114 SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
115 bool fHasNext;
116 };
117
118 StreamFontFileEnumerator::StreamFontFileEnumerator(IDWriteFactory* factory,
119 IDWriteFontFileLoader* fontFi leLoader)
120 : fRefCount(1)
121 , fFactory(SkRefComPtr(factory))
122 , fCurrentFile()
123 , fFontFileLoader(SkRefComPtr(fontFileLoader))
124 , fHasNext(true)
125 { }
126
127 HRESULT StreamFontFileEnumerator::QueryInterface(REFIID iid, void** ppvObject) {
128 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) {
129 *ppvObject = this;
130 AddRef();
131 return S_OK;
132 } else {
133 *ppvObject = NULL;
134 return E_NOINTERFACE;
135 }
136 }
137
138 ULONG StreamFontFileEnumerator::AddRef() {
139 return InterlockedIncrement(&fRefCount);
140 }
141
142 ULONG StreamFontFileEnumerator::Release() {
143 ULONG newCount = InterlockedDecrement(&fRefCount);
144 if (0 == newCount) {
145 delete this;
146 }
147 return newCount;
148 }
149
150 HRESULT StreamFontFileEnumerator::MoveNext(BOOL* hasCurrentFile) {
151 *hasCurrentFile = FALSE;
152
153 if (!fHasNext) {
154 return S_OK;
155 }
156 fHasNext = false;
157
158 UINT32 dummy = 0;
159 HR(fFactory->CreateCustomFontFileReference(
160 &dummy, //cannot be NULL
161 sizeof(dummy), //even if this is 0
162 fFontFileLoader.get(),
163 &fCurrentFile));
164
165 *hasCurrentFile = TRUE;
166 return S_OK;
167 }
168
169 HRESULT StreamFontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** fontFile) {
170 if (fCurrentFile.get() == NULL) {
171 *fontFile = NULL;
172 return E_FAIL;
173 }
174
175 *fontFile = SkRefComPtr(fCurrentFile.get());
176 return S_OK;
177 }
178
179 ////////////////////////////////////////////////////////////////////////////////
180
181 class StreamFontCollectionLoader : public IDWriteFontCollectionLoader {
182 public:
183 // IUnknown methods
184 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t);
185 virtual ULONG STDMETHODCALLTYPE AddRef();
186 virtual ULONG STDMETHODCALLTYPE Release();
187
188 // IDWriteFontCollectionLoader methods
189 virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(
190 IDWriteFactory* factory,
191 void const* collectionKey,
192 UINT32 collectionKeySize,
193 IDWriteFontFileEnumerator** fontFileEnumerator);
194
195 static HRESULT Create(IDWriteFontFileLoader* fontFileLoader,
196 StreamFontCollectionLoader** streamFontCollectionLoade r) {
197 *streamFontCollectionLoader = new StreamFontCollectionLoader(fontFileLoa der);
198 if (NULL == streamFontCollectionLoader) {
199 return E_OUTOFMEMORY;
200 }
201 return S_OK;
202 }
203 private:
204 StreamFontCollectionLoader(IDWriteFontFileLoader* fontFileLoader)
205 : fRefCount(1)
206 , fFontFileLoader(SkRefComPtr(fontFileLoader))
207 { }
208
209 ULONG fRefCount;
210 SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
211 };
212
213 HRESULT StreamFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) {
214 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) {
215 *ppvObject = this;
216 AddRef();
217 return S_OK;
218 } else {
219 *ppvObject = NULL;
220 return E_NOINTERFACE;
221 }
222 }
223
224 ULONG StreamFontCollectionLoader::AddRef() {
225 return InterlockedIncrement(&fRefCount);
226 }
227
228 ULONG StreamFontCollectionLoader::Release() {
229 ULONG newCount = InterlockedDecrement(&fRefCount);
230 if (0 == newCount) {
231 delete this;
232 }
233 return newCount;
234 }
235
236 HRESULT StreamFontCollectionLoader::CreateEnumeratorFromKey(
237 IDWriteFactory* factory,
238 void const* collectionKey,
239 UINT32 collectionKeySize,
240 IDWriteFontFileEnumerator** fontFileEnumerator)
241 {
242 SkTScopedComPtr<StreamFontFileEnumerator> enumerator;
243 HR(StreamFontFileEnumerator::Create(factory, fFontFileLoader.get(), &enumera tor));
244 *fontFileEnumerator = enumerator.release();
245 return S_OK;
246 }
247
248 ////////////////////////////////////////////////////////////////////////////////
249
250 class SkFontMgr_DirectWrite : public SkFontMgr {
251 public:
252 /** localeNameLength must include the null terminator. */
253 SkFontMgr_DirectWrite(IDWriteFactory* factory, IDWriteFontCollection* fontCo llection,
254 WCHAR* localeName, int localeNameLength)
255 : fFactory(SkRefComPtr(factory))
256 , fFontCollection(SkRefComPtr(fontCollection))
257 , fLocaleName(localeNameLength)
258 {
259 memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
260 }
261
262 /** Creates a typeface using a typeface cache. */
263 SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
264 IDWriteFont* font,
265 IDWriteFontFamily* fontFamily) cons t;
266
267 protected:
268 virtual int onCountFamilies() const SK_OVERRIDE;
269 virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR IDE;
270 virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE;
271 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE;
272 virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
273 const SkFontStyle& fontstyle) const S K_OVERRIDE;
274 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
275 const SkFontStyle& fontstyle) const SK_ OVERRIDE;
276 virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE;
277 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV ERRIDE;
278 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE;
279 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
280 unsigned styleBits) const SK_OVER RIDE;
281
282 private:
283 HRESULT getByFamilyName(const WCHAR familyName[], IDWriteFontFamily** fontFa mily) const;
284 HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily) const;
285
286 void Add(SkTypeface* face, SkTypeface::Style requestedStyle, bool strong) co nst {
287 SkAutoMutexAcquire ama(fTFCacheMutex);
288 fTFCache.add(face, requestedStyle, strong);
289 }
290
291 SkTypeface* FindByProcAndRef(SkTypefaceCache::FindProc proc, void* ctx) cons t {
292 SkAutoMutexAcquire ama(fTFCacheMutex);
293 SkTypeface* typeface = fTFCache.findByProcAndRef(proc, ctx);
294 return typeface;
295 }
296
297 SkTScopedComPtr<IDWriteFactory> fFactory;
298 SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
299 SkSMallocWCHAR fLocaleName;
300 mutable SkMutex fTFCacheMutex;
301 mutable SkTypefaceCache fTFCache;
302
303 friend class SkFontStyleSet_DirectWrite;
304 };
305
306 class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
307 public:
308 SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr,
309 IDWriteFontFamily* fontFamily)
310 : fFontMgr(SkRef(fontMgr))
311 , fFontFamily(SkRefComPtr(fontFamily))
312 { }
313
314 virtual int count() SK_OVERRIDE;
315 virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OV ERRIDE;
316 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE;
317 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE;
318
319 private:
320 SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr;
321 SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
322 };
323
324 static bool are_same(IUnknown* a, IUnknown* b) {
325 SkTScopedComPtr<IUnknown> iunkA;
326 if (FAILED(a->QueryInterface(&iunkA))) {
327 return false;
328 }
329
330 SkTScopedComPtr<IUnknown> iunkB;
331 if (FAILED(b->QueryInterface(&iunkB))) {
332 return false;
333 }
334
335 return iunkA.get() == iunkB.get();
336 }
337
338 static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style, void* ctx) {
339 //Check to see if the two fonts are identical.
340 DWriteFontTypeface* dwFace = reinterpret_cast<DWriteFontTypeface*>(face);
341 IDWriteFont* dwFont = reinterpret_cast<IDWriteFont*>(ctx);
342 if (are_same(dwFace->fDWriteFont.get(), dwFont)) {
343 return true;
344 }
345
346 //Check if the two fonts share the same loader and have the same key.
347 SkTScopedComPtr<IDWriteFontFace> dwFaceFontFace;
348 SkTScopedComPtr<IDWriteFontFace> dwFontFace;
349 HRB(dwFace->fDWriteFont->CreateFontFace(&dwFaceFontFace));
350 HRB(dwFont->CreateFontFace(&dwFontFace));
351 if (are_same(dwFaceFontFace.get(), dwFontFace.get())) {
352 return true;
353 }
354
355 UINT32 dwFaceNumFiles;
356 UINT32 dwNumFiles;
357 HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, NULL));
358 HRB(dwFontFace->GetFiles(&dwNumFiles, NULL));
359 if (dwFaceNumFiles != dwNumFiles) {
360 return false;
361 }
362
363 SkTScopedComPtr<IDWriteFontFile> dwFaceFontFile;
364 SkTScopedComPtr<IDWriteFontFile> dwFontFile;
365 HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, &dwFaceFontFile));
366 HRB(dwFontFace->GetFiles(&dwNumFiles, &dwFontFile));
367
368 //for (each file) { //we currently only admit fonts from one file.
369 SkTScopedComPtr<IDWriteFontFileLoader> dwFaceFontFileLoader;
370 SkTScopedComPtr<IDWriteFontFileLoader> dwFontFileLoader;
371 HRB(dwFaceFontFile->GetLoader(&dwFaceFontFileLoader));
372 HRB(dwFontFile->GetLoader(&dwFontFileLoader));
373 if (!are_same(dwFaceFontFileLoader.get(), dwFontFileLoader.get())) {
374 return false;
375 }
376 //}
377
378 const void* dwFaceFontRefKey;
379 UINT32 dwFaceFontRefKeySize;
380 const void* dwFontRefKey;
381 UINT32 dwFontRefKeySize;
382 HRB(dwFaceFontFile->GetReferenceKey(&dwFaceFontRefKey, &dwFaceFontRefKeySize ));
383 HRB(dwFontFile->GetReferenceKey(&dwFontRefKey, &dwFontRefKeySize));
384 if (dwFaceFontRefKeySize != dwFontRefKeySize) {
385 return false;
386 }
387 if (0 != memcmp(dwFaceFontRefKey, dwFontRefKey, dwFontRefKeySize)) {
388 return false;
389 }
390
391 //TODO: better means than comparing name strings?
392 //NOTE: .tfc and fake bold/italic will end up here.
393 SkTScopedComPtr<IDWriteFontFamily> dwFaceFontFamily;
394 SkTScopedComPtr<IDWriteFontFamily> dwFontFamily;
395 HRB(dwFace->fDWriteFont->GetFontFamily(&dwFaceFontFamily));
396 HRB(dwFont->GetFontFamily(&dwFontFamily));
397
398 SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontFamilyNames;
399 SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontNames;
400 HRB(dwFaceFontFamily->GetFamilyNames(&dwFaceFontFamilyNames));
401 HRB(dwFace->fDWriteFont->GetFaceNames(&dwFaceFontNames));
402
403 SkTScopedComPtr<IDWriteLocalizedStrings> dwFontFamilyNames;
404 SkTScopedComPtr<IDWriteLocalizedStrings> dwFontNames;
405 HRB(dwFontFamily->GetFamilyNames(&dwFontFamilyNames));
406 HRB(dwFont->GetFaceNames(&dwFontNames));
407
408 UINT32 dwFaceFontFamilyNameLength;
409 UINT32 dwFaceFontNameLength;
410 HRB(dwFaceFontFamilyNames->GetStringLength(0, &dwFaceFontFamilyNameLength));
411 HRB(dwFaceFontNames->GetStringLength(0, &dwFaceFontNameLength));
412
413 UINT32 dwFontFamilyNameLength;
414 UINT32 dwFontNameLength;
415 HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength));
416 HRB(dwFontNames->GetStringLength(0, &dwFontNameLength));
417
418 if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength ||
419 dwFaceFontNameLength != dwFontNameLength)
420 {
421 return false;
422 }
423
424 SkSMallocWCHAR dwFaceFontFamilyNameChar(dwFaceFontFamilyNameLength+1);
425 SkSMallocWCHAR dwFaceFontNameChar(dwFaceFontNameLength+1);
426 HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.get(), dwFa ceFontFamilyNameLength+1));
427 HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.get(), dwFaceFontNameLe ngth+1));
428
429 SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1);
430 SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1);
431 HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamily NameLength+1));
432 HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1));
433
434 return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) == 0 &&
435 wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0;
436 }
437
438 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont(
439 IDWriteFontFace* fontFace,
440 IDWriteFont* font,
441 IDWriteFontFamily* fontFamily) const {
442 SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font);
443 if (NULL == face) {
444 face = DWriteFontTypeface::Create(fFactory.get(), fontFace, font, fontFa mily);
445 if (face) {
446 Add(face, get_style(font), true);
447 }
448 }
449 return face;
450 }
451
452 int SkFontMgr_DirectWrite::onCountFamilies() const {
453 return fFontCollection->GetFontFamilyCount();
454 }
455
456 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con st {
457 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
458 HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ ested family.");
459
460 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
461 HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names." );
462
463 sk_get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
464 }
465
466 SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const {
467 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
468 HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ ested family.");
469
470 return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get()));
471 }
472
473 SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) co nst {
474 SkSMallocWCHAR dwFamilyName;
475 HRN(sk_cstring_to_wchar(familyName, &dwFamilyName));
476
477 UINT32 index;
478 BOOL exists;
479 HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
480 "Failed while finding family by name.");
481 if (!exists) {
482 return NULL;
483 }
484
485 return this->onCreateStyleSet(index);
486 }
487
488 SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[],
489 const SkFontStyle& fontsty le) const {
490 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
491 return sset->matchStyle(fontstyle);
492 }
493
494 SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMemb er,
495 const SkFontStyle& fontstyle ) const {
496 SkString familyName;
497 SkFontStyleSet_DirectWrite sset(
498 this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
499 );
500 return sset.matchStyle(fontstyle);
501 }
502
503 template <typename T> class SkAutoIDWriteUnregister {
504 public:
505 SkAutoIDWriteUnregister(IDWriteFactory* factory, T* unregister)
506 : fFactory(factory), fUnregister(unregister)
507 { }
508
509 ~SkAutoIDWriteUnregister() {
510 if (fUnregister) {
511 unregister(fFactory, fUnregister);
512 }
513 }
514
515 T* detatch() {
516 T* old = fUnregister;
517 fUnregister = NULL;
518 return old;
519 }
520
521 private:
522 HRESULT unregister(IDWriteFactory* factory, IDWriteFontFileLoader* unregiste r) {
523 return factory->UnregisterFontFileLoader(unregister);
524 }
525
526 HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unr egister) {
527 return factory->UnregisterFontCollectionLoader(unregister);
528 }
529
530 IDWriteFactory* fFactory;
531 T* fUnregister;
532 };
533
534 SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcI ndex) const {
535 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
536 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader));
537 HRN(fFactory->RegisterFontFileLoader(fontFileLoader.get()));
538 SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader(
539 fFactory.get(), fontFileLoader.get());
540
541 SkTScopedComPtr<StreamFontCollectionLoader> fontCollectionLoader;
542 HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &fontCollection Loader));
543 HRN(fFactory->RegisterFontCollectionLoader(fontCollectionLoader.get()));
544 SkAutoIDWriteUnregister<StreamFontCollectionLoader> autoUnregisterFontCollec tionLoader(
545 fFactory.get(), fontCollectionLoader.get());
546
547 SkTScopedComPtr<IDWriteFontCollection> fontCollection;
548 HRN(fFactory->CreateCustomFontCollection(fontCollectionLoader.get(), NULL, 0 , &fontCollection));
549
550 // Find the first non-simulated font which has the given ttc index.
551 UINT32 familyCount = fontCollection->GetFontFamilyCount();
552 for (UINT32 familyIndex = 0; familyIndex < familyCount; ++familyIndex) {
553 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
554 HRN(fontCollection->GetFontFamily(familyIndex, &fontFamily));
555
556 UINT32 fontCount = fontFamily->GetFontCount();
557 for (UINT32 fontIndex = 0; fontIndex < fontCount; ++fontIndex) {
558 SkTScopedComPtr<IDWriteFont> font;
559 HRN(fontFamily->GetFont(fontIndex, &font));
560 if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) {
561 continue;
562 }
563
564 SkTScopedComPtr<IDWriteFontFace> fontFace;
565 HRN(font->CreateFontFace(&fontFace));
566
567 UINT32 faceIndex = fontFace->GetIndex();
568 if (faceIndex == ttcIndex) {
569 return DWriteFontTypeface::Create(fFactory.get(),
570 fontFace.get(), font.get(), fo ntFamily.get(),
571 autoUnregisterFontFileLoader.d etatch(),
572 autoUnregisterFontCollectionLo ader.detatch());
573 }
574 }
575 }
576
577 return NULL;
578 }
579
580 SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) const {
581 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
582 return this->createFromStream(stream, ttcIndex);
583 }
584
585 SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIn dex) const {
586 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
587 return this->createFromStream(stream, ttcIndex);
588 }
589
590 HRESULT SkFontMgr_DirectWrite::getByFamilyName(const WCHAR wideFamilyName[],
591 IDWriteFontFamily** fontFamily) c onst {
592 UINT32 index;
593 BOOL exists;
594 HR(fFontCollection->FindFamilyName(wideFamilyName, &index, &exists));
595
596 if (exists) {
597 HR(fFontCollection->GetFontFamily(index, fontFamily));
598 }
599 return S_OK;
600 }
601
602 HRESULT SkFontMgr_DirectWrite::getDefaultFontFamily(IDWriteFontFamily** fontFami ly) const {
603 NONCLIENTMETRICSW metrics;
604 metrics.cbSize = sizeof(metrics);
605 if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
606 sizeof(metrics),
607 &metrics,
608 0)) {
609 return E_UNEXPECTED;
610 }
611 HRM(this->getByFamilyName(metrics.lfMessageFont.lfFaceName, fontFamily),
612 "Could not create DWrite font family from LOGFONT.");
613 return S_OK;
614 }
615
616 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[ ],
617 unsigned styleBits) co nst {
618 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
619 if (familyName) {
620 SkSMallocWCHAR wideFamilyName;
621 if (SUCCEEDED(sk_cstring_to_wchar(familyName, &wideFamilyName))) {
622 this->getByFamilyName(wideFamilyName, &fontFamily);
623 }
624 }
625
626 if (NULL == fontFamily.get()) {
627 // No family with given name, try default.
628 HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default fon t family.");
629 }
630
631 if (NULL == fontFamily.get()) {
632 // Could not obtain the default font.
633 HRNM(fFontCollection->GetFontFamily(0, &fontFamily),
634 "Could not get default-default font family.");
635 }
636
637 SkTScopedComPtr<IDWriteFont> font;
638 DWRITE_FONT_WEIGHT weight = (styleBits & SkTypeface::kBold)
639 ? DWRITE_FONT_WEIGHT_BOLD
640 : DWRITE_FONT_WEIGHT_NORMAL;
641 DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL;
642 DWRITE_FONT_STYLE italic = (styleBits & SkTypeface::kItalic)
643 ? DWRITE_FONT_STYLE_ITALIC
644 : DWRITE_FONT_STYLE_NORMAL;
645 HRNM(fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font),
646 "Could not get matching font.");
647
648 SkTScopedComPtr<IDWriteFontFace> fontFace;
649 HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
650
651 return this->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFa mily.get());
652 }
653
654 ///////////////////////////////////////////////////////////////////////////////
655
656 int SkFontStyleSet_DirectWrite::count() {
657 return fFontFamily->GetFontCount();
658 }
659
660 SkTypeface* SkFontStyleSet_DirectWrite::createTypeface(int index) {
661 SkTScopedComPtr<IDWriteFont> font;
662 HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
663
664 SkTScopedComPtr<IDWriteFontFace> fontFace;
665 HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
666
667 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fF ontFamily.get());
668 }
669
670 void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) {
671 SkTScopedComPtr<IDWriteFont> font;
672 HRVM(fFontFamily->GetFont(index, &font), "Could not get font.");
673
674 if (fs) {
675 SkFontStyle::Slant slant;
676 switch (font->GetStyle()) {
677 case DWRITE_FONT_STYLE_NORMAL:
678 slant = SkFontStyle::kUpright_Slant;
679 break;
680 case DWRITE_FONT_STYLE_OBLIQUE:
681 case DWRITE_FONT_STYLE_ITALIC:
682 slant = SkFontStyle::kItalic_Slant;
683 break;
684 default:
685 SkASSERT(false);
686 }
687
688 int weight = font->GetWeight();
689 int width = font->GetStretch();
690
691 *fs = SkFontStyle(weight, width, slant);
692 }
693
694 if (styleName) {
695 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames;
696 if (SUCCEEDED(font->GetFaceNames(&faceNames))) {
697 sk_get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), s tyleName);
698 }
699 }
700 }
701
702 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) {
703 DWRITE_FONT_STYLE slant;
704 switch (pattern.slant()) {
705 case SkFontStyle::kUpright_Slant:
706 slant = DWRITE_FONT_STYLE_NORMAL;
707 break;
708 case SkFontStyle::kItalic_Slant:
709 slant = DWRITE_FONT_STYLE_ITALIC;
710 break;
711 default:
712 SkASSERT(false);
713 }
714
715 DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight();
716 DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
717
718 SkTScopedComPtr<IDWriteFont> font;
719 // TODO: perhaps use GetMatchingFonts and get the least simulated?
720 HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
721 "Could not match font in family.");
722
723 SkTScopedComPtr<IDWriteFontFace> fontFace;
724 HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
725
726 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(),
727 fFontFamily.get());
728 }
729
730 ////////////////////////////////////////////////////////////////////////////////
731
732 SkFontMgr* SkFontMgr_New_DirectWrite(IDWriteFactory* factory) {
733 if (NULL == factory) {
734 factory = sk_get_dwrite_factory();
735 if (NULL == factory) {
736 return NULL;
737 }
738 }
739
740 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection;
741 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE),
742 "Could not get system font collection.");
743
744 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH];
745 WCHAR* localeName = NULL;
746 int localeNameLen = 0;
747
748 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl e on XP.
749 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL;
750 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc );
751 if (NULL == getUserDefaultLocaleNameProc) {
752 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName.");
753 } else {
754 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N AME_MAX_LENGTH);
755 if (localeNameLen) {
756 localeName = localeNameStorage;
757 };
758 }
759
760 return SkNEW_ARGS(SkFontMgr_DirectWrite, (factory, sysFontCollection.get(),
761 localeName, localeNameLen));
762 }
763
764 ////////////////////////////////////////////////////////////////////////////////
765
766 #include "SkFontMgr_indirect.h"
767 #include "SkTypeface_win.h"
768 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) {
769 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite());
770 if (impl.get() == NULL) {
771 return NULL;
772 }
773 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy));
774 }
OLDNEW
« no previous file with comments | « src/ports/SkFontHost_win_dw.cpp ('k') | src/ports/SkScalerContext_win_dw.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698