зеркало из https://github.com/mozilla/pjs.git
Bug 310473 - avoid passing noninvertable matrices to cairo. r=jwatt
This commit is contained in:
Родитель
fded44a111
Коммит
1c35e721a3
|
@ -630,6 +630,9 @@ nsSVGCairoCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
|
||||||
cairo_matrix_t oldMatrix;
|
cairo_matrix_t oldMatrix;
|
||||||
cairo_get_matrix(mCR, &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 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_transform(mCR, &matrix);
|
||||||
|
|
||||||
cairo_new_path(mCR);
|
cairo_new_path(mCR);
|
||||||
|
|
|
@ -83,7 +83,7 @@ protected:
|
||||||
~nsSVGCairoGlyphGeometry();
|
~nsSVGCairoGlyphGeometry();
|
||||||
nsresult Init(nsISVGGlyphGeometrySource* src);
|
nsresult Init(nsISVGGlyphGeometrySource* src);
|
||||||
|
|
||||||
void GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
|
nsresult GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// nsISupports interface:
|
// nsISupports interface:
|
||||||
|
@ -219,7 +219,12 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
|
||||||
cairo_get_matrix(ctx, &matrix);
|
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);
|
metrics->SelectFont(ctx);
|
||||||
|
|
||||||
|
@ -297,9 +302,11 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
|
||||||
mSource->GetFillGradient(getter_AddRefs(aGrad));
|
mSource->GetFillGradient(getter_AddRefs(aGrad));
|
||||||
|
|
||||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
||||||
cairo_set_source(ctx, gradient);
|
if (gradient) {
|
||||||
LOOP_CHARS(cairo_show_text)
|
cairo_set_source(ctx, gradient);
|
||||||
cairo_pattern_destroy(gradient);
|
LOOP_CHARS(cairo_show_text)
|
||||||
|
cairo_pattern_destroy(gradient);
|
||||||
|
}
|
||||||
} else if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
} else if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
||||||
nsCOMPtr<nsISVGPattern> aPat;
|
nsCOMPtr<nsISVGPattern> aPat;
|
||||||
mSource->GetFillPattern(getter_AddRefs(aPat));
|
mSource->GetFillPattern(getter_AddRefs(aPat));
|
||||||
|
@ -390,9 +397,11 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
|
||||||
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
|
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
|
||||||
|
|
||||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
||||||
cairo_set_source(ctx, gradient);
|
if (gradient) {
|
||||||
cairo_stroke(ctx);
|
cairo_set_source(ctx, gradient);
|
||||||
cairo_pattern_destroy(gradient);
|
cairo_stroke(ctx);
|
||||||
|
cairo_pattern_destroy(gradient);
|
||||||
|
}
|
||||||
} else if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
} else if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
||||||
nsCOMPtr<nsISVGPattern> aPat;
|
nsCOMPtr<nsISVGPattern> aPat;
|
||||||
mSource->GetStrokePattern(getter_AddRefs(aPat));
|
mSource->GetStrokePattern(getter_AddRefs(aPat));
|
||||||
|
@ -486,7 +495,10 @@ nsSVGCairoGlyphGeometry::GetCoveredRegion(nsISVGRendererRegion **_retval)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetGlobalTransform(ctx, nsnull);
|
if (NS_FAILED(GetGlobalTransform(ctx, nsnull))) {
|
||||||
|
cairo_destroy(ctx);
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
metrics->SelectFont(ctx);
|
metrics->SelectFont(ctx);
|
||||||
|
|
||||||
|
@ -626,7 +638,10 @@ nsSVGCairoGlyphGeometry::ContainsPoint(float x, float y, PRBool *_retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_t *ctx = cairo_create(gSVGCairoDummySurface);
|
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);
|
metrics->SelectFont(ctx);
|
||||||
|
|
||||||
|
@ -684,7 +699,7 @@ nsSVGCairoGlyphGeometry::ContainsPoint(float x, float y, PRBool *_retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
nsresult
|
||||||
nsSVGCairoGlyphGeometry::GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCanvas)
|
nsSVGCairoGlyphGeometry::GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCanvas)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMSVGMatrix> ctm;
|
nsCOMPtr<nsIDOMSVGMatrix> ctm;
|
||||||
|
@ -715,7 +730,15 @@ nsSVGCairoGlyphGeometry::GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas* aCa
|
||||||
if (aCanvas) {
|
if (aCanvas) {
|
||||||
aCanvas->AdjustMatrixForInitialTransform(&matrix);
|
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);
|
cairo_set_matrix(ctx, &matrix);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -741,7 +764,11 @@ nsSVGCairoGlyphGeometry::GetBoundingBox(nsIDOMSVGRect * *aBoundingBox)
|
||||||
|
|
||||||
cairo_t *ctx = cairo_create(gSVGCairoDummySurface);
|
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 */
|
/* get the metrics */
|
||||||
nsCOMPtr<nsISVGCairoGlyphMetrics> metrics;
|
nsCOMPtr<nsISVGCairoGlyphMetrics> metrics;
|
||||||
|
@ -750,8 +777,10 @@ nsSVGCairoGlyphGeometry::GetBoundingBox(nsIDOMSVGRect * *aBoundingBox)
|
||||||
mSource->GetMetrics(getter_AddRefs(xpmetrics));
|
mSource->GetMetrics(getter_AddRefs(xpmetrics));
|
||||||
metrics = do_QueryInterface(xpmetrics);
|
metrics = do_QueryInterface(xpmetrics);
|
||||||
NS_ASSERTION(metrics, "wrong metrics object!");
|
NS_ASSERTION(metrics, "wrong metrics object!");
|
||||||
if (!metrics)
|
if (!metrics) {
|
||||||
|
delete [] cp;
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
metrics->SelectFont(ctx);
|
metrics->SelectFont(ctx);
|
||||||
|
|
|
@ -134,7 +134,7 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aGrad, "Called CairoGradient without a gradient!");
|
NS_ASSERTION(aGrad, "Called CairoGradient without a gradient!");
|
||||||
if (!aGrad)
|
if (!aGrad)
|
||||||
return NULL;
|
return nsnull;
|
||||||
|
|
||||||
// Get the transform list (if there is one)
|
// Get the transform list (if there is one)
|
||||||
nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
|
nsCOMPtr<nsIDOMSVGMatrix> svgMatrix;
|
||||||
|
@ -142,6 +142,9 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
|
||||||
NS_ASSERTION(svgMatrix, "CairoGradient: GetGradientTransform returns null");
|
NS_ASSERTION(svgMatrix, "CairoGradient: GetGradientTransform returns null");
|
||||||
|
|
||||||
cairo_matrix_t patternMatrix = SVGToMatrix(svgMatrix);
|
cairo_matrix_t patternMatrix = SVGToMatrix(svgMatrix);
|
||||||
|
if (cairo_matrix_invert(&patternMatrix)) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
cairo_pattern_t *gradient;
|
cairo_pattern_t *gradient;
|
||||||
|
|
||||||
|
@ -153,7 +156,7 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
|
||||||
else if (type == nsISVGGradient::SVG_RADIAL_GRADIENT)
|
else if (type == nsISVGGradient::SVG_RADIAL_GRADIENT)
|
||||||
gradient = CairoRadialGradient(ctx, aGrad);
|
gradient = CairoRadialGradient(ctx, aGrad);
|
||||||
else
|
else
|
||||||
return NULL; // Shouldn't happen
|
return nsnull; // Shouldn't happen
|
||||||
|
|
||||||
PRUint16 aSpread;
|
PRUint16 aSpread;
|
||||||
aGrad->GetSpreadMethod(&aSpread);
|
aGrad->GetSpreadMethod(&aSpread);
|
||||||
|
@ -164,7 +167,6 @@ CairoGradient(cairo_t *ctx, nsISVGGradient *aGrad,
|
||||||
else if (aSpread == nsIDOMSVGGradientElement::SVG_SPREADMETHOD_REPEAT)
|
else if (aSpread == nsIDOMSVGGradientElement::SVG_SPREADMETHOD_REPEAT)
|
||||||
cairo_pattern_set_extend(gradient, CAIRO_EXTEND_REPEAT);
|
cairo_pattern_set_extend(gradient, CAIRO_EXTEND_REPEAT);
|
||||||
|
|
||||||
cairo_matrix_invert(&patternMatrix);
|
|
||||||
cairo_pattern_set_matrix(gradient, &patternMatrix);
|
cairo_pattern_set_matrix(gradient, &patternMatrix);
|
||||||
|
|
||||||
CairoSetStops(gradient, aGrad);
|
CairoSetStops(gradient, aGrad);
|
||||||
|
|
|
@ -182,6 +182,13 @@ nsSVGCairoPathGeometry::GeneratePath(cairo_t *ctx, nsISVGCairoCanvas* aCanvas)
|
||||||
if (aCanvas) {
|
if (aCanvas) {
|
||||||
aCanvas->AdjustMatrixForInitialTransform(&matrix);
|
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);
|
cairo_set_matrix(ctx, &matrix);
|
||||||
|
|
||||||
nsCOMPtr<nsISVGRendererPathBuilder> builder;
|
nsCOMPtr<nsISVGRendererPathBuilder> builder;
|
||||||
|
@ -350,9 +357,11 @@ nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas)
|
||||||
mSource->GetFillGradient(getter_AddRefs(aGrad));
|
mSource->GetFillGradient(getter_AddRefs(aGrad));
|
||||||
|
|
||||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
||||||
cairo_set_source(ctx, gradient);
|
if (gradient) {
|
||||||
cairo_fill_preserve(ctx);
|
cairo_set_source(ctx, gradient);
|
||||||
cairo_pattern_destroy(gradient);
|
cairo_fill_preserve(ctx);
|
||||||
|
cairo_pattern_destroy(gradient);
|
||||||
|
}
|
||||||
} else if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
} else if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
||||||
nsCOMPtr<nsISVGPattern> aPat;
|
nsCOMPtr<nsISVGPattern> aPat;
|
||||||
mSource->GetFillPattern(getter_AddRefs(aPat));
|
mSource->GetFillPattern(getter_AddRefs(aPat));
|
||||||
|
@ -392,9 +401,11 @@ nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas)
|
||||||
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
|
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
|
||||||
|
|
||||||
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
|
||||||
cairo_set_source(ctx, gradient);
|
if (gradient) {
|
||||||
cairo_stroke(ctx);
|
cairo_set_source(ctx, gradient);
|
||||||
cairo_pattern_destroy(gradient);
|
cairo_stroke(ctx);
|
||||||
|
cairo_pattern_destroy(gradient);
|
||||||
|
}
|
||||||
} else if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
} else if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_PATTERN) {
|
||||||
nsCOMPtr<nsISVGPattern> aPat;
|
nsCOMPtr<nsISVGPattern> aPat;
|
||||||
mSource->GetStrokePattern(getter_AddRefs(aPat));
|
mSource->GetStrokePattern(getter_AddRefs(aPat));
|
||||||
|
|
|
@ -113,11 +113,15 @@ CairoPattern(nsISVGRendererCanvas *canvas, nsISVGPattern *aPat,
|
||||||
|
|
||||||
// Translate the pattern frame
|
// Translate the pattern frame
|
||||||
cairo_matrix_t pmatrix = SVGToMatrix(pMatrix);
|
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_t *surface_pattern =
|
||||||
cairo_pattern_set_matrix (surface_pattern, &pmatrix);
|
cairo_pattern_create_for_surface(pattern_surface);
|
||||||
cairo_pattern_set_extend (surface_pattern, CAIRO_EXTEND_REPEAT);
|
if (surface_pattern) {
|
||||||
|
cairo_pattern_set_matrix (surface_pattern, &pmatrix);
|
||||||
|
cairo_pattern_set_extend (surface_pattern, CAIRO_EXTEND_REPEAT);
|
||||||
|
}
|
||||||
return surface_pattern;
|
return surface_pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче