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

Unified Diff: src/core/SkMatrix.cpp

Issue 298473002: Add function to get both min and max scale factors from matrix (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Address comments Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkMatrix.h ('k') | tests/MatrixTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkMatrix.cpp
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index 483c6c83e44ef064f3f0191408b98e827668d037..40f6e5298d9375df55a8822b2a0c2372b1b0f116 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -1451,27 +1451,40 @@ bool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[],
///////////////////////////////////////////////////////////////////////////////
-enum MinOrMax {
- kMin_MinOrMax,
- kMax_MinOrMax
+enum MinMaxOrBoth {
+ kMin_MinMaxOrBoth,
+ kMax_MinMaxOrBoth,
+ kBoth_MinMaxOrBoth
};
-template <MinOrMax MIN_OR_MAX> SkScalar get_scale_factor(SkMatrix::TypeMask typeMask,
- const SkScalar m[9]) {
+template <MinMaxOrBoth MIN_MAX_OR_BOTH> bool get_scale_factor(SkMatrix::TypeMask typeMask,
+ const SkScalar m[9],
+ SkScalar results[/*1 or 2*/]) {
if (typeMask & SkMatrix::kPerspective_Mask) {
- return -1;
+ return false;
}
if (SkMatrix::kIdentity_Mask == typeMask) {
- return 1;
+ results[0] = SK_Scalar1;
+ if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ results[1] = SK_Scalar1;
+ }
+ return true;
}
if (!(typeMask & SkMatrix::kAffine_Mask)) {
- if (kMin_MinOrMax == MIN_OR_MAX) {
- return SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
- SkScalarAbs(m[SkMatrix::kMScaleY]));
+ if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ results[0] = SkMinScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
+ SkScalarAbs(m[SkMatrix::kMScaleY]));
+ } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ results[0] = SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
+ SkScalarAbs(m[SkMatrix::kMScaleY]));
} else {
- return SkMaxScalar(SkScalarAbs(m[SkMatrix::kMScaleX]),
- SkScalarAbs(m[SkMatrix::kMScaleY]));
+ results[0] = SkScalarAbs(m[SkMatrix::kMScaleX]);
+ results[1] = SkScalarAbs(m[SkMatrix::kMScaleY]);
+ if (results[0] > results[1]) {
+ SkTSwap(results[0], results[1]);
+ }
}
+ return true;
}
// ignore the translation part of the matrix, just look at 2x2 portion.
// compute singular values, take largest or smallest abs value.
@@ -1487,35 +1500,62 @@ template <MinOrMax MIN_OR_MAX> SkScalar get_scale_factor(SkMatrix::TypeMask type
// l^2 - (a + c)l + (ac-b^2)
// solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff
// and roots are guaranteed to be pos and real).
- SkScalar chosenRoot;
SkScalar bSqd = b * b;
// if upper left 2x2 is orthogonal save some math
if (bSqd <= SK_ScalarNearlyZero*SK_ScalarNearlyZero) {
- if (kMin_MinOrMax == MIN_OR_MAX) {
- chosenRoot = SkMinScalar(a, c);
+ if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ results[0] = SkMinScalar(a, c);
+ } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ results[0] = SkMaxScalar(a, c);
} else {
- chosenRoot = SkMaxScalar(a, c);
+ results[0] = a;
+ results[1] = c;
+ if (results[0] > results[1]) {
+ SkTSwap(results[0], results[1]);
+ }
}
} else {
SkScalar aminusc = a - c;
SkScalar apluscdiv2 = SkScalarHalf(a + c);
SkScalar x = SkScalarHalf(SkScalarSqrt(aminusc * aminusc + 4 * bSqd));
- if (kMin_MinOrMax == MIN_OR_MAX) {
- chosenRoot = apluscdiv2 - x;
+ if (kMin_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ results[0] = apluscdiv2 - x;
+ } else if (kMax_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ results[0] = apluscdiv2 + x;
} else {
- chosenRoot = apluscdiv2 + x;
+ results[0] = apluscdiv2 - x;
+ results[1] = apluscdiv2 + x;
}
}
- SkASSERT(chosenRoot >= 0);
- return SkScalarSqrt(chosenRoot);
+ SkASSERT(results[0] >= 0);
+ results[0] = SkScalarSqrt(results[0]);
+ if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
+ SkASSERT(results[1] >= 0);
+ results[1] = SkScalarSqrt(results[1]);
+ }
+ return true;
}
SkScalar SkMatrix::getMinScale() const {
- return get_scale_factor<kMin_MinOrMax>(this->getType(), fMat);
+ SkScalar factor;
+ if (get_scale_factor<kMin_MinMaxOrBoth>(this->getType(), fMat, &factor)) {
+ return factor;
+ } else {
+ return -1;
+ }
}
SkScalar SkMatrix::getMaxScale() const {
- return get_scale_factor<kMax_MinOrMax>(this->getType(), fMat);
+ SkScalar factor;
+ if (get_scale_factor<kMax_MinMaxOrBoth>(this->getType(), fMat, &factor)) {
+ return factor;
+ } else {
+ return -1;
+ }
+}
+
+bool SkMatrix::getMinMaxScales(SkScalar scaleFactors[2]) const {
+ return get_scale_factor<kBoth_MinMaxOrBoth>(this->getType(), fMat, scaleFactors);
}
static void reset_identity_matrix(SkMatrix* identity) {
« no previous file with comments | « include/core/SkMatrix.h ('k') | tests/MatrixTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698