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

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

Issue 263503004: Add support for kEmbeddedBitmapText_Flag to DirectWrite. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/sfnt/SkOTTable_EBDT.h » ('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 2011 Google Inc. 2 * Copyright 2011 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 "SkTypes.h" 8 #include "SkTypes.h"
9 #undef GetGlyphIndices 9 #undef GetGlyphIndices
10 10
11 #include "SkAdvancedTypefaceMetrics.h" 11 #include "SkAdvancedTypefaceMetrics.h"
12 #include "SkColorFilter.h" 12 #include "SkColorFilter.h"
13 #include "SkDWrite.h" 13 #include "SkDWrite.h"
14 #include "SkDWriteFontFileStream.h" 14 #include "SkDWriteFontFileStream.h"
15 #include "SkDWriteGeometrySink.h" 15 #include "SkDWriteGeometrySink.h"
16 #include "SkDescriptor.h" 16 #include "SkDescriptor.h"
17 #include "SkEndian.h" 17 #include "SkEndian.h"
18 #include "SkFontDescriptor.h" 18 #include "SkFontDescriptor.h"
19 #include "SkFontHost.h" 19 #include "SkFontHost.h"
20 #include "SkFontMgr.h" 20 #include "SkFontMgr.h"
21 #include "SkFontStream.h" 21 #include "SkFontStream.h"
22 #include "SkGlyph.h" 22 #include "SkGlyph.h"
23 #include "SkHRESULT.h" 23 #include "SkHRESULT.h"
24 #include "SkMaskGamma.h" 24 #include "SkMaskGamma.h"
25 #include "SkMatrix22.h"
25 #include "SkOnce.h" 26 #include "SkOnce.h"
27 #include "SkOTTable_EBLC.h"
28 #include "SkOTTable_EBSC.h"
26 #include "SkOTTable_head.h" 29 #include "SkOTTable_head.h"
27 #include "SkOTTable_hhea.h" 30 #include "SkOTTable_hhea.h"
28 #include "SkOTTable_OS_2.h" 31 #include "SkOTTable_OS_2.h"
29 #include "SkOTTable_post.h" 32 #include "SkOTTable_post.h"
30 #include "SkPath.h" 33 #include "SkPath.h"
31 #include "SkStream.h" 34 #include "SkStream.h"
32 #include "SkString.h" 35 #include "SkString.h"
33 #include "SkTScopedComPtr.h" 36 #include "SkTScopedComPtr.h"
34 #include "SkThread.h" 37 #include "SkThread.h"
35 #include "SkTypeface_win.h" 38 #include "SkTypeface_win.h"
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE; 445 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
443 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE; 446 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
444 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE; 447 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
445 virtual void generateFontMetrics(SkPaint::FontMetrics* mX, 448 virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
446 SkPaint::FontMetrics* mY) SK_OVERRIDE; 449 SkPaint::FontMetrics* mY) SK_OVERRIDE;
447 450
448 private: 451 private:
449 const void* drawDWMask(const SkGlyph& glyph); 452 const void* drawDWMask(const SkGlyph& glyph);
450 453
451 SkTDArray<uint8_t> fBits; 454 SkTDArray<uint8_t> fBits;
455 /** The total matrix without the text height scale. */
456 SkMatrix fSkXform;
457 /** The total matrix without the text height scale. */
452 DWRITE_MATRIX fXform; 458 DWRITE_MATRIX fXform;
459 /** The non-rotational part of total matrix without the text height scale.
460 * This is used to find the magnitude of gdi compatible advances.
461 */
462 DWRITE_MATRIX fGsA;
463 /** The inverse of the rotational part of the total matrix.
464 * This is used to find the direction of gdi compatible advances.
465 */
466 SkMatrix fG_inv;
467 /** The text size to render with. */
468 SkScalar fTextSizeRender;
469 /** The text size to measure with. */
470 SkScalar fTextSizeMeasure;
453 SkAutoTUnref<DWriteFontTypeface> fTypeface; 471 SkAutoTUnref<DWriteFontTypeface> fTypeface;
454 int fGlyphCount; 472 int fGlyphCount;
455 DWRITE_RENDERING_MODE fRenderingMode; 473 DWRITE_RENDERING_MODE fRenderingMode;
456 DWRITE_TEXTURE_TYPE fTextureType; 474 DWRITE_TEXTURE_TYPE fTextureType;
457 DWRITE_MEASURING_MODE fMeasuringMode; 475 DWRITE_MEASURING_MODE fMeasuringMode;
458 }; 476 };
459 477
460 static bool are_same(IUnknown* a, IUnknown* b) { 478 static bool are_same(IUnknown* a, IUnknown* b) {
461 SkTScopedComPtr<IUnknown> iunkA; 479 SkTScopedComPtr<IUnknown> iunkA;
462 if (FAILED(a->QueryInterface(&iunkA))) { 480 if (FAILED(a->QueryInterface(&iunkA))) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 581
564 SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1); 582 SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1);
565 SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1); 583 SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1);
566 HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamily NameLength+1)); 584 HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamily NameLength+1));
567 HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1)); 585 HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1));
568 586
569 return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) == 0 && 587 return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) == 0 &&
570 wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0; 588 wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0;
571 } 589 }
572 590
591 class AutoDWriteTable {
592 public:
593 AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFac e), fExists(FALSE) {
594 // Any errors are ignored, user must check fExists anyway.
595 fontFace->TryGetFontTable(beTag,
596 reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
597 }
598 ~AutoDWriteTable() {
599 if (fExists) {
600 fFontFace->ReleaseFontTable(fLock);
601 }
602 }
603
604 const uint8_t* fData;
605 UINT32 fSize;
606 BOOL fExists;
607 private:
608 // Borrowed reference, the user must ensure the fontFace stays alive.
609 IDWriteFontFace* fFontFace;
610 void* fLock;
611 };
612 template<typename T> class AutoTDWriteTable : public AutoDWriteTable {
613 public:
614 static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2 , T::TAG3);
615 AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { }
616
617 const T* get() const { return reinterpret_cast<const T*>(fData); }
618 const T* operator->() const { return reinterpret_cast<const T*>(fData); }
619 };
620
621 static bool hasBitmapStrike(DWriteFontTypeface* typeface, int size) {
622 {
623 AutoTDWriteTable<SkOTTableEmbeddedBitmapLocation> eblc(typeface->fDWrite FontFace.get());
624 if (!eblc.fExists) {
625 return false;
626 }
627 if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation)) {
628 return false;
629 }
630 if (eblc->version != SkOTTableEmbeddedBitmapLocation::version_initial) {
631 return false;
632 }
633
634 uint32_t numSizes = SkEndianSwap32(eblc->numSizes);
635 if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation) +
636 sizeof(SkOTTableEmbeddedBitmapLocation::BitmapSizeTable ) * numSizes)
637 {
638 return false;
639 }
640
641 const SkOTTableEmbeddedBitmapLocation::BitmapSizeTable* sizeTable =
642 SkTAfter<const SkOTTableEmbeddedBitmapLocation::BitmapSizeTable> (eblc.get());
643 for (uint32_t i = 0; i < numSizes; ++i, ++sizeTable) {
644 if (sizeTable->ppemX == size && sizeTable->ppemY == size) {
645 // TODO: determine if we should dig through IndexSubTableArray/I ndexSubTable
646 // to determine the actual number of glyphs with bitmaps.
647
648 // TODO: Ensure that the bitmaps actually cover a significant po rtion of the strike.
649
650 //TODO: Endure that the bitmaps are bi-level.
651 if (sizeTable->endGlyphIndex >= sizeTable->startGlyphIndex + 3) {
652 return true;
653 }
654 }
655 }
656 }
657
658 {
659 AutoTDWriteTable<SkOTTableEmbeddedBitmapScaling> ebsc(typeface->fDWriteF ontFace.get());
660 if (!ebsc.fExists) {
661 return false;
662 }
663 if (ebsc.fSize < sizeof(SkOTTableEmbeddedBitmapScaling)) {
664 return false;
665 }
666 if (ebsc->version != SkOTTableEmbeddedBitmapScaling::version_initial) {
667 return false;
668 }
669
670 uint32_t numSizes = SkEndianSwap32(ebsc->numSizes);
671 if (ebsc.fSize < sizeof(SkOTTableEmbeddedBitmapScaling) +
672 sizeof(SkOTTableEmbeddedBitmapScaling::BitmapScaleTable ) * numSizes)
673 {
674 return false;
675 }
676
677 const SkOTTableEmbeddedBitmapScaling::BitmapScaleTable* scaleTable =
678 SkTAfter<const SkOTTableEmbeddedBitmapScaling::BitmapScaleTable> (ebsc.get());
679 for (uint32_t i = 0; i < numSizes; ++i, ++scaleTable) {
680 if (scaleTable->ppemX == size && scaleTable->ppemY == size) {
681 // EBSC tables are normally only found in bitmap only fonts.
682 return true;
683 }
684 }
685 }
686
687 return false;
688 }
689
690 static bool bothZero(SkScalar a, SkScalar b) {
691 return 0 == a && 0 == b;
692 }
693
694 // returns false if there is any non-90-rotation or skew
695 static bool isAxisAligned(const SkScalerContext::Rec& rec) {
696 return 0 == rec.fPreSkewX &&
697 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
698 bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
699 }
700
573 SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface, 701 SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
574 const SkDescriptor* desc) 702 const SkDescriptor* desc)
575 : SkScalerContext(typeface, desc) 703 : SkScalerContext(typeface, desc)
576 , fTypeface(SkRef(typeface)) 704 , fTypeface(SkRef(typeface))
577 , fGlyphCount(-1) { 705 , fGlyphCount(-1) {
578 706
579 fXform.m11 = SkScalarToFloat(fRec.fPost2x2[0][0]); 707 // In general, all glyphs should use CLEARTYPE_NATURAL_SYMMETRIC
580 fXform.m12 = SkScalarToFloat(fRec.fPost2x2[1][0]); 708 // except when bi-level rendering is requested or there are embedded
581 fXform.m21 = SkScalarToFloat(fRec.fPost2x2[0][1]); 709 // bi-level bitmaps (and the embedded bitmap flag is set and no rotation).
582 fXform.m22 = SkScalarToFloat(fRec.fPost2x2[1][1]); 710 //
711 // DirectWrite's IDWriteFontFace::GetRecommendedRenderingMode does not do
712 // this. As a result, determine the actual size of the text and then see if
713 // there are any embedded bi-level bitmaps of that size. If there are, then
714 // force bitmaps by requesting bi-level rendering.
715 //
716 // FreeType allows for separate ppemX and ppemY, but DirectWrite assumes
717 // square pixels and only uses ppemY. Therefore the transform must track any
718 // non-uniform x-scale.
719 //
720 // Also, rotated glyphs should have the same absolute advance widths as
721 // horizontal glyphs and the subpixel flag should not affect glyph shapes.
722
723 // A is the total matrix.
724 SkMatrix A;
725 fRec.getSingleMatrix(&A);
726
727 // h is where A maps the horizontal baseline.
728 SkPoint h = SkPoint::Make(SK_Scalar1, 0);
729 A.mapPoints(&h, 1);
730
731 // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
732 SkMatrix G;
733 SkComputeGivensRotation(h, &G);
734
735 // GA is the matrix A with rotation removed.
736 SkMatrix GA(G);
737 GA.preConcat(A);
738
739 // realTextSize is the actual device size we want (as opposed to the size th e user requested).
740 // gdiTextSize is the size we request when GDI compatible.
741 // If the scale is negative, this means the matrix will do the flip anyway.
742 SkScalar realTextSize = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
743 // Due to floating point math, the lower bits are suspect. Round carefully.
744 SkScalar roundedTextSize = SkScalarRoundToScalar(realTextSize * 64.0f) / 64. 0f;
745 SkScalar gdiTextSize = SkScalarFloorToScalar(roundedTextSize);
746 if (gdiTextSize == 0) {
747 gdiTextSize = SK_Scalar1;
748 }
749
750 bool hasBitmap = fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag &&
751 hasBitmapStrike(typeface, SkScalarTruncToInt(gdiTextSize));
752 bool axisAligned = isAxisAligned(fRec);
753 bool isBiLevel = SkMask::kBW_Format == fRec.fMaskFormat || (hasBitmap && axi sAligned);
754
755 if (isBiLevel) {
756 fTextSizeRender = gdiTextSize;
757 fRenderingMode = DWRITE_RENDERING_MODE_ALIASED;
758 fTextureType = DWRITE_TEXTURE_ALIASED_1x1;
759 fTextSizeMeasure = gdiTextSize;
760 fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
761 } else if (hasBitmap) {
762 // If rotated but the horizontal text would have used a bitmap,
763 // render high quality rotated glyphs using the bitmap metrics.
764 fTextSizeRender = gdiTextSize;
765 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
766 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
767 fTextSizeMeasure = gdiTextSize;
768 fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
769 } else {
770 fTextSizeRender = realTextSize;
771 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
772 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
773 fTextSizeMeasure = realTextSize;
774 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
775 }
776
777 if (this->isSubpixel()) {
778 fTextSizeMeasure = realTextSize;
779 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
780 }
781
782 // Remove the realTextSize, as that is the text height scale currently in A.
783 SkScalar scale = SkScalarInvert(realTextSize);
784
785 // fSkXform is the total matrix A without the text height scale.
786 fSkXform = A;
787 fSkXform.preScale(scale, scale); //remove the text height scale.
788
789 fXform.m11 = SkScalarToFloat(fSkXform.getScaleX());
790 fXform.m12 = SkScalarToFloat(fSkXform.getSkewY());
791 fXform.m21 = SkScalarToFloat(fSkXform.getSkewX());
792 fXform.m22 = SkScalarToFloat(fSkXform.getScaleY());
583 fXform.dx = 0; 793 fXform.dx = 0;
584 fXform.dy = 0; 794 fXform.dy = 0;
585 795
586 if (SkMask::kBW_Format == fRec.fMaskFormat) { 796 // GsA is the non-rotational part of A without the text height scale.
587 fRenderingMode = DWRITE_RENDERING_MODE_ALIASED; 797 SkMatrix GsA(GA);
588 fTextureType = DWRITE_TEXTURE_ALIASED_1x1; 798 GsA.preScale(scale, scale); //remove text height scale, G is rotational so r eorders with scale.
589 fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC; 799
590 } else { 800 fGsA.m11 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleX));
591 fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; 801 fGsA.m12 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewY)); // This should be ~0 .
592 fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1; 802 fGsA.m21 = SkScalarToFloat(GsA.get(SkMatrix::kMSkewX));
593 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; 803 fGsA.m22 = SkScalarToFloat(GsA.get(SkMatrix::kMScaleY));
594 } 804
595 805 // fG_inv is G inverse, which is fairly simple since G is 2x2 rotational.
596 if (this->isSubpixel()) { 806 fG_inv.setAll(G.get(SkMatrix::kMScaleX), -G.get(SkMatrix::kMSkewX), G.get(Sk Matrix::kMTransX),
597 fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL; 807 -G.get(SkMatrix::kMSkewY), G.get(SkMatrix::kMScaleY), G.get(Sk Matrix::kMTransY),
598 } 808 G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(Sk Matrix::kMPersp2));
599 } 809 }
600 810
601 SkScalerContext_DW::~SkScalerContext_DW() { 811 SkScalerContext_DW::~SkScalerContext_DW() {
602 } 812 }
603 813
604 unsigned SkScalerContext_DW::generateGlyphCount() { 814 unsigned SkScalerContext_DW::generateGlyphCount() {
605 if (fGlyphCount < 0) { 815 if (fGlyphCount < 0) {
606 fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount(); 816 fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount();
607 } 817 }
608 return fGlyphCount; 818 return fGlyphCount;
(...skipping 15 matching lines...) Expand all
624 glyph->fAdvanceX = 0; 834 glyph->fAdvanceX = 0;
625 glyph->fAdvanceY = 0; 835 glyph->fAdvanceY = 0;
626 836
627 uint16_t glyphId = glyph->getGlyphID(); 837 uint16_t glyphId = glyph->getGlyphID();
628 DWRITE_GLYPH_METRICS gm; 838 DWRITE_GLYPH_METRICS gm;
629 839
630 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || 840 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
631 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) 841 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
632 { 842 {
633 HRVM(fTypeface->fDWriteFontFace->GetGdiCompatibleGlyphMetrics( 843 HRVM(fTypeface->fDWriteFontFace->GetGdiCompatibleGlyphMetrics(
634 fRec.fTextSize, 844 fTextSizeMeasure,
635 1.0f, // pixelsPerDip 845 1.0f, // pixelsPerDip
636 &fXform, 846 &fGsA,
637 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode, 847 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode,
638 &glyphId, 1, 848 &glyphId, 1,
639 &gm), 849 &gm),
640 "Could not get gdi compatible glyph metrics."); 850 "Could not get gdi compatible glyph metrics.");
641 } else { 851 } else {
642 HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm) , 852 HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm) ,
643 "Could not get design metrics."); 853 "Could not get design metrics.");
644 } 854 }
645 855
646 DWRITE_FONT_METRICS dwfm; 856 DWRITE_FONT_METRICS dwfm;
647 fTypeface->fDWriteFontFace->GetMetrics(&dwfm); 857 fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
648 SkScalar advanceX = SkScalarMulDiv(fRec.fTextSize, 858 SkScalar advanceX = SkScalarMulDiv(fTextSizeMeasure,
649 SkIntToScalar(gm.advanceWidth), 859 SkIntToScalar(gm.advanceWidth),
650 SkIntToScalar(dwfm.designUnitsPerEm)); 860 SkIntToScalar(dwfm.designUnitsPerEm));
651 861
652 if (!this->isSubpixel()) { 862 if (!this->isSubpixel()) {
653 advanceX = SkScalarRoundToScalar(advanceX); 863 advanceX = SkScalarRoundToScalar(advanceX);
654 } 864 }
655 865
656 SkVector vecs[1] = { { advanceX, 0 } }; 866 SkVector vecs[1] = { { advanceX, 0 } };
657 SkMatrix mat; 867 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
658 fRec.getMatrixFrom2x2(&mat); 868 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
659 mat.mapVectors(vecs, SK_ARRAY_COUNT(vecs)); 869 {
870 fG_inv.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
871 } else {
872 fSkXform.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
873 }
660 874
661 glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX); 875 glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX);
662 glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY); 876 glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY);
663 } 877 }
664 878
665 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) { 879 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
666 glyph->fWidth = 0; 880 glyph->fWidth = 0;
667 881
668 this->generateAdvance(glyph); 882 this->generateAdvance(glyph);
669 883
670 //Measure raster size. 884 //Measure raster size.
671 fXform.dx = SkFixedToFloat(glyph->getSubXFixed()); 885 fXform.dx = SkFixedToFloat(glyph->getSubXFixed());
672 fXform.dy = SkFixedToFloat(glyph->getSubYFixed()); 886 fXform.dy = SkFixedToFloat(glyph->getSubYFixed());
673 887
674 FLOAT advance = 0; 888 FLOAT advance = 0;
675 889
676 UINT16 glyphId = glyph->getGlyphID(); 890 UINT16 glyphId = glyph->getGlyphID();
677 891
678 DWRITE_GLYPH_OFFSET offset; 892 DWRITE_GLYPH_OFFSET offset;
679 offset.advanceOffset = 0.0f; 893 offset.advanceOffset = 0.0f;
680 offset.ascenderOffset = 0.0f; 894 offset.ascenderOffset = 0.0f;
681 895
682 DWRITE_GLYPH_RUN run; 896 DWRITE_GLYPH_RUN run;
683 run.glyphCount = 1; 897 run.glyphCount = 1;
684 run.glyphAdvances = &advance; 898 run.glyphAdvances = &advance;
685 run.fontFace = fTypeface->fDWriteFontFace.get(); 899 run.fontFace = fTypeface->fDWriteFontFace.get();
686 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); 900 run.fontEmSize = SkScalarToFloat(fTextSizeRender);
687 run.bidiLevel = 0; 901 run.bidiLevel = 0;
688 run.glyphIndices = &glyphId; 902 run.glyphIndices = &glyphId;
689 run.isSideways = FALSE; 903 run.isSideways = FALSE;
690 run.glyphOffsets = &offset; 904 run.glyphOffsets = &offset;
691 905
692 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; 906 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
693 HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis( 907 HRVM(fTypeface->fFactory->CreateGlyphRunAnalysis(
694 &run, 908 &run,
695 1.0f, // pixelsPerDip, 909 1.0f, // pixelsPerDip,
696 &fXform, 910 &fXform,
(...skipping 24 matching lines...) Expand all
721 } 935 }
722 if (my) { 936 if (my) {
723 sk_bzero(my, sizeof(*my)); 937 sk_bzero(my, sizeof(*my));
724 } 938 }
725 939
726 DWRITE_FONT_METRICS dwfm; 940 DWRITE_FONT_METRICS dwfm;
727 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode || 941 if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
728 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode) 942 DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
729 { 943 {
730 fTypeface->fDWriteFontFace->GetGdiCompatibleMetrics( 944 fTypeface->fDWriteFontFace->GetGdiCompatibleMetrics(
731 fRec.fTextSize, 945 fTextSizeRender,
732 1.0f, // pixelsPerDip 946 1.0f, // pixelsPerDip
733 &fXform, 947 &fXform,
734 &dwfm); 948 &dwfm);
735 } else { 949 } else {
736 fTypeface->fDWriteFontFace->GetMetrics(&dwfm); 950 fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
737 } 951 }
738 952
739 SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm); 953 SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm);
740 if (mx) { 954 if (mx) {
741 mx->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem; 955 mx->fTop = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
742 mx->fAscent = mx->fTop; 956 mx->fAscent = mx->fTop;
743 mx->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem; 957 mx->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
744 mx->fBottom = mx->fDescent; 958 mx->fBottom = mx->fDescent;
745 mx->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem; 959 mx->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
746 mx->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem; 960 mx->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
747 mx->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlineP osition) / upem; 961 mx->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underline Position) / upem;
748 mx->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underline Thickness) / upem); 962 mx->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlin eThickness) / upem);
749 963
750 mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; 964 mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
751 mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; 965 mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
752 } 966 }
753 967
754 if (my) { 968 if (my) {
755 my->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem; 969 my->fTop = -fTextSizeRender * SkIntToScalar(dwfm.ascent) / upem;
756 my->fAscent = my->fTop; 970 my->fAscent = my->fTop;
757 my->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem; 971 my->fDescent = fTextSizeRender * SkIntToScalar(dwfm.descent) / upem;
758 my->fBottom = my->fDescent; 972 my->fBottom = my->fDescent;
759 my->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem; 973 my->fLeading = fTextSizeRender * SkIntToScalar(dwfm.lineGap) / upem;
760 my->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem; 974 my->fXHeight = fTextSizeRender * SkIntToScalar(dwfm.xHeight) / upem;
761 my->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlineP osition) / upem; 975 my->fUnderlineThickness = fTextSizeRender * SkIntToScalar(dwfm.underline Position) / upem;
762 my->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underline Thickness) / upem); 976 my->fUnderlinePosition = -(fTextSizeRender * SkIntToScalar(dwfm.underlin eThickness) / upem);
763 977
764 my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; 978 my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
765 my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; 979 my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
766 } 980 }
767 } 981 }
768 982
769 /////////////////////////////////////////////////////////////////////////////// 983 ///////////////////////////////////////////////////////////////////////////////
770 984
771 #include "SkColorPriv.h" 985 #include "SkColorPriv.h"
772 986
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 UINT16 index = glyph.getGlyphID(); 1095 UINT16 index = glyph.getGlyphID();
882 1096
883 DWRITE_GLYPH_OFFSET offset; 1097 DWRITE_GLYPH_OFFSET offset;
884 offset.advanceOffset = 0.0f; 1098 offset.advanceOffset = 0.0f;
885 offset.ascenderOffset = 0.0f; 1099 offset.ascenderOffset = 0.0f;
886 1100
887 DWRITE_GLYPH_RUN run; 1101 DWRITE_GLYPH_RUN run;
888 run.glyphCount = 1; 1102 run.glyphCount = 1;
889 run.glyphAdvances = &advance; 1103 run.glyphAdvances = &advance;
890 run.fontFace = fTypeface->fDWriteFontFace.get(); 1104 run.fontFace = fTypeface->fDWriteFontFace.get();
891 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); 1105 run.fontEmSize = SkScalarToFloat(fTextSizeRender);
892 run.bidiLevel = 0; 1106 run.bidiLevel = 0;
893 run.glyphIndices = &index; 1107 run.glyphIndices = &index;
894 run.isSideways = FALSE; 1108 run.isSideways = FALSE;
895 run.glyphOffsets = &offset; 1109 run.glyphOffsets = &offset;
896 1110
897 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis; 1111 SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
898 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run, 1112 HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
899 1.0f, // pixelsPerDip, 1113 1.0f, // pixelsPerDip,
900 &fXform, 1114 &fXform,
901 fRenderingMode, 1115 fRenderingMode,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 SkASSERT(&glyph && path); 1173 SkASSERT(&glyph && path);
960 1174
961 path->reset(); 1175 path->reset();
962 1176
963 SkTScopedComPtr<IDWriteGeometrySink> geometryToPath; 1177 SkTScopedComPtr<IDWriteGeometrySink> geometryToPath;
964 HRVM(SkDWriteGeometrySink::Create(path, &geometryToPath), 1178 HRVM(SkDWriteGeometrySink::Create(path, &geometryToPath),
965 "Could not create geometry to path converter."); 1179 "Could not create geometry to path converter.");
966 uint16_t glyphId = glyph.getGlyphID(); 1180 uint16_t glyphId = glyph.getGlyphID();
967 //TODO: convert to<->from DIUs? This would make a difference if hinting. 1181 //TODO: convert to<->from DIUs? This would make a difference if hinting.
968 //It may not be needed, it appears that DirectWrite only hints at em size. 1182 //It may not be needed, it appears that DirectWrite only hints at em size.
969 HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fRec.fTe xtSize), 1183 HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fTextSiz eRender),
970 &glyphId, 1184 &glyphId,
971 NULL, //advances 1185 NULL, //advances
972 NULL, //offsets 1186 NULL, //offsets
973 1, //num glyphs 1187 1, //num glyphs
974 FALSE, //sideways 1188 FALSE, //sideways
975 FALSE, //rtl 1189 FALSE, //rtl
976 geometryToPath.get()), 1190 geometryToPath.get()),
977 "Could not create glyph outline."); 1191 "Could not create glyph outline.");
978 1192
979 SkMatrix mat; 1193 path->transform(fSkXform);
980 fRec.getMatrixFrom2x2(&mat);
981 path->transform(mat);
982 } 1194 }
983 1195
984 void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 1196 void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
985 bool* isLocalStream) const { 1197 bool* isLocalStream) const {
986 // Get the family name. 1198 // Get the family name.
987 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames; 1199 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames;
988 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames)); 1200 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames));
989 1201
990 UINT32 dwFamilyNamesLength; 1202 UINT32 dwFamilyNamesLength;
991 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength)); 1203 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength));
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) 1351 type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
1140 { 1352 {
1141 return 0; 1353 return 0;
1142 } 1354 }
1143 1355
1144 int ttcIndex; 1356 int ttcIndex;
1145 SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex)); 1357 SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex));
1146 return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0 ; 1358 return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0 ;
1147 } 1359 }
1148 1360
1149 class AutoDWriteTable {
1150 public:
1151 AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFac e), fExists(FALSE) {
1152 // Any errors are ignored, user must check fExists anyway.
1153 fontFace->TryGetFontTable(beTag,
1154 reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
1155 }
1156 ~AutoDWriteTable() {
1157 if (fExists) {
1158 fFontFace->ReleaseFontTable(fLock);
1159 }
1160 }
1161
1162 const uint8_t* fData;
1163 UINT32 fSize;
1164 BOOL fExists;
1165 private:
1166 // Borrowed reference, the user must ensure the fontFace stays alive.
1167 IDWriteFontFace* fFontFace;
1168 void* fLock;
1169 };
1170
1171 size_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset, 1361 size_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
1172 size_t length, void* data) const 1362 size_t length, void* data) const
1173 { 1363 {
1174 AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag)); 1364 AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag));
1175 if (!table.fExists) { 1365 if (!table.fExists) {
1176 return 0; 1366 return 0;
1177 } 1367 }
1178 1368
1179 if (offset > table.fSize) { 1369 if (offset > table.fSize) {
1180 return 0; 1370 return 0;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 1443
1254 void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const { 1444 void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
1255 if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag || 1445 if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
1256 rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) 1446 rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
1257 { 1447 {
1258 rec->fMaskFormat = SkMask::kA8_Format; 1448 rec->fMaskFormat = SkMask::kA8_Format;
1259 } 1449 }
1260 1450
1261 unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag | 1451 unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
1262 SkScalerContext::kForceAutohinting_Flag | 1452 SkScalerContext::kForceAutohinting_Flag |
1263 SkScalerContext::kEmbeddedBitmapText_Flag |
1264 SkScalerContext::kEmbolden_Flag | 1453 SkScalerContext::kEmbolden_Flag |
1265 SkScalerContext::kLCD_BGROrder_Flag | 1454 SkScalerContext::kLCD_BGROrder_Flag |
1266 SkScalerContext::kLCD_Vertical_Flag; 1455 SkScalerContext::kLCD_Vertical_Flag;
1267 rec->fFlags &= ~flagsWeDontSupport; 1456 rec->fFlags &= ~flagsWeDontSupport;
1268 1457
1269 SkPaint::Hinting h = rec->getHinting(); 1458 SkPaint::Hinting h = rec->getHinting();
1270 // DirectWrite does not provide for hinting hints. 1459 // DirectWrite does not provide for hinting hints.
1271 h = SkPaint::kSlight_Hinting; 1460 h = SkPaint::kSlight_Hinting;
1272 rec->setHinting(h); 1461 rec->setHinting(h);
1273 1462
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 1544
1356 if (FAILED(hr)) { 1545 if (FAILED(hr)) {
1357 *advance = 0; 1546 *advance = 0;
1358 return false; 1547 return false;
1359 } 1548 }
1360 1549
1361 *advance = gm.advanceWidth; 1550 *advance = gm.advanceWidth;
1362 return true; 1551 return true;
1363 } 1552 }
1364 1553
1365 template<typename T> class AutoTDWriteTable : public AutoDWriteTable {
1366 public:
1367 static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2 , T::TAG3);
1368 AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { }
1369
1370 const T* operator->() const { return reinterpret_cast<const T*>(fData); }
1371 };
1372
1373 SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics( 1554 SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
1374 SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo, 1555 SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
1375 const uint32_t* glyphIDs, 1556 const uint32_t* glyphIDs,
1376 uint32_t glyphIDsCount) const { 1557 uint32_t glyphIDsCount) const {
1377 1558
1378 SkAdvancedTypefaceMetrics* info = NULL; 1559 SkAdvancedTypefaceMetrics* info = NULL;
1379 1560
1380 HRESULT hr = S_OK; 1561 HRESULT hr = S_OK;
1381 1562
1382 const unsigned glyphCount = fDWriteFontFace->GetGlyphCount(); 1563 const unsigned glyphCount = fDWriteFontFace->GetGlyphCount();
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 } 2002 }
1822 2003
1823 #include "SkFontMgr_indirect.h" 2004 #include "SkFontMgr_indirect.h"
1824 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { 2005 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) {
1825 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); 2006 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite());
1826 if (impl.get() == NULL) { 2007 if (impl.get() == NULL) {
1827 return NULL; 2008 return NULL;
1828 } 2009 }
1829 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy)); 2010 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy));
1830 } 2011 }
OLDNEW
« no previous file with comments | « no previous file | src/sfnt/SkOTTable_EBDT.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698