diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 38 | ||||
-rw-r--r-- | src/core/SkMatrix.cpp | 22 | ||||
-rw-r--r-- | src/core/SkPictureShader.cpp | 3 |
3 files changed, 35 insertions, 28 deletions
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 720a30f05c..0b50fbc32d 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -98,12 +98,6 @@ static bool valid_for_filtering(unsigned dimension) { return (dimension & ~0x3FFF) == 0; } -static SkScalar effective_matrix_scale(const SkMatrix& mat) { - SkScalar dx = SkVector::Length(mat.getScaleX(), mat.getSkewY()); - SkScalar dy = SkVector::Length(mat.getSkewX(), mat.getScaleY()); - return SkScalarSqrt(dx * dy); -} - // Check to see that the size of the bitmap that would be produced by // scaling by the given inverted matrix is less than the maximum allowed. static inline bool cache_size_okay(const SkBitmap& bm, const SkMatrix& invMat) { @@ -119,22 +113,6 @@ static inline bool cache_size_okay(const SkBitmap& bm, const SkMatrix& invMat) { } /* - * Extract the "best" scale factors from a matrix. - */ -static bool extract_scale(const SkMatrix& matrix, SkVector* scale) { - SkASSERT(!matrix.hasPerspective()); - SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]); - SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX], matrix[SkMatrix::kMScaleY]); - if (!SkScalarIsFinite(sx) || !SkScalarIsFinite(sy) || - SkScalarNearlyZero(sx) || SkScalarNearlyZero(sy)) - { - return false; - } - scale->set(sx, sy); - return true; -} - -/* * High quality is implemented by performing up-right scale-only filtering and then * using bilerp for any remaining transformations. */ @@ -154,12 +132,12 @@ void SkBitmapProcState::processHQRequest() { SkScalar invScaleX = fInvMatrix.getScaleX(); SkScalar invScaleY = fInvMatrix.getScaleY(); if (fInvMatrix.getType() & SkMatrix::kAffine_Mask) { - SkVector scale; - if (!extract_scale(fInvMatrix, &scale)) { - return; // can't find suitable scale factors + SkSize scale; + if (!fInvMatrix.decomposeScale(&scale)) { + return; } - invScaleX = scale.x(); - invScaleY = scale.y(); + invScaleX = scale.width(); + invScaleY = scale.height(); } if (SkScalarNearlyEqual(invScaleX, 1) && SkScalarNearlyEqual(invScaleY, 1)) { return; // no need for HQ @@ -204,7 +182,11 @@ void SkBitmapProcState::processMediumRequest() { // to a valid bitmap. fFilterLevel = kLow_SkFilterQuality; - SkScalar invScale = effective_matrix_scale(fInvMatrix); + SkSize invScaleSize; + if (!fInvMatrix.decomposeScale(&invScaleSize, NULL)) { + return; + } + SkScalar invScale = SkScalarSqrt(invScaleSize.width() * invScaleSize.height()); if (invScale > SK_Scalar1) { fCurrMip.reset(SkMipMapCache::FindAndRef(fOrigBitmap)); diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 9658177ec9..753c4dc61e 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1603,6 +1603,28 @@ const SkMatrix& SkMatrix::InvalidMatrix() { return invalid.asSkMatrix(); } +bool SkMatrix::decomposeScale(SkSize* scale, SkMatrix* remaining) const { + if (this->hasPerspective()) { + return false; + } + + const SkScalar sx = SkVector::Length(this->getScaleX(), this->getSkewY()); + const SkScalar sy = SkVector::Length(this->getSkewX(), this->getScaleY()); + if (!SkScalarIsFinite(sx) || !SkScalarIsFinite(sy) || + SkScalarNearlyZero(sx) || SkScalarNearlyZero(sy)) { + return false; + } + + if (scale) { + scale->set(sx, sy); + } + if (remaining) { + *remaining = *this; + remaining->postScale(SkScalarInvert(sx), SkScalarInvert(sy)); + } + return true; +} + /////////////////////////////////////////////////////////////////////////////// size_t SkMatrix::writeToMemory(void* buffer) const { diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index 776fe5e655..3734791ce4 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -152,6 +152,9 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatri // Use a rotation-invariant scale SkPoint scale; + // + // TODO: replace this with decomposeScale() -- but beware LayoutTest rebaselines! + // if (!SkDecomposeUpper2x2(m, NULL, &scale, NULL)) { // Decomposition failed, use an approximation. scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSkewX()), |