зеркало из https://github.com/mozilla/gecko-dev.git
Bug 310473 - avoid passing noninvertable matrices to cairo. r=jwatt
This commit is contained in:
Родитель
2583a3b7b8
Коммит
0dc9a332f3
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче