| 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 |