From a86d1febf45a2a99196e081471900fec4cef2ef8 Mon Sep 17 00:00:00 2001 From: "tor%cs.brown.edu" Date: Tue, 26 Sep 2006 22:27:56 +0000 Subject: [PATCH] Bug 354341 - quit depending on cairo extent calculation bug. r+sr=roc git-svn-id: svn://10.0.0.236/trunk@212420 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/svg/base/src/nsSVGGlyphFrame.cpp | 13 +++++------ .../svg/base/src/nsSVGPathGeometryFrame.cpp | 12 +++------- mozilla/layout/svg/base/src/nsSVGUtils.cpp | 22 +++++++++++++++++++ mozilla/layout/svg/base/src/nsSVGUtils.h | 8 +++++++ 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp b/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp index 09d2f72d2b2..60ab00203a4 100644 --- a/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -429,13 +429,12 @@ nsSVGGlyphFrame::UpdateCoveredRegion() if (hasStroke) { SetupCairoStrokeGeometry(ctx); cairo_stroke_extents(ctx, &xmin, &ymin, &xmax, &ymax); + nsSVGUtils::UserToDeviceBBox(ctx, &xmin, &ymin, &xmax, &ymax); } else { + cairo_identity_matrix(ctx); cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax); } - cairo_user_to_device(ctx, &xmin, &ymin); - cairo_user_to_device(ctx, &xmax, &ymax); - mRect = nsSVGUtils::ToBoundingPixelRect(xmin, ymin, xmax, ymax); return NS_OK; @@ -495,13 +494,12 @@ nsSVGGlyphFrame::GetBBox(nsIDOMSVGRect **_retval) LoopCharacters(ctx, text, cp, cairo_text_path); + cairo_identity_matrix(ctx); + double xmin, ymin, xmax, ymax; cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax); - cairo_user_to_device(ctx, &xmin, &ymin); - cairo_user_to_device(ctx, &xmax, &ymax); - return NS_NewSVGRect(_retval, xmin, ymin, xmax - xmin, ymax - ymin); } @@ -873,12 +871,11 @@ nsSVGGlyphFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval) cairo_rel_line_to(ctx, 0, extent.height); cairo_rel_line_to(ctx, -extent.width, 0); cairo_close_path(ctx); + cairo_identity_matrix(ctx); double xmin, ymin, xmax, ymax; cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax); - cairo_user_to_device(ctx, &xmin, &ymin); - cairo_user_to_device(ctx, &xmax, &ymax); cairo_set_matrix(ctx, &matrix); diff --git a/mozilla/layout/svg/base/src/nsSVGPathGeometryFrame.cpp b/mozilla/layout/svg/base/src/nsSVGPathGeometryFrame.cpp index b38578b43d4..2b78b6dd8e3 100644 --- a/mozilla/layout/svg/base/src/nsSVGPathGeometryFrame.cpp +++ b/mozilla/layout/svg/base/src/nsSVGPathGeometryFrame.cpp @@ -405,7 +405,6 @@ nsSVGPathGeometryFrame::UpdateCoveredRegion() mRect.Empty(); cairo_t *ctx = cairo_create(nsSVGUtils::GetCairoComputationalSurface()); - GeneratePath(ctx, nsnull); double xmin, ymin, xmax, ymax; @@ -413,11 +412,11 @@ nsSVGPathGeometryFrame::UpdateCoveredRegion() if (HasStroke()) { SetupCairoStrokeGeometry(ctx); cairo_stroke_extents(ctx, &xmin, &ymin, &xmax, &ymax); + nsSVGUtils::UserToDeviceBBox(ctx, &xmin, &ymin, &xmax, &ymax); } else { + cairo_identity_matrix(ctx); cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax); } - cairo_user_to_device(ctx, &xmin, &ymin); - cairo_user_to_device(ctx, &xmax, &ymax); if (!IsDegeneratePath(xmin, ymin, xmax, ymax)) mRect = nsSVGUtils::ToBoundingPixelRect(xmin, ymin, xmax, ymax); @@ -482,19 +481,14 @@ nsSVGPathGeometryFrame::GetBBox(nsIDOMSVGRect **_retval) cairo_t *ctx = cairo_create(nsSVGUtils::GetCairoComputationalSurface()); GeneratePath(ctx, nsnull); + cairo_identity_matrix(ctx); cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax); - cairo_user_to_device(ctx, &xmin, &ymin); - cairo_user_to_device(ctx, &xmax, &ymax); - if (IsDegeneratePath(xmin, ymin, xmax, ymax)) { /* cairo_stroke_extents doesn't work with stroke width zero, fudge */ cairo_set_line_width(ctx, 0.0001); cairo_stroke_extents(ctx, &xmin, &ymin, &xmax, &ymax); - - cairo_user_to_device(ctx, &xmin, &ymin); - cairo_user_to_device(ctx, &xmax, &ymax); } cairo_destroy(ctx); diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.cpp b/mozilla/layout/svg/base/src/nsSVGUtils.cpp index b0b16b00567..42f0525a886 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.cpp +++ b/mozilla/layout/svg/base/src/nsSVGUtils.cpp @@ -991,3 +991,25 @@ nsSVGUtils::HitTestRect(nsIDOMSVGMatrix *aMatrix, return result; } + +void +nsSVGUtils::UserToDeviceBBox(cairo_t *ctx, + double *xmin, double *ymin, + double *xmax, double *ymax) +{ + double x[3], y[3]; + x[0] = *xmin; y[0] = *ymax; + x[1] = *xmax; y[1] = *ymax; + x[2] = *xmax; y[2] = *ymin; + + cairo_user_to_device(ctx, xmin, ymin); + *xmax = *xmin; + *ymax = *ymin; + for (int i = 0; i < 3; i++) { + cairo_user_to_device(ctx, &x[i], &y[i]); + *xmin = PR_MIN(*xmin, x[i]); + *xmax = PR_MAX(*xmax, x[i]); + *ymin = PR_MIN(*ymin, y[i]); + *ymax = PR_MAX(*ymax, y[i]); + } +} diff --git a/mozilla/layout/svg/base/src/nsSVGUtils.h b/mozilla/layout/svg/base/src/nsSVGUtils.h index ca141d7eb82..4e00f3ac3a3 100644 --- a/mozilla/layout/svg/base/src/nsSVGUtils.h +++ b/mozilla/layout/svg/base/src/nsSVGUtils.h @@ -268,6 +268,14 @@ public: float aRX, float aRY, float aRWidth, float aRHeight, float aX, float aY); + /* + * Convert a rectangle from cairo user space to device space. + */ + static void + UserToDeviceBBox(cairo_t *ctx, + double *xmin, double *ymin, + double *xmax, double *ymax); + private: /* Cairo computational (nil) surface */ static cairo_surface_t *mCairoComputationalSurface;