OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |