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 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
610 { | 610 { |
611 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); | 611 LogFontTypeface* typeface = reinterpret_cast<LogFontTypeface*>(rawTypeface); |
612 | 612 |
613 fDDC = ::CreateCompatibleDC(NULL); | 613 fDDC = ::CreateCompatibleDC(NULL); |
614 if (!fDDC) { | 614 if (!fDDC) { |
615 return; | 615 return; |
616 } | 616 } |
617 SetGraphicsMode(fDDC, GM_ADVANCED); | 617 SetGraphicsMode(fDDC, GM_ADVANCED); |
618 SetBkMode(fDDC, TRANSPARENT); | 618 SetBkMode(fDDC, TRANSPARENT); |
619 | 619 |
620 SkPoint h = SkPoint::Make(SK_Scalar1, 0); | 620 // When GDI hinting, remove the entire Y scale to prevent 'subpixel' metrics . |
621 // A is the total matrix. | 621 // When not hinting, remove only the gdiTextSize scale which will be applied by GDI. |
622 SkScalerContextRec::PreMatrixScale scaleConstraints = | |
623 (fRec.getHinting() == SkPaint::kNo_Hinting || fRec.getHinting() == SkPai nt::kSlight_Hinting) | |
624 ? SkScalerContextRec::kVerticalInteger_PreMatrixScale | |
625 : SkScalerContextRec::kVertical_PreMatrixScale; | |
626 SkVector scale; | |
627 SkMatrix sA; | |
628 SkMatrix GsA; | |
622 SkMatrix A; | 629 SkMatrix A; |
623 fRec.getSingleMatrix(&A); | 630 fRec.computeMatrices(scaleConstraints, &scale, &sA, &GsA, &fG_inv, &A); |
624 A.mapPoints(&h, 1); | |
625 | |
626 // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0). | |
627 SkMatrix G; | |
628 SkComputeGivensRotation(h, &G); | |
629 | |
630 // GA is the matrix A with rotation removed. | |
631 SkMatrix GA(G); | |
632 GA.preConcat(A); | |
633 | |
634 // realTextSize is the actual device size we want (as opposed to the size th e user requested). | |
635 // gdiTextSize is the size we request from GDI. | |
636 // If the scale is negative, this means the matrix will do the flip anyway. | |
637 SkScalar realTextSize = SkScalarAbs(GA.get(SkMatrix::kMScaleY)); | |
638 SkScalar gdiTextSize = SkScalarRoundToScalar(realTextSize); | |
639 if (gdiTextSize == 0) { | |
640 gdiTextSize = SK_Scalar1; | |
641 } | |
642 | |
643 // When not hinting, remove only the gdiTextSize scale which will be applied by GDI. | |
644 // When GDI hinting, remove the entire Y scale to prevent 'subpixel' metrics . | |
645 SkScalar scale = (fRec.getHinting() == SkPaint::kNo_Hinting || | |
646 fRec.getHinting() == SkPaint::kSlight_Hinting) | |
647 ? SkScalarInvert(gdiTextSize) | |
648 : SkScalarInvert(realTextSize); | |
649 | |
650 // sA is the total matrix A without the textSize (so GDI knows the text size separately). | |
651 // When this matrix is used with GetGlyphOutline, no further processing is n eeded. | |
652 SkMatrix sA(A); | |
653 sA.preScale(scale, scale); //remove text size | |
654 | |
655 // GsA is the non-rotational part of A without the text height scale. | |
656 // This is what is used to find the magnitude of advances. | |
657 SkMatrix GsA(GA); | |
658 GsA.preScale(scale, scale); //remove text size, G is rotational so reorders with the scale. | |
659 | 631 |
660 fGsA.eM11 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleX)); | 632 fGsA.eM11 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleX)); |
661 fGsA.eM12 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewY)); // This should be ~0. | 633 fGsA.eM12 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewY)); // This should be ~0. |
662 fGsA.eM21 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewX)); | 634 fGsA.eM21 = SkScalarToFIXED(-GsA.get(SkMatrix::kMSkewX)); |
663 fGsA.eM22 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleY)); | 635 fGsA.eM22 = SkScalarToFIXED(GsA.get(SkMatrix::kMScaleY)); |
664 | 636 |
665 // fG_inv is G inverse, which is fairly simple since G is 2x2 rotational. | 637 SkScalar gdiTextSize = scale.fY; |
bungeman-skia
2015/03/17 21:15:18
Here we need to call SkScalarRoundToScalar(). The
| |
666 fG_inv.setAll(G.get(SkMatrix::kMScaleX), -G.get(SkMatrix::kMSkewX), G.get(Sk Matrix::kMTransX), | 638 if (gdiTextSize == 0) { |
667 -G.get(SkMatrix::kMSkewY), G.get(SkMatrix::kMScaleY), G.get(Sk Matrix::kMTransY), | 639 gdiTextSize = SK_Scalar1; |
668 G.get(SkMatrix::kMPersp0), G.get(SkMatrix::kMPersp1), G.get(Sk Matrix::kMPersp2)); | 640 } |
669 | 641 |
670 LOGFONT lf = typeface->fLogFont; | 642 LOGFONT lf = typeface->fLogFont; |
671 lf.lfHeight = -SkScalarTruncToInt(gdiTextSize); | 643 lf.lfHeight = -SkScalarTruncToInt(gdiTextSize); |
672 lf.lfQuality = compute_quality(fRec); | 644 lf.lfQuality = compute_quality(fRec); |
673 fFont = CreateFontIndirect(&lf); | 645 fFont = CreateFontIndirect(&lf); |
674 if (!fFont) { | 646 if (!fFont) { |
675 return; | 647 return; |
676 } | 648 } |
677 | 649 |
678 fSavefont = (HFONT)SelectObject(fDDC, fFont); | 650 fSavefont = (HFONT)SelectObject(fDDC, fFont); |
(...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2541 | 2513 |
2542 private: | 2514 private: |
2543 SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 2515 SkTDArray<ENUMLOGFONTEX> fLogFontArray; |
2544 }; | 2516 }; |
2545 | 2517 |
2546 /////////////////////////////////////////////////////////////////////////////// | 2518 /////////////////////////////////////////////////////////////////////////////// |
2547 | 2519 |
2548 SkFontMgr* SkFontMgr_New_GDI() { | 2520 SkFontMgr* SkFontMgr_New_GDI() { |
2549 return SkNEW(SkFontMgrGDI); | 2521 return SkNEW(SkFontMgrGDI); |
2550 } | 2522 } |
OLD | NEW |