| 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 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 | 745 |
| 746 // Since the determinant is on the order of the cube of the matrix members, | 746 // Since the determinant is on the order of the cube of the matrix members, |
| 747 // compare to the cube of the default nearly-zero constant (although an | 747 // compare to the cube of the default nearly-zero constant (although an |
| 748 // estimate of the condition number would be better if it wasn't so expensiv
e). | 748 // estimate of the condition number would be better if it wasn't so expensiv
e). |
| 749 if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero
* SK_ScalarNearlyZero)) { | 749 if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero
* SK_ScalarNearlyZero)) { |
| 750 return 0; | 750 return 0; |
| 751 } | 751 } |
| 752 return 1.0 / det; | 752 return 1.0 / det; |
| 753 } | 753 } |
| 754 | 754 |
| 755 bool SkMatrix::isFinite() const { |
| 756 for (int i = 0; i < 9; ++i) { |
| 757 if (!SkScalarIsFinite(fMat[i])) { |
| 758 return false; |
| 759 } |
| 760 } |
| 761 |
| 762 return true; |
| 763 } |
| 764 |
| 755 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) { | 765 void SkMatrix::SetAffineIdentity(SkScalar affine[6]) { |
| 756 affine[kAScaleX] = 1; | 766 affine[kAScaleX] = 1; |
| 757 affine[kASkewY] = 0; | 767 affine[kASkewY] = 0; |
| 758 affine[kASkewX] = 0; | 768 affine[kASkewX] = 0; |
| 759 affine[kAScaleY] = 1; | 769 affine[kAScaleY] = 1; |
| 760 affine[kATransX] = 0; | 770 affine[kATransX] = 0; |
| 761 affine[kATransY] = 0; | 771 affine[kATransY] = 0; |
| 762 } | 772 } |
| 763 | 773 |
| 764 bool SkMatrix::asAffine(SkScalar affine[6]) const { | 774 bool SkMatrix::asAffine(SkScalar affine[6]) const { |
| 765 if (this->hasPerspective()) { | 775 if (this->hasPerspective()) { |
| 766 return false; | 776 return false; |
| 767 } | 777 } |
| 768 if (affine) { | 778 if (affine) { |
| 769 affine[kAScaleX] = this->fMat[kMScaleX]; | 779 affine[kAScaleX] = this->fMat[kMScaleX]; |
| 770 affine[kASkewY] = this->fMat[kMSkewY]; | 780 affine[kASkewY] = this->fMat[kMSkewY]; |
| 771 affine[kASkewX] = this->fMat[kMSkewX]; | 781 affine[kASkewX] = this->fMat[kMSkewX]; |
| 772 affine[kAScaleY] = this->fMat[kMScaleY]; | 782 affine[kAScaleY] = this->fMat[kMScaleY]; |
| 773 affine[kATransX] = this->fMat[kMTransX]; | 783 affine[kATransX] = this->fMat[kMTransX]; |
| 774 affine[kATransY] = this->fMat[kMTransY]; | 784 affine[kATransY] = this->fMat[kMTransY]; |
| 775 } | 785 } |
| 776 return true; | 786 return true; |
| 777 } | 787 } |
| 778 | 788 |
| 789 void SkMatrix::ComputeInv(SkScalar dst[9], const SkScalar src[9], SkScalar invDe
t, bool isPersp) { |
| 790 SkASSERT(src != dst); |
| 791 SkASSERT(src && dst); |
| 792 |
| 793 if (isPersp) { |
| 794 dst[kMScaleX] = scross_dscale(src[kMScaleY], src[kMPersp2], src[kMTransY
], src[kMPersp1], invDet); |
| 795 dst[kMSkewX] = scross_dscale(src[kMTransX], src[kMPersp1], src[kMSkewX]
, src[kMPersp2], invDet); |
| 796 dst[kMTransX] = scross_dscale(src[kMSkewX], src[kMTransY], src[kMTransX
], src[kMScaleY], invDet); |
| 797 |
| 798 dst[kMSkewY] = scross_dscale(src[kMTransY], src[kMPersp0], src[kMSkewY]
, src[kMPersp2], invDet); |
| 799 dst[kMScaleY] = scross_dscale(src[kMScaleX], src[kMPersp2], src[kMTransX
], src[kMPersp0], invDet); |
| 800 dst[kMTransY] = scross_dscale(src[kMTransX], src[kMSkewY], src[kMScaleX
], src[kMTransY], invDet); |
| 801 |
| 802 dst[kMPersp0] = scross_dscale(src[kMSkewY], src[kMPersp1], src[kMScaleY
], src[kMPersp0], invDet); |
| 803 dst[kMPersp1] = scross_dscale(src[kMSkewX], src[kMPersp0], src[kMScaleX
], src[kMPersp1], invDet); |
| 804 dst[kMPersp2] = scross_dscale(src[kMScaleX], src[kMScaleY], src[kMSkewX]
, src[kMSkewY], invDet); |
| 805 } else { // not perspective |
| 806 dst[kMScaleX] = SkDoubleToScalar(src[kMScaleY] * invDet); |
| 807 dst[kMSkewX] = SkDoubleToScalar(-src[kMSkewX] * invDet); |
| 808 dst[kMTransX] = dcross_dscale(src[kMSkewX], src[kMTransY], src[kMScaleY]
, src[kMTransX], invDet); |
| 809 |
| 810 dst[kMSkewY] = SkDoubleToScalar(-src[kMSkewY] * invDet); |
| 811 dst[kMScaleY] = SkDoubleToScalar(src[kMScaleX] * invDet); |
| 812 dst[kMTransY] = dcross_dscale(src[kMSkewY], src[kMTransX], src[kMScaleX]
, src[kMTransY], invDet); |
| 813 |
| 814 dst[kMPersp0] = 0; |
| 815 dst[kMPersp1] = 0; |
| 816 dst[kMPersp2] = 1; |
| 817 } |
| 818 } |
| 819 |
| 779 bool SkMatrix::invertNonIdentity(SkMatrix* inv) const { | 820 bool SkMatrix::invertNonIdentity(SkMatrix* inv) const { |
| 780 SkASSERT(!this->isIdentity()); | 821 SkASSERT(!this->isIdentity()); |
| 781 | 822 |
| 782 TypeMask mask = this->getType(); | 823 TypeMask mask = this->getType(); |
| 783 | 824 |
| 784 if (0 == (mask & ~(kScale_Mask | kTranslate_Mask))) { | 825 if (0 == (mask & ~(kScale_Mask | kTranslate_Mask))) { |
| 785 bool invertible = true; | 826 bool invertible = true; |
| 786 if (inv) { | 827 if (inv) { |
| 787 if (mask & kScale_Mask) { | 828 if (mask & kScale_Mask) { |
| 788 SkScalar invX = fMat[kMScaleX]; | 829 SkScalar invX = fMat[kMScaleX]; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 812 } | 853 } |
| 813 } else { // inv is NULL, just check if we're invertible | 854 } else { // inv is NULL, just check if we're invertible |
| 814 if (!fMat[kMScaleX] || !fMat[kMScaleY]) { | 855 if (!fMat[kMScaleX] || !fMat[kMScaleY]) { |
| 815 invertible = false; | 856 invertible = false; |
| 816 } | 857 } |
| 817 } | 858 } |
| 818 return invertible; | 859 return invertible; |
| 819 } | 860 } |
| 820 | 861 |
| 821 int isPersp = mask & kPerspective_Mask; | 862 int isPersp = mask & kPerspective_Mask; |
| 822 double scale = sk_inv_determinant(fMat, isPersp); | 863 double invDet = sk_inv_determinant(fMat, isPersp); |
| 823 | 864 |
| 824 if (scale == 0) { // underflow | 865 if (invDet == 0) { // underflow |
| 825 return false; | 866 return false; |
| 826 } | 867 } |
| 827 | 868 |
| 828 if (inv) { | 869 bool applyingInPlace = (inv == this); |
| 829 SkMatrix tmp; | |
| 830 if (inv == this) { | |
| 831 inv = &tmp; | |
| 832 } | |
| 833 | 870 |
| 834 if (isPersp) { | 871 SkMatrix* tmp = inv; |
| 835 inv->fMat[kMScaleX] = scross_dscale(fMat[kMScaleY], fMat[kMPersp2],
fMat[kMTransY], fMat[kMPersp1], scale); | |
| 836 inv->fMat[kMSkewX] = scross_dscale(fMat[kMTransX], fMat[kMPersp1],
fMat[kMSkewX], fMat[kMPersp2], scale); | |
| 837 inv->fMat[kMTransX] = scross_dscale(fMat[kMSkewX], fMat[kMTransY],
fMat[kMTransX], fMat[kMScaleY], scale); | |
| 838 | 872 |
| 839 inv->fMat[kMSkewY] = scross_dscale(fMat[kMTransY], fMat[kMPersp0],
fMat[kMSkewY], fMat[kMPersp2], scale); | 873 SkMatrix storage; |
| 840 inv->fMat[kMScaleY] = scross_dscale(fMat[kMScaleX], fMat[kMPersp2],
fMat[kMTransX], fMat[kMPersp0], scale); | 874 if (applyingInPlace || NULL == tmp) { |
| 841 inv->fMat[kMTransY] = scross_dscale(fMat[kMTransX], fMat[kMSkewY],
fMat[kMScaleX], fMat[kMTransY], scale); | 875 tmp = &storage; // we either need to avoid trampling memory or have
no memory |
| 876 } |
| 842 | 877 |
| 843 inv->fMat[kMPersp0] = scross_dscale(fMat[kMSkewY], fMat[kMPersp1],
fMat[kMScaleY], fMat[kMPersp0], scale); | 878 ComputeInv(tmp->fMat, fMat, invDet, isPersp); |
| 844 inv->fMat[kMPersp1] = scross_dscale(fMat[kMSkewX], fMat[kMPersp0],
fMat[kMScaleX], fMat[kMPersp1], scale); | 879 if (!tmp->isFinite()) { |
| 845 inv->fMat[kMPersp2] = scross_dscale(fMat[kMScaleX], fMat[kMScaleY],
fMat[kMSkewX], fMat[kMSkewY], scale); | 880 return false; |
| 846 } else { // not perspective | 881 } |
| 847 inv->fMat[kMScaleX] = SkDoubleToScalar(fMat[kMScaleY] * scale); | |
| 848 inv->fMat[kMSkewX] = SkDoubleToScalar(-fMat[kMSkewX] * scale); | |
| 849 inv->fMat[kMTransX] = dcross_dscale(fMat[kMSkewX], fMat[kMTransY], f
Mat[kMScaleY], fMat[kMTransX], scale); | |
| 850 | 882 |
| 851 inv->fMat[kMSkewY] = SkDoubleToScalar(-fMat[kMSkewY] * scale); | 883 tmp->setTypeMask(fTypeMask); |
| 852 inv->fMat[kMScaleY] = SkDoubleToScalar(fMat[kMScaleX] * scale); | |
| 853 inv->fMat[kMTransY] = dcross_dscale(fMat[kMSkewY], fMat[kMTransX], f
Mat[kMScaleX], fMat[kMTransY], scale); | |
| 854 | 884 |
| 855 inv->fMat[kMPersp0] = 0; | 885 if (applyingInPlace) { |
| 856 inv->fMat[kMPersp1] = 0; | 886 *inv = storage; // need to copy answer back |
| 857 inv->fMat[kMPersp2] = 1; | 887 } |
| 858 } | |
| 859 | 888 |
| 860 inv->setTypeMask(fTypeMask); | |
| 861 | |
| 862 if (inv == &tmp) { | |
| 863 *(SkMatrix*)this = tmp; | |
| 864 } | |
| 865 } | |
| 866 return true; | 889 return true; |
| 867 } | 890 } |
| 868 | 891 |
| 869 /////////////////////////////////////////////////////////////////////////////// | 892 /////////////////////////////////////////////////////////////////////////////// |
| 870 | 893 |
| 871 void SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[
], int count) { | 894 void SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], const SkPoint src[
], int count) { |
| 872 SkASSERT(m.getType() == 0); | 895 SkASSERT(m.getType() == 0); |
| 873 | 896 |
| 874 if (dst != src && count > 0) { | 897 if (dst != src && count > 0) { |
| 875 memcpy(dst, src, count * sizeof(SkPoint)); | 898 memcpy(dst, src, count * sizeof(SkPoint)); |
| (...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1793 rotation1->fX = cos1; | 1816 rotation1->fX = cos1; |
| 1794 rotation1->fY = sin1; | 1817 rotation1->fY = sin1; |
| 1795 } | 1818 } |
| 1796 if (rotation2) { | 1819 if (rotation2) { |
| 1797 rotation2->fX = cos2; | 1820 rotation2->fX = cos2; |
| 1798 rotation2->fY = sin2; | 1821 rotation2->fY = sin2; |
| 1799 } | 1822 } |
| 1800 | 1823 |
| 1801 return true; | 1824 return true; |
| 1802 } | 1825 } |
| OLD | NEW |