OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkAdvancedTypefaceMetrics.h" | 9 #include "SkAdvancedTypefaceMetrics.h" |
10 #include "SkBase64.h" | 10 #include "SkBase64.h" |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 | 543 |
544 private: | 544 private: |
545 DWORD getGDIGlyphPath(const SkGlyph& glyph, UINT flags, | 545 DWORD getGDIGlyphPath(const SkGlyph& glyph, UINT flags, |
546 SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf); | 546 SkAutoSTMalloc<BUFFERSIZE, uint8_t>* glyphbuf); |
547 | 547 |
548 HDCOffscreen fOffscreen; | 548 HDCOffscreen fOffscreen; |
549 /** fGsA is the non-rotational part of total matrix without the text height
scale. | 549 /** fGsA is the non-rotational part of total matrix without the text height
scale. |
550 * Used to find the magnitude of advances. | 550 * Used to find the magnitude of advances. |
551 */ | 551 */ |
552 MAT2 fGsA; | 552 MAT2 fGsA; |
| 553 /** The total matrix without the textSize. */ |
553 MAT2 fMat22; | 554 MAT2 fMat22; |
| 555 /** Scales font to EM size. */ |
| 556 MAT2 fHighResMat22; |
554 HDC fDDC; | 557 HDC fDDC; |
555 HFONT fSavefont; | 558 HFONT fSavefont; |
556 HFONT fFont; | 559 HFONT fFont; |
557 HFONT fHiResFont; | |
558 SCRIPT_CACHE fSC; | 560 SCRIPT_CACHE fSC; |
559 int fGlyphCount; | 561 int fGlyphCount; |
560 | 562 |
| 563 /** The total matrix which also removes EM scale. */ |
561 SkMatrix fHiResMatrix; | 564 SkMatrix fHiResMatrix; |
562 /** fG_inv is the inverse of the rotational part of the total matrix. | 565 /** fG_inv is the inverse of the rotational part of the total matrix. |
563 * Used to set the direction of advances. | 566 * Used to set the direction of advances. |
564 */ | 567 */ |
565 SkMatrix fG_inv; | 568 SkMatrix fG_inv; |
566 enum Type { | 569 enum Type { |
567 kTrueType_Type, kBitmap_Type, | 570 kTrueType_Type, kBitmap_Type, |
568 } fType; | 571 } fType; |
569 TEXTMETRIC fTM; | 572 TEXTMETRIC fTM; |
570 }; | 573 }; |
(...skipping 17 matching lines...) Expand all Loading... |
588 } | 591 } |
589 } | 592 } |
590 } | 593 } |
591 | 594 |
592 SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface, | 595 SkScalerContext_Windows::SkScalerContext_Windows(SkTypeface* rawTypeface, |
593 const SkDescriptor* desc) | 596 const SkDescriptor* desc) |
594 : SkScalerContext(rawTypeface, desc) | 597 : SkScalerContext(rawTypeface, desc) |
595 , fDDC(0) | 598 , fDDC(0) |
596 , fSavefont(0) | 599 , fSavefont(0) |
597 , fFont(0) | 600 , fFont(0) |
598 , fHiResFont(0) | |
599 , fSC(0) | 601 , fSC(0) |
600 , fGlyphCount(-1) | 602 , fGlyphCount(-1) |
601 { | 603 { |
602 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); | 604 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); |
603 | 605 |
604 fDDC = ::CreateCompatibleDC(NULL); | 606 fDDC = ::CreateCompatibleDC(NULL); |
605 if (!fDDC) { | 607 if (!fDDC) { |
606 return; | 608 return; |
607 } | 609 } |
608 SetGraphicsMode(fDDC, GM_ADVANCED); | 610 SetGraphicsMode(fDDC, GM_ADVANCED); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 | 730 |
729 // Create a hires font if we need linear metrics. | 731 // Create a hires font if we need linear metrics. |
730 if (this->isSubpixel()) { | 732 if (this->isSubpixel()) { |
731 OUTLINETEXTMETRIC otm; | 733 OUTLINETEXTMETRIC otm; |
732 UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm); | 734 UINT success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm); |
733 if (0 == success) { | 735 if (0 == success) { |
734 call_ensure_accessible(lf); | 736 call_ensure_accessible(lf); |
735 success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm); | 737 success = GetOutlineTextMetrics(fDDC, sizeof(otm), &otm); |
736 } | 738 } |
737 if (0 != success) { | 739 if (0 != success) { |
738 lf.lfHeight = -SkToS32(otm.otmEMSquare); | 740 SkScalar scale = SkIntToScalar(otm.otmEMSquare); |
739 fHiResFont = CreateFontIndirect(&lf); | |
740 if (!fHiResFont) { | |
741 return; | |
742 } | |
743 | 741 |
744 // construct a matrix to go from HIRES logical units to our devi
ce units | 742 SkScalar textScale = scale / textSize; |
745 fRec.getSingleMatrix(&fHiResMatrix); | 743 fHighResMat22.eM11 = float2FIXED(textScale); |
746 SkScalar scale = SkScalarInvert(SkIntToScalar(otm.otmEMSquare)); | 744 fHighResMat22.eM12 = float2FIXED(0); |
747 fHiResMatrix.preScale(scale, scale); | 745 fHighResMat22.eM21 = float2FIXED(0); |
| 746 fHighResMat22.eM22 = float2FIXED(textScale); |
| 747 |
| 748 SkScalar invScale = SkScalarInvert(scale); |
| 749 fHiResMatrix = A; |
| 750 fHiResMatrix.preScale(invScale, invScale); |
748 } | 751 } |
749 } | 752 } |
750 | 753 |
751 } else { | 754 } else { |
752 // Assume bitmap | 755 // Assume bitmap |
753 fType = SkScalerContext_Windows::kBitmap_Type; | 756 fType = SkScalerContext_Windows::kBitmap_Type; |
754 | 757 |
755 xform.eM11 = 1.0f; | 758 xform.eM11 = 1.0f; |
756 xform.eM12 = 0.0f; | 759 xform.eM12 = 0.0f; |
757 xform.eM21 = 0.0f; | 760 xform.eM21 = 0.0f; |
(...skipping 13 matching lines...) Expand all Loading... |
771 } | 774 } |
772 | 775 |
773 SkScalerContext_Windows::~SkScalerContext_Windows() { | 776 SkScalerContext_Windows::~SkScalerContext_Windows() { |
774 if (fDDC) { | 777 if (fDDC) { |
775 ::SelectObject(fDDC, fSavefont); | 778 ::SelectObject(fDDC, fSavefont); |
776 ::DeleteDC(fDDC); | 779 ::DeleteDC(fDDC); |
777 } | 780 } |
778 if (fFont) { | 781 if (fFont) { |
779 ::DeleteObject(fFont); | 782 ::DeleteObject(fFont); |
780 } | 783 } |
781 if (fHiResFont) { | |
782 ::DeleteObject(fHiResFont); | |
783 } | |
784 if (fSC) { | 784 if (fSC) { |
785 ::ScriptFreeCache(&fSC); | 785 ::ScriptFreeCache(&fSC); |
786 } | 786 } |
787 } | 787 } |
788 | 788 |
789 bool SkScalerContext_Windows::isValid() const { | 789 bool SkScalerContext_Windows::isValid() const { |
790 return fDDC && fFont; | 790 return fDDC && fFont; |
791 } | 791 } |
792 | 792 |
793 unsigned SkScalerContext_Windows::generateGlyphCount() { | 793 unsigned SkScalerContext_Windows::generateGlyphCount() { |
(...skipping 26 matching lines...) Expand all Loading... |
820 SkAssertResult(SUCCEEDED(ScriptShape( | 820 SkAssertResult(SUCCEEDED(ScriptShape( |
821 fDDC, &fSC, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs))); | 821 fDDC, &fSC, c, 2, 1, &si[0].a, &index, log, &vsa, &glyphs))); |
822 } | 822 } |
823 return index; | 823 return index; |
824 } | 824 } |
825 | 825 |
826 void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) { | 826 void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) { |
827 this->generateMetrics(glyph); | 827 this->generateMetrics(glyph); |
828 } | 828 } |
829 | 829 |
830 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; | |
831 void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) { | 830 void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) { |
832 SkASSERT(fDDC); | 831 SkASSERT(fDDC); |
833 | 832 |
834 if (fType == SkScalerContext_Windows::kBitmap_Type) { | 833 if (fType == SkScalerContext_Windows::kBitmap_Type) { |
835 SIZE size; | 834 SIZE size; |
836 WORD glyphs = glyph->getGlyphID(0); | 835 WORD glyphs = glyph->getGlyphID(0); |
837 if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) { | 836 if (0 == GetTextExtentPointI(fDDC, &glyphs, 1, &size)) { |
838 glyph->fWidth = SkToS16(fTM.tmMaxCharWidth); | 837 glyph->fWidth = SkToS16(fTM.tmMaxCharWidth); |
839 } else { | 838 } else { |
840 glyph->fWidth = SkToS16(size.cx); | 839 glyph->fWidth = SkToS16(size.cx); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 glyph->fWidth = gm.gmBlackBoxX + 4; | 890 glyph->fWidth = gm.gmBlackBoxX + 4; |
892 glyph->fHeight = gm.gmBlackBoxY + 4; | 891 glyph->fHeight = gm.gmBlackBoxY + 4; |
893 glyph->fTop -= 2; | 892 glyph->fTop -= 2; |
894 glyph->fLeft -= 2; | 893 glyph->fLeft -= 2; |
895 } | 894 } |
896 glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX); | 895 glyph->fAdvanceX = SkIntToFixed(gm.gmCellIncX); |
897 glyph->fAdvanceY = SkIntToFixed(gm.gmCellIncY); | 896 glyph->fAdvanceY = SkIntToFixed(gm.gmCellIncY); |
898 glyph->fRsbDelta = 0; | 897 glyph->fRsbDelta = 0; |
899 glyph->fLsbDelta = 0; | 898 glyph->fLsbDelta = 0; |
900 | 899 |
901 if (fHiResFont) { | 900 if (this->isSubpixel()) { |
902 SelectObject(fDDC, fHiResFont); | |
903 sk_bzero(&gm, sizeof(gm)); | 901 sk_bzero(&gm, sizeof(gm)); |
904 status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX,
&gm, 0, NULL, &gMat2Identity); | 902 status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX,
&gm, 0, NULL, &fHighResMat22); |
905 if (GDI_ERROR != status) { | 903 if (GDI_ERROR != status) { |
906 SkPoint advance; | 904 SkPoint advance; |
907 fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gm
CellIncY), &advance); | 905 fHiResMatrix.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gm
CellIncY), &advance); |
908 glyph->fAdvanceX = SkScalarToFixed(advance.fX); | 906 glyph->fAdvanceX = SkScalarToFixed(advance.fX); |
909 glyph->fAdvanceY = SkScalarToFixed(advance.fY); | 907 glyph->fAdvanceY = SkScalarToFixed(advance.fY); |
910 } | 908 } |
911 SelectObject(fDDC, fFont); | |
912 } else if (!isAxisAligned(this->fRec)) { | 909 } else if (!isAxisAligned(this->fRec)) { |
913 status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX,
&gm, 0, NULL, &fGsA); | 910 status = GetGlyphOutlineW(fDDC, glyphId, GGO_METRICS | GGO_GLYPH_INDEX,
&gm, 0, NULL, &fGsA); |
914 if (GDI_ERROR != status) { | 911 if (GDI_ERROR != status) { |
915 SkPoint advance; | 912 SkPoint advance; |
916 fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIn
cY), &advance); | 913 fG_inv.mapXY(SkIntToScalar(gm.gmCellIncX), SkIntToScalar(gm.gmCellIn
cY), &advance); |
917 glyph->fAdvanceX = SkScalarToFixed(advance.fX); | 914 glyph->fAdvanceX = SkScalarToFixed(advance.fX); |
918 glyph->fAdvanceY = SkScalarToFixed(advance.fY); | 915 glyph->fAdvanceY = SkScalarToFixed(advance.fY); |
919 } | 916 } |
920 } | 917 } |
921 } | 918 } |
922 | 919 |
| 920 static const MAT2 gMat2Identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}}; |
923 void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa
int::FontMetrics* my) { | 921 void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa
int::FontMetrics* my) { |
924 if (!(mx || my)) { | 922 if (!(mx || my)) { |
925 return; | 923 return; |
926 } | 924 } |
927 | 925 |
928 if (mx) { | 926 if (mx) { |
929 sk_bzero(mx, sizeof(*mx)); | 927 sk_bzero(mx, sizeof(*mx)); |
930 } | 928 } |
931 if (my) { | 929 if (my) { |
932 sk_bzero(my, sizeof(*my)); | 930 sk_bzero(my, sizeof(*my)); |
(...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2316 return this->createFromStream(stream); | 2314 return this->createFromStream(stream); |
2317 } | 2315 } |
2318 | 2316 |
2319 private: | 2317 private: |
2320 SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 2318 SkTDArray<ENUMLOGFONTEX> fLogFontArray; |
2321 }; | 2319 }; |
2322 | 2320 |
2323 SkFontMgr* SkFontMgr::Factory() { | 2321 SkFontMgr* SkFontMgr::Factory() { |
2324 return SkNEW(SkFontMgrGDI); | 2322 return SkNEW(SkFontMgrGDI); |
2325 } | 2323 } |
OLD | NEW |