Bug 310473 - avoid passing noninvertable matrices to cairo. r=jwatt

This commit is contained in:
tor%cs.brown.edu 2005-10-02 19:35:22 +00:00
Родитель 2583a3b7b8
Коммит 0dc9a332f3
5 изменённых файлов: 75 добавлений и 26 удалений

Просмотреть файл

@ -630,6 +630,9 @@ nsSVGCairoCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
cairo_matrix_t oldMatrix;
cairo_get_matrix(mCR, &oldMatrix);
cairo_matrix_t matrix = {m[0], m[1], m[2], m[3], m[4], m[5]};
cairo_matrix_t inverse = matrix;
if (cairo_matrix_invert(&inverse))
return NS_ERROR_FAILURE;
cairo_transform(mCR, &matrix);
cairo_new_path(mCR);

Просмотреть файл

@ -83,7 +83,7 @@ protected:
~nsSVGCairoGlyphGeometry();
nsresult Init(nsISVGGlyphGeometrySource* src);
void GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
nsresult GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
public:
// nsISupports interface:
@ -219,7 +219,12 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
cairo_get_matrix(ctx, &matrix);
}
GetGlobalTransform(ctx, cairoCanvas);
if (NS_FAILED(GetGlobalTransform(ctx, cairoCanvas))) {
if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL)
cairo_restore(ctx);
delete [] cp;
return NS_ERROR_FAILURE;
}
metrics->SelectFont(ctx);
@ -297,9 +302,11 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
mSource->GetFillGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
LOOP_CHARS(cairo_show_text)
cairo_pattern_destroy(gradient);
if (gradient) {
cairo_set_source(ctx, gradient);
LOOP_CHARS(cairo_show_text)
cairo_pattern_destroy(gradient);
}
} else if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
nsCOMPtr<nsISVGPattern> aPat;
mSource->GetFillPattern(getter_AddRefs(aPat));
@ -390,9 +397,11 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
if (gradient) {
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
}
} else if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
nsCOMPtr<nsISVGPattern> aPat;
mSource->GetStrokePattern(getter_AddRefs(aPat));
@ -486,7 +495,10 @@ nsSVGCairoGlyphGeometry::GetCoveredRegion(nsISVGRendererRegion **_retval)
return NS_ERROR_FAILURE;
}
GetGlobalTransform(ctx, nsnull);
if (NS_FAILED(GetGlobalTransform(ctx, nsnull))) {
cairo_destroy(ctx);
return NS_ERROR_FAILURE;
}
metrics->SelectFont(ctx);
@ -626,7 +638,10 @@ nsSVGCairoGlyphGeometry::ContainsPoint(float x, float y, PRBool *_retval)
}
cairo_t *ctx = cairo_create(gSVGCairoDummySurface);
GetGlobalTransform(ctx, nsnull);
if (NS_FAILED(GetGlobalTransform(ctx, nsnull))) {
cairo_destroy(ctx);
return NS_ERROR_FAILURE;
}
metrics->SelectFont(ctx);
@ -684,7 +699,7 @@ nsSVGCairoGlyphGeometry::ContainsPoint(float x, float y, PRBool *_retval)
}
void
nsresult
nsSVGCairoGlyphGeometry::GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCanvas)
{
nsCOMPtr<nsIDOMSVGMatrix> ctm;
@ -715,7 +730,15 @@ nsSVGCairoGlyphGeometry::GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCa
if (aCanvas) {
aCanvas->AdjustMatrixForInitialTransform(&matrix);
}
cairo_matrix_t inverse = matrix;
if (cairo_matrix_invert(&inverse)) {
cairo_identity_matrix(ctx);
return NS_ERROR_FAILURE;
}
cairo_set_matrix(ctx, &matrix);
return NS_OK;
}
NS_IMETHODIMP
@ -741,7 +764,11 @@ nsSVGCairoGlyphGeometry::GetBoundingBox(nsIDOMSVGRect * *aBoundingBox)
cairo_t *ctx = cairo_create(gSVGCairoDummySurface);
GetGlobalTransform(ctx, nsnull);
if (NS_FAILED(GetGlobalTransform(ctx, nsnull))) {
cairo_destroy(ctx);
delete [] cp;
return NS_ERROR_FAILURE;
}
/* get the metrics */
nsCOMPtr<nsISVGCairoGlyphMetrics> metrics;
@ -750,8 +777,10 @@ nsSVGCairoGlyphGeometry::GetBoundingBox(nsIDOMSVGRect * *aBoundingBox)
mSource->GetMetrics(getter_AddRefs(xpmetrics));
metrics = do_QueryInterface(xpmetrics);
NS_ASSERTION(metrics, "wrong metrics object!");
if (!metrics)
if (!metrics) {
delete [] cp;
return NS_ERROR_FAILURE;
}
}
metrics->SelectFont(ctx);

Просмотреть файл

@ -134,7 +134,7 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
{
NS_ASSERTION(aGrad, "Called CairoGradient without a gradient!");
if (!aGrad)
return NULL;
return nsnull;
// Get the transform list (if there is one)
nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
@ -142,6 +142,9 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
NS_ASSERTION(svgMatrix, "CairoGradient: GetGradientTransform returns null");
cairo_matrix_t patternMatrix = SVGToMatrix(svgMatrix);
if (cairo_matrix_invert(&patternMatrix)) {
return nsnull;
}
cairo_pattern_t *gradient;
@ -153,7 +156,7 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
else if (type == nsISVGGradient::SVG_RADIAL_GRADIENT)
gradient = CairoRadialGradient(ctx, aGrad);
else
return NULL; // Shouldn't happen
return nsnull; // Shouldn't happen
PRUint16 aSpread;
aGrad->GetSpreadMethod(&aSpread);
@ -164,7 +167,6 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
else if (aSpread == nsIDOMSVGGradientElement::SVG_SPREADMETHOD_REPEAT)
cairo_pattern_set_extend(gradient, CAIRO_EXTEND_REPEAT);
cairo_matrix_invert(&patternMatrix);
cairo_pattern_set_matrix(gradient, &patternMatrix);
CairoSetStops(gradient, aGrad);

Просмотреть файл

@ -182,6 +182,13 @@ nsSVGCairoPathGeometry::GeneratePath(cairo_t *ctx, nsISVGCairoCanvas* aCanvas)
if (aCanvas) {
aCanvas->AdjustMatrixForInitialTransform(&matrix);
}
cairo_matrix_t inverse = matrix;
if (cairo_matrix_invert(&inverse)) {
cairo_identity_matrix(ctx);
cairo_new_path(ctx);
return;
}
cairo_set_matrix(ctx, &matrix);
nsCOMPtr<nsISVGRendererPathBuilder> builder;
@ -350,9 +357,11 @@ nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas)
mSource->GetFillGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_fill_preserve(ctx);
cairo_pattern_destroy(gradient);
if (gradient) {
cairo_set_source(ctx, gradient);
cairo_fill_preserve(ctx);
cairo_pattern_destroy(gradient);
}
} else if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
nsCOMPtr<nsISVGPattern> aPat;
mSource->GetFillPattern(getter_AddRefs(aPat));
@ -392,9 +401,11 @@ nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas)
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
if (gradient) {
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
}
} else if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
nsCOMPtr<nsISVGPattern> aPat;
mSource->GetStrokePattern(getter_AddRefs(aPat));

Просмотреть файл

@ -113,11 +113,15 @@ CairoPattern(nsISVGRendererCanvas *canvas, nsISVGPattern *aPat,
// Translate the pattern frame
cairo_matrix_t pmatrix = SVGToMatrix(pMatrix);
cairo_matrix_invert(&pmatrix);
if (cairo_matrix_invert(&pmatrix))
return nsnull;
cairo_pattern_t *surface_pattern = cairo_pattern_create_for_surface(pattern_surface);
cairo_pattern_set_matrix (surface_pattern, &pmatrix);
cairo_pattern_set_extend (surface_pattern, CAIRO_EXTEND_REPEAT);
cairo_pattern_t *surface_pattern =
cairo_pattern_create_for_surface(pattern_surface);
if (surface_pattern) {
cairo_pattern_set_matrix (surface_pattern, &pmatrix);
cairo_pattern_set_extend (surface_pattern, CAIRO_EXTEND_REPEAT);
}
return surface_pattern;
}