OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |