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

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

Issue 21047008: Fix subpixel metrics with GDI. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Move global now that there is one fewer user. Created 7 years, 4 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 | no next file » | 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 /* 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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698