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

Side by Side Diff: src/core/SkMatrix.cpp

Issue 306013010: allow subpixel positioning w/ bitmap filtering Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 6 years, 6 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
« no previous file with comments | « src/core/SkDraw.cpp ('k') | src/core/SkMatrixUtils.h » ('j') | 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 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
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 "SkMatrix.h" 8 #include "SkMatrix.h"
9 #include "SkFloatBits.h" 9 #include "SkFloatBits.h"
10 #include "SkString.h" 10 #include "SkString.h"
(...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 str->appendf("[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]", 1631 str->appendf("[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]",
1632 fMat[0], fMat[1], fMat[2], fMat[3], fMat[4], fMat[5], 1632 fMat[0], fMat[1], fMat[2], fMat[3], fMat[4], fMat[5],
1633 fMat[6], fMat[7], fMat[8]); 1633 fMat[6], fMat[7], fMat[8]);
1634 } 1634 }
1635 #endif 1635 #endif
1636 1636
1637 /////////////////////////////////////////////////////////////////////////////// 1637 ///////////////////////////////////////////////////////////////////////////////
1638 1638
1639 #include "SkMatrixUtils.h" 1639 #include "SkMatrixUtils.h"
1640 1640
1641 bool SkRectIsOnGrid(int width, int height, const SkRect& r, unsigned subpixelBit s) {
1642 const int lowBitsMask = (1 << subpixelBits) - 1;
1643 const SkScalar scale = 1 << subpixelBits;
1644
1645 const int dL = SkScalarRoundToInt(r.fLeft * scale);
1646 const int dT = SkScalarRoundToInt(r.fTop * scale);
1647 const int dR = SkScalarRoundToInt(r.fRight * scale);
1648 const int dB = SkScalarRoundToInt(r.fBottom * scale);
1649
1650 if (subpixelBits) {
1651 // we only check the low-bits for gridding if we have subpixelBits
1652 const int merge = dL | dT | dR | dB;
1653 if (merge & lowBitsMask) {
1654 return false;
1655 }
1656 }
1657
1658 // Now we know we're integral, just need to check our width/height
1659 const int dW = (dR - dL);
1660 const int dH = (dB - dT);
1661 if (dW != (width << subpixelBits) || dH != (height << subpixelBits)) {
1662 return false;
1663 }
1664 return true;
1665 }
1666
1641 bool SkTreatAsSprite(const SkMatrix& mat, int width, int height, 1667 bool SkTreatAsSprite(const SkMatrix& mat, int width, int height,
1642 unsigned subpixelBits) { 1668 unsigned subpixelBits) {
1643 // quick reject on affine or perspective 1669 // quick reject on affine or perspective
1644 if (mat.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { 1670 if (mat.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) {
1645 return false; 1671 return false;
1646 } 1672 }
1647 1673
1648 // quick success check 1674 // quick success check
1649 if (!subpixelBits && !(mat.getType() & ~SkMatrix::kTranslate_Mask)) { 1675 if (!subpixelBits && !(mat.getType() & ~SkMatrix::kTranslate_Mask)) {
1650 return true; 1676 return true;
1651 } 1677 }
1652 1678
1653 // mapRect supports negative scales, so we eliminate those first 1679 // mapRect supports negative scales, so we eliminate those first
1654 if (mat.getScaleX() < 0 || mat.getScaleY() < 0) { 1680 if (mat.getScaleX() < 0 || mat.getScaleY() < 0) {
1655 return false; 1681 return false;
1656 } 1682 }
1657 1683
1658 SkRect dst; 1684 SkRect dst;
1659 SkIRect isrc = { 0, 0, width, height }; 1685 SkIRect isrc = { 0, 0, width, height };
1660 1686
1661 { 1687 {
1662 SkRect src; 1688 SkRect src;
1663 src.set(isrc); 1689 src.set(isrc);
1664 mat.mapRect(&dst, src); 1690 mat.mapRect(&dst, src);
1665 } 1691 }
1666 1692
1693 #if 0
1667 // just apply the translate to isrc 1694 // just apply the translate to isrc
1668 isrc.offset(SkScalarRoundToInt(mat.getTranslateX()), 1695 isrc.offset(SkScalarRoundToInt(mat.getTranslateX()),
1669 SkScalarRoundToInt(mat.getTranslateY())); 1696 SkScalarRoundToInt(mat.getTranslateY()));
1670 1697
1671 if (subpixelBits) { 1698 if (subpixelBits) {
1672 isrc.fLeft <<= subpixelBits; 1699 isrc.fLeft <<= subpixelBits;
1673 isrc.fTop <<= subpixelBits; 1700 isrc.fTop <<= subpixelBits;
1674 isrc.fRight <<= subpixelBits; 1701 isrc.fRight <<= subpixelBits;
1675 isrc.fBottom <<= subpixelBits; 1702 isrc.fBottom <<= subpixelBits;
1676 1703
1677 const float scale = 1 << subpixelBits; 1704 const float scale = 1 << subpixelBits;
1678 dst.fLeft *= scale; 1705 dst.fLeft *= scale;
1679 dst.fTop *= scale; 1706 dst.fTop *= scale;
1680 dst.fRight *= scale; 1707 dst.fRight *= scale;
1681 dst.fBottom *= scale; 1708 dst.fBottom *= scale;
1682 } 1709 }
1683 1710
1684 SkIRect idst; 1711 SkIRect idst;
1685 dst.round(&idst); 1712 dst.round(&idst);
1686 return isrc == idst; 1713 return isrc == idst;
1714 #else
1715 return SkRectIsOnGrid(width, height, dst, subpixelBits);
1716 #endif
1687 } 1717 }
1688 1718
1689 // A square matrix M can be decomposed (via polar decomposition) into two matric es -- 1719 // A square matrix M can be decomposed (via polar decomposition) into two matric es --
1690 // an orthogonal matrix Q and a symmetric matrix S. In turn we can decompose S i nto U*W*U^T, 1720 // an orthogonal matrix Q and a symmetric matrix S. In turn we can decompose S i nto U*W*U^T,
1691 // where U is another orthogonal matrix and W is a scale matrix. These can be re combined 1721 // where U is another orthogonal matrix and W is a scale matrix. These can be re combined
1692 // to give M = (Q*U)*W*U^T, i.e., the product of two orthogonal matrices and a s cale matrix. 1722 // to give M = (Q*U)*W*U^T, i.e., the product of two orthogonal matrices and a s cale matrix.
1693 // 1723 //
1694 // The one wrinkle is that traditionally Q may contain a reflection -- the 1724 // The one wrinkle is that traditionally Q may contain a reflection -- the
1695 // calculation has been rejiggered to put that reflection into W. 1725 // calculation has been rejiggered to put that reflection into W.
1696 bool SkDecomposeUpper2x2(const SkMatrix& matrix, 1726 bool SkDecomposeUpper2x2(const SkMatrix& matrix,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 rotation1->fX = cos1; 1810 rotation1->fX = cos1;
1781 rotation1->fY = sin1; 1811 rotation1->fY = sin1;
1782 } 1812 }
1783 if (NULL != rotation2) { 1813 if (NULL != rotation2) {
1784 rotation2->fX = cos2; 1814 rotation2->fX = cos2;
1785 rotation2->fY = sin2; 1815 rotation2->fY = sin2;
1786 } 1816 }
1787 1817
1788 return true; 1818 return true;
1789 } 1819 }
OLDNEW
« no previous file with comments | « src/core/SkDraw.cpp ('k') | src/core/SkMatrixUtils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698