Skip to content
This repository has been archived by the owner on Jun 19, 2018. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
[PDF] Handle failures of matrix inversion
Previously reviewed in https://codereview.appspot.com/6033047.  Rolled back
because of unrelated fixed-point bugs.

Review URL: https://codereview.appspot.com/6052051

git-svn-id: http://skia.googlecode.com/svn/trunk/src@3715 2bbb7eff-a529-9590-31e7-b0007b416f81
  • Loading branch information
vandebo@chromium.org committed Apr 17, 2012
1 parent 091d321 commit 86edf73
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 12 deletions.
4 changes: 3 additions & 1 deletion pdf/SkPDFDevice.cpp
Expand Up @@ -491,6 +491,8 @@ static inline SkBitmap makeContentBitmap(const SkISize& contentSize,
drawingSize.set(SkIntToScalar(contentSize.fWidth),
SkIntToScalar(contentSize.fHeight));
if (!initialTransform->invert(&inverse)) {
// This shouldn't happen, initial transform should be invertible.
SkASSERT(false);
inverse.reset();
}
inverse.mapVectors(&drawingSize, 1);
Expand Down Expand Up @@ -603,7 +605,7 @@ void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
totalTransform.preConcat(contentEntry->fState.fMatrix);
SkMatrix inverse;
if (!totalTransform.invert(&inverse)) {
inverse.reset();
return;
}
inverse.mapRect(&bbox);

Expand Down
2 changes: 2 additions & 0 deletions pdf/SkPDFFormXObject.cpp
Expand Up @@ -37,6 +37,8 @@ SkPDFFormXObject::SkPDFFormXObject(SkPDFDevice* device) {
if (!device->initialTransform().isIdentity()) {
SkMatrix inverse;
if (!device->initialTransform().invert(&inverse)) {
// The initial transform should be invertible.
SkASSERT(false);
inverse.reset();
}
insert("Matrix", SkPDFUtils::MatrixToArray(inverse))->unref();
Expand Down
35 changes: 24 additions & 11 deletions pdf/SkPDFShader.cpp
Expand Up @@ -21,12 +21,13 @@
#include "SkThread.h"
#include "SkTypes.h"

static void transformBBox(const SkMatrix& matrix, SkRect* bbox) {
static bool transformBBox(const SkMatrix& matrix, SkRect* bbox) {
SkMatrix inverse;
if (!matrix.invert(&inverse)) {
inverse.reset();
return false;
}
inverse.mapRect(bbox);
return true;
}

static void unitToPointsMatrix(const SkPoint pts[2], SkMatrix* matrix) {
Expand Down Expand Up @@ -309,7 +310,7 @@ class SkPDFFunctionShader : public SkPDFDict, public SkPDFShader {
fResources.unrefAll();
}

bool isValid() { return fResources.count() > 0; }
virtual bool isValid() { return fResources.count() > 0; }

void getResources(SkTDArray<SkPDFObject*>* resourceList) {
GetResourcesHelper(&fResources, resourceList);
Expand All @@ -332,6 +333,8 @@ class SkPDFImageShader : public SkPDFStream, public SkPDFShader {
fResources.unrefAll();
}

virtual bool isValid() { return size() > 0; }

void getResources(SkTDArray<SkPDFObject*>* resourceList) {
GetResourcesHelper(&fResources, resourceList);
}
Expand Down Expand Up @@ -367,18 +370,24 @@ SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader,
result->ref();
return result;
}

bool valid = false;
// The PDFShader takes ownership of the shaderSate.
if (shaderState.get()->fType == SkShader::kNone_GradientType) {
result = new SkPDFImageShader(shaderState.detach());
SkPDFImageShader* imageShader =
new SkPDFImageShader(shaderState.detach());
valid = imageShader->isValid();
result = imageShader;
} else {
SkPDFFunctionShader* functionShader =
new SkPDFFunctionShader(shaderState.detach());
if (!functionShader->isValid()) {
delete functionShader;
return NULL;
}
valid = functionShader->isValid();
result = functionShader;
}
if (!valid) {
delete result;
return NULL;
}
entry.fPDFShader = result;
CanonicalShaders().push(entry);
return result; // return the reference that came from new.
Expand Down Expand Up @@ -472,7 +481,9 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
finalMatrix.preConcat(fState.get()->fShaderTransform);
SkRect bbox;
bbox.set(fState.get()->fBBox);
transformBBox(finalMatrix, &bbox);
if (!transformBBox(finalMatrix, &bbox)) {
return;
}

SkRefPtr<SkPDFArray> domain = new SkPDFArray;
domain->unref(); // SkRefPtr and new both took a reference.
Expand All @@ -490,7 +501,7 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
SkShader::GradientInfo twoPointRadialInfo = *info;
SkMatrix inverseMapperMatrix;
if (!mapperMatrix.invert(&inverseMapperMatrix)) {
inverseMapperMatrix.reset();
return;
}
inverseMapperMatrix.mapPoints(twoPointRadialInfo.fPoint, 2);
twoPointRadialInfo.fRadius[0] =
Expand Down Expand Up @@ -525,7 +536,9 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
finalMatrix.preConcat(fState.get()->fShaderTransform);
SkRect surfaceBBox;
surfaceBBox.set(fState.get()->fBBox);
transformBBox(finalMatrix, &surfaceBBox);
if (!transformBBox(finalMatrix, &surfaceBBox)) {
return;
}

SkMatrix unflip;
unflip.setTranslate(0, SkScalarRoundToScalar(surfaceBBox.height()));
Expand Down
2 changes: 2 additions & 0 deletions pdf/SkPDFShader.h
Expand Up @@ -60,6 +60,8 @@ class SkPDFShader {
static void RemoveShader(SkPDFObject* shader);

SkPDFShader();

virtual bool isValid() = 0;
};

#endif

0 comments on commit 86edf73

Please sign in to comment.