SkScalerContextRec::computeMatrices to return status.

When computing the matricies for a scaler context, there is a special
case when the matrix is determined to be singular. No port properly
handles zero sized text, so we detect this case and return a 'normal'
text size and a zero matrix for all computed transformations. This
CL causes computeMatricies to return 'false' in this case.

This is used in the constructor of SkScalerContext_Mac in order to
avoid calling CGAffineTransformInvert on non-invertible transformations.
CGAffineTransformInvert documents that if the transform is
non-invertible it will return the passed transform unchanged. It does
so, but then also prints a message to stdout. Since the information is
already available to avoid this chatty behavior, use it to keep things
quiet.

BUG=skia:3231,chromium:630169
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2276583003

Review-Url: https://codereview.chromium.org/2276583003
This commit is contained in:
bungeman 2016-08-23 13:19:01 -07:00 committed by Commit bot
parent da19f6f3b5
commit 1f0e78ddf9
3 changed files with 15 additions and 6 deletions

View File

@ -687,7 +687,7 @@ void SkScalerContextRec::getSingleMatrix(SkMatrix* m) const {
m->postConcat(deviceMatrix); m->postConcat(deviceMatrix);
} }
void SkScalerContextRec::computeMatrices(PreMatrixScale preMatrixScale, SkVector* s, SkMatrix* sA, bool SkScalerContextRec::computeMatrices(PreMatrixScale preMatrixScale, SkVector* s, SkMatrix* sA,
SkMatrix* GsA, SkMatrix* G_inv, SkMatrix* A_out) SkMatrix* GsA, SkMatrix* G_inv, SkMatrix* A_out)
{ {
// A is the 'total' matrix. // A is the 'total' matrix.
@ -723,7 +723,7 @@ void SkScalerContextRec::computeMatrices(PreMatrixScale preMatrixScale, SkVector
if (G_inv) { if (G_inv) {
G_inv->reset(); G_inv->reset();
} }
return; return false;
} }
// GA is the matrix A with rotation removed. // GA is the matrix A with rotation removed.
@ -803,6 +803,8 @@ void SkScalerContextRec::computeMatrices(PreMatrixScale preMatrixScale, SkVector
// G is rotational so reorders with the scale. // G is rotational so reorders with the scale.
GsA->preScale(SkScalarInvert(s->fX), SkScalarInvert(s->fY)); GsA->preScale(SkScalarInvert(s->fX), SkScalarInvert(s->fY));
} }
return true;
} }
SkAxisAlignment SkScalerContext::computeAxisAlignmentForHText() { SkAxisAlignment SkScalerContext::computeAxisAlignmentForHText() {

View File

@ -146,8 +146,9 @@ struct SkScalerContextRec {
* @param remainingWithoutRotation apply after scale to apply the total matrix sans rotation. * @param remainingWithoutRotation apply after scale to apply the total matrix sans rotation.
* @param remainingRotation apply after remainingWithoutRotation to apply the total matrix. * @param remainingRotation apply after remainingWithoutRotation to apply the total matrix.
* @param total the total matrix. * @param total the total matrix.
* @return false if the matrix was singular. The output will be valid but not invertable.
*/ */
void computeMatrices(PreMatrixScale preMatrixScale, bool computeMatrices(PreMatrixScale preMatrixScale,
SkVector* scale, SkMatrix* remaining, SkVector* scale, SkMatrix* remaining,
SkMatrix* remainingWithoutRotation = nullptr, SkMatrix* remainingWithoutRotation = nullptr,
SkMatrix* remainingRotation = nullptr, SkMatrix* remainingRotation = nullptr,

View File

@ -807,10 +807,16 @@ SkScalerContext_Mac::SkScalerContext_Mac(SkTypeface_Mac* typeface,
// As a result, it is necessary to know the actual device size and request that. // As a result, it is necessary to know the actual device size and request that.
SkVector scale; SkVector scale;
SkMatrix skTransform; SkMatrix skTransform;
fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale, &scale, &skTransform, bool invertable = fRec.computeMatrices(SkScalerContextRec::kVertical_PreMatrixScale,
nullptr, nullptr, &fFUnitMatrix); &scale, &skTransform, nullptr, nullptr, &fFUnitMatrix);
fTransform = MatrixToCGAffineTransform(skTransform); fTransform = MatrixToCGAffineTransform(skTransform);
fInvTransform = CGAffineTransformInvert(fTransform); // CGAffineTransformInvert documents that if the transform is non-invertible it will return the
// passed transform unchanged. It does so, but then also prints a message to stdout. Avoid this.
if (invertable) {
fInvTransform = CGAffineTransformInvert(fTransform);
} else {
fInvTransform = fTransform;
}
// The transform contains everything except the requested text size. // The transform contains everything except the requested text size.
// Some properties, like 'trak', are based on the text size (before applying the matrix). // Some properties, like 'trak', are based on the text size (before applying the matrix).