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

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

Issue 946603002: Implement onMatchFamilyStyleCharacter for DirectWrite. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Line length. Created 5 years, 10 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 | « no previous file | src/ports/SkRemotableFontMgr_win_dw.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkDWrite.h" 8 #include "SkDWrite.h"
9 #include "SkDWriteFontFileStream.h" 9 #include "SkDWriteFontFileStream.h"
10 #include "SkFontMgr.h" 10 #include "SkFontMgr.h"
11 #include "SkHRESULT.h" 11 #include "SkHRESULT.h"
12 #include "SkStream.h" 12 #include "SkStream.h"
13 #include "SkTScopedComPtr.h" 13 #include "SkTScopedComPtr.h"
14 #include "SkThread.h" 14 #include "SkThread.h"
15 #include "SkTypeface.h" 15 #include "SkTypeface.h"
16 #include "SkTypefaceCache.h" 16 #include "SkTypefaceCache.h"
17 #include "SkTypeface_win_dw.h" 17 #include "SkTypeface_win_dw.h"
18 #include "SkTypes.h" 18 #include "SkTypes.h"
19 #include "SkUtils.h"
19 20
20 #include <dwrite.h> 21 #include <dwrite.h>
21 22
22 //////////////////////////////////////////////////////////////////////////////// 23 ////////////////////////////////////////////////////////////////////////////////
23 24
24 class StreamFontFileLoader : public IDWriteFontFileLoader { 25 class StreamFontFileLoader : public IDWriteFontFileLoader {
25 public: 26 public:
26 // IUnknown methods 27 // IUnknown methods
27 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t); 28 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t);
28 virtual ULONG STDMETHODCALLTYPE AddRef(); 29 virtual ULONG STDMETHODCALLTYPE AddRef();
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 IDWriteFont* font, 292 IDWriteFont* font,
292 IDWriteFontFamily* fontFamily) cons t; 293 IDWriteFontFamily* fontFamily) cons t;
293 294
294 SkTScopedComPtr<IDWriteFactory> fFactory; 295 SkTScopedComPtr<IDWriteFactory> fFactory;
295 SkTScopedComPtr<IDWriteFontCollection> fFontCollection; 296 SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
296 SkSMallocWCHAR fLocaleName; 297 SkSMallocWCHAR fLocaleName;
297 mutable SkMutex fTFCacheMutex; 298 mutable SkMutex fTFCacheMutex;
298 mutable SkTypefaceCache fTFCache; 299 mutable SkTypefaceCache fTFCache;
299 300
300 friend class SkFontStyleSet_DirectWrite; 301 friend class SkFontStyleSet_DirectWrite;
302 friend class FontFallbackRenderer;
301 }; 303 };
302 304
303 class SkFontStyleSet_DirectWrite : public SkFontStyleSet { 305 class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
304 public: 306 public:
305 SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr, 307 SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr,
306 IDWriteFontFamily* fontFamily) 308 IDWriteFontFamily* fontFamily)
307 : fFontMgr(SkRef(fontMgr)) 309 : fFontMgr(SkRef(fontMgr))
308 , fFontFamily(SkRefComPtr(fontFamily)) 310 , fFontFamily(SkRefComPtr(fontFamily))
309 { } 311 { }
310 312
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 482
481 return this->onCreateStyleSet(index); 483 return this->onCreateStyleSet(index);
482 } 484 }
483 485
484 SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[], 486 SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[],
485 const SkFontStyle& fontsty le) const { 487 const SkFontStyle& fontsty le) const {
486 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); 488 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
487 return sset->matchStyle(fontstyle); 489 return sset->matchStyle(fontstyle);
488 } 490 }
489 491
492 class FontFallbackRenderer : public IDWriteTextRenderer {
493 public:
494 FontFallbackRenderer(const SkFontMgr_DirectWrite* outer, UINT32 character)
495 : fRefCount(1), fOuter(SkSafeRef(outer)), fCharacter(character), fResolv edTypeface(NULL) {
496 }
497
498 virtual ~FontFallbackRenderer() { }
499
500 // IDWriteTextRenderer methods
501 virtual HRESULT STDMETHODCALLTYPE DrawGlyphRun(
502 void* clientDrawingContext,
503 FLOAT baselineOriginX,
504 FLOAT baselineOriginY,
505 DWRITE_MEASURING_MODE measuringMode,
506 DWRITE_GLYPH_RUN const* glyphRun,
507 DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
508 IUnknown* clientDrawingEffect) SK_OVERRIDE
509 {
510 SkTScopedComPtr<IDWriteFont> font;
511 HRM(fOuter->fFontCollection->GetFontFromFontFace(glyphRun->fontFace, &fo nt),
512 "Could not get font from font face.");
513
514 // It is possible that the font passed does not actually have the reques ted character,
515 // due to no font being found and getting the fallback font.
516 // Check that the font actually contains the requested character.
517 BOOL exists;
518 HRM(font->HasCharacter(fCharacter, &exists), "Could not find character." );
519
520 if (exists) {
521 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
522 HRM(font->GetFontFamily(&fontFamily), "Could not get family.");
523 fResolvedTypeface = fOuter->createTypefaceFromDWriteFont(glyphRun->f ontFace,
524 font.get(),
525 fontFamily. get());
526 }
527
528 return S_OK;
529 }
530
531 virtual HRESULT STDMETHODCALLTYPE DrawUnderline(
532 void* clientDrawingContext,
533 FLOAT baselineOriginX,
534 FLOAT baselineOriginY,
535 DWRITE_UNDERLINE const* underline,
536 IUnknown* clientDrawingEffect) SK_OVERRIDE
537 { return E_NOTIMPL; }
538
539 virtual HRESULT STDMETHODCALLTYPE DrawStrikethrough(
540 void* clientDrawingContext,
541 FLOAT baselineOriginX,
542 FLOAT baselineOriginY,
543 DWRITE_STRIKETHROUGH const* strikethrough,
544 IUnknown* clientDrawingEffect) SK_OVERRIDE
545 { return E_NOTIMPL; }
546
547 virtual HRESULT STDMETHODCALLTYPE DrawInlineObject(
548 void* clientDrawingContext,
549 FLOAT originX,
550 FLOAT originY,
551 IDWriteInlineObject* inlineObject,
552 BOOL isSideways,
553 BOOL isRightToLeft,
554 IUnknown* clientDrawingEffect) SK_OVERRIDE
555 { return E_NOTIMPL; }
556
557 // IDWritePixelSnapping methods
558 virtual HRESULT STDMETHODCALLTYPE IsPixelSnappingDisabled(
559 void* clientDrawingContext,
560 BOOL* isDisabled) SK_OVERRIDE
561 {
562 *isDisabled = FALSE;
563 return S_OK;
564 }
565
566 virtual HRESULT STDMETHODCALLTYPE GetCurrentTransform(
567 void* clientDrawingContext,
568 DWRITE_MATRIX* transform) SK_OVERRIDE
569 {
570 const DWRITE_MATRIX ident = { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 };
571 *transform = ident;
572 return S_OK;
573 }
574
575 virtual HRESULT STDMETHODCALLTYPE GetPixelsPerDip(
576 void* clientDrawingContext,
577 FLOAT* pixelsPerDip) SK_OVERRIDE
578 {
579 *pixelsPerDip = 1.0f;
580 return S_OK;
581 }
582
583 // IUnknown methods
584 ULONG STDMETHODCALLTYPE AddRef() SK_OVERRIDE {
585 return InterlockedIncrement(&fRefCount);
586 }
587
588 ULONG STDMETHODCALLTYPE Release() SK_OVERRIDE {
589 ULONG newCount = InterlockedDecrement(&fRefCount);
590 if (0 == newCount) {
591 delete this;
592 }
593 return newCount;
594 }
595
596 virtual HRESULT STDMETHODCALLTYPE QueryInterface(
597 IID const& riid, void** ppvObject) SK_OVERRIDE
598 {
599 if (__uuidof(IUnknown) == riid ||
600 __uuidof(IDWritePixelSnapping) == riid ||
601 __uuidof(IDWriteTextRenderer) == riid)
602 {
603 *ppvObject = this;
604 this->AddRef();
605 return S_OK;
606 }
607 *ppvObject = NULL;
608 return E_FAIL;
609 }
610
611 SkTypeface* FallbackTypeface() { return fResolvedTypeface; }
612
613 protected:
614 ULONG fRefCount;
615 SkAutoTUnref<const SkFontMgr_DirectWrite> fOuter;
616 UINT32 fCharacter;
617 SkTypeface* fResolvedTypeface;
618 };
619
620 static HRESULT getDefaultFontFamilyName(SkSMallocWCHAR* name) {
621 NONCLIENTMETRICSW metrics;
622 metrics.cbSize = sizeof(metrics);
623 if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(metrics), &me trics, 0)) {
624 return E_UNEXPECTED;
625 }
626
627 size_t len = wcsnlen_s(metrics.lfMessageFont.lfFaceName, LF_FACESIZE) + 1;
628 if (0 != wcsncpy_s(name->reset(len), len, metrics.lfMessageFont.lfFaceName, _TRUNCATE)) {
629 return E_UNEXPECTED;
630 }
631
632 return S_OK;
633 }
634
490 SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyleCharacter(const char family Name[], 635 SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyleCharacter(const char family Name[],
491 const SkFontStyle &, 636 const SkFontStyle & style,
492 const char* bcp47 [], int bcp47Count, 637 const char* bcp47 [], int bcp47Count,
493 SkUnichar charact er) const { 638 SkUnichar charact er) const
494 return NULL; 639 {
640 // TODO: use IDWriteFactory2::GetSystemFontFallback when available.
641
642 const DWriteStyle dwStyle(style);
643
644 SkSMallocWCHAR dwFamilyName;
645 if (NULL == familyName) {
646 HRN(getDefaultFontFamilyName(&dwFamilyName));
647 } else {
648 HRN(sk_cstring_to_wchar(familyName, &dwFamilyName));
649 }
650
651 const SkSMallocWCHAR* dwBcp47;
652 SkSMallocWCHAR dwBcp47Local;
653 if (bcp47Count < 1) {
654 dwBcp47 = &fLocaleName;
655 } else {
656 // TODO: support fallback stack.
657 // TODO: DirectWrite supports 'zh-CN' or 'zh-Hans', but 'zh' misses comp letely
658 // and may produce a Japanese font.
659 HRN(sk_cstring_to_wchar(bcp47[bcp47Count - 1], &dwBcp47Local));
660 dwBcp47 = &dwBcp47Local;
661 }
662
663 SkTScopedComPtr<IDWriteTextFormat> fallbackFormat;
664 HRNM(fFactory->CreateTextFormat(dwFamilyName,
665 fFontCollection.get(),
666 dwStyle.fWeight,
667 dwStyle.fSlant,
668 dwStyle.fWidth,
669 72.0f,
670 *dwBcp47,
671 &fallbackFormat),
672 "Could not create text format.");
673
674 WCHAR str[16];
675 UINT32 strLen = static_cast<UINT32>(
676 SkUTF16_FromUnichar(character, reinterpret_cast<uint16_t*>(str)));
677 SkTScopedComPtr<IDWriteTextLayout> fallbackLayout;
678 HRNM(fFactory->CreateTextLayout(str, strLen, fallbackFormat.get(),
679 200.0f, 200.0f,
680 &fallbackLayout),
681 "Could not create text layout.");
682
683 SkTScopedComPtr<FontFallbackRenderer> fontFallbackRenderer(
684 new FontFallbackRenderer(this, character));
685
686 HRNM(fallbackLayout->Draw(NULL, fontFallbackRenderer.get(), 50.0f, 50.0f),
687 "Could not draw layout with renderer.");
688
689 return fontFallbackRenderer->FallbackTypeface();
495 } 690 }
496 691
497 SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMemb er, 692 SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMemb er,
498 const SkFontStyle& fontstyle ) const { 693 const SkFontStyle& fontstyle ) const {
499 SkString familyName; 694 SkString familyName;
500 SkFontStyleSet_DirectWrite sset( 695 SkFontStyleSet_DirectWrite sset(
501 this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get() 696 this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
502 ); 697 );
503 return sset.matchStyle(fontstyle); 698 return sset.matchStyle(fontstyle);
504 } 699 }
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 } 960 }
766 961
767 #include "SkFontMgr_indirect.h" 962 #include "SkFontMgr_indirect.h"
768 SK_API SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { 963 SK_API SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) {
769 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); 964 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite());
770 if (impl.get() == NULL) { 965 if (impl.get() == NULL) {
771 return NULL; 966 return NULL;
772 } 967 }
773 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy)); 968 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy));
774 } 969 }
OLDNEW
« no previous file with comments | « no previous file | src/ports/SkRemotableFontMgr_win_dw.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698