[cairo-commit] 2 commits - src/cairoint.h src/cairo-pattern.c test/huge-pattern-pdf-ref.png test/huge-pattern-pdf-rgb24-ref.png test/huge-pattern-ps3-ref.png test/Makefile.am
Chris Wilson
ickle at kemper.freedesktop.org
Sun Oct 12 04:26:25 PDT 2008
src/cairo-pattern.c | 48 +++++++++++++++++++++++++++++++-----
src/cairoint.h | 5 +++
test/Makefile.am | 5 ++-
test/huge-pattern-pdf-ref.png |binary
test/huge-pattern-pdf-rgb24-ref.png |binary
test/huge-pattern-ps3-ref.png |binary
6 files changed, 49 insertions(+), 9 deletions(-)
New commits:
commit ceab32e2c3d51c0dd29b105a5a390cdd8aa58f8f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Oct 12 12:11:12 2008 +0100
[win32] win32 also uses font subsets.
Include win32 in the list of font subset users, fixes build when
cross-compiling.
diff --git a/src/cairoint.h b/src/cairoint.h
index 8b2bd49..afdcd4d 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -72,7 +72,10 @@
#include "cairo-compiler-private.h"
-#if CAIRO_HAS_PS_SURFACE || CAIRO_HAS_PDF_SURFACE || CAIRO_HAS_SVG_SURFACE
+#if CAIRO_HAS_PS_SURFACE || \
+ CAIRO_HAS_PDF_SURFACE || \
+ CAIRO_HAS_SVG_SURFACE || \
+ CAIRO_HAS_WIN32_SURFACE
#define CAIRO_HAS_FONT_SUBSET 1
#endif
commit 1d3453eee50e4343995c5d3f225d18289fbcebec
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Oct 12 11:21:14 2008 +0100
[pattern] Rescale the linear pattern matrix to avoid overflow.
As proof-of-principle, compute a scale factor to avoid overflow when
converting a linear pattern to pixman_fixed_t. Fixes test/huge-pattern,
but the principle should be extended to handle more cases of overflow.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index b2b1c60..c60b1f6 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1248,6 +1248,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
pixman_gradient_stop_t *pixman_stops = pixman_stops_static;
unsigned int i;
int clone_offset_x, clone_offset_y;
+ cairo_matrix_t matrix = pattern->base.matrix;
if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t));
@@ -1267,11 +1268,46 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
{
cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern;
pixman_point_fixed_t p1, p2;
+ cairo_fixed_t xdim, ydim;
+
+ xdim = linear->p2.x - linear->p1.x;
+ ydim = linear->p2.y - linear->p1.y;
+
+ /*
+ * Transform the matrix to avoid overflow when converting between
+ * cairo_fixed_t and pixman_fixed_t (without incurring performance
+ * loss when the transformation is unnecessary).
+ *
+ * XXX: Consider converting out-of-range co-ordinates and transforms.
+ * Having a function to compute the required transformation to
+ * "normalize" a given bounding box would be generally useful -
+ * cf linear patterns, gradient patterns, surface patterns...
+ */
+#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */
+ if (_cairo_fixed_integer_ceil (xdim) > PIXMAN_MAX_INT ||
+ _cairo_fixed_integer_ceil (ydim) > PIXMAN_MAX_INT)
+ {
+ double sf;
+
+ if (xdim > ydim)
+ sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (xdim);
+ else
+ sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim);
+
+ p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.x) * sf);
+ p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.y) * sf);
+ p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.x) * sf);
+ p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.y) * sf);
- p1.x = _cairo_fixed_to_16_16 (linear->p1.x);
- p1.y = _cairo_fixed_to_16_16 (linear->p1.y);
- p2.x = _cairo_fixed_to_16_16 (linear->p2.x);
- p2.y = _cairo_fixed_to_16_16 (linear->p2.y);
+ cairo_matrix_scale (&matrix, sf, sf);
+ }
+ else
+ {
+ p1.x = _cairo_fixed_to_16_16 (linear->p1.x);
+ p1.y = _cairo_fixed_to_16_16 (linear->p1.y);
+ p2.x = _cairo_fixed_to_16_16 (linear->p2.x);
+ p2.y = _cairo_fixed_to_16_16 (linear->p2.y);
+ }
pixman_image = pixman_image_create_linear_gradient (&p1, &p2,
pixman_stops,
@@ -1315,7 +1351,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
}
attr->x_offset = attr->y_offset = 0;
- attr->matrix = pattern->base.matrix;
+ attr->matrix = matrix;
attr->extend = pattern->base.extend;
attr->filter = CAIRO_FILTER_NEAREST;
attr->acquired = FALSE;
@@ -1363,7 +1399,7 @@ _cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
return image->base.status;
}
- _cairo_matrix_to_pixman_matrix (&pattern->base.matrix, &pixman_transform);
+ _cairo_matrix_to_pixman_matrix (&matrix, &pixman_transform);
if (!pixman_image_set_transform (pixman_image, &pixman_transform)) {
cairo_surface_destroy (&image->base);
pixman_image_unref (pixman_image);
diff --git a/test/Makefile.am b/test/Makefile.am
index 6a98cf6..bd7272e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -541,6 +541,9 @@ REFERENCE_IMAGES = \
gradient-zero-stops-rgb24-ref.png \
group-paint-ref.png \
huge-pattern-ref.png \
+ huge-pattern-ps3-ref.png \
+ huge-pattern-pdf-ref.png \
+ huge-pattern-pdf-rgb24-ref.png \
image-surface-source-ref.png \
infinite-join-ref.png \
infinite-join-ps2-ref.png \
@@ -947,7 +950,6 @@ $(REFERENCE_IMAGES)
# room, with Carl as a moderator and not let them out
# until they have come up with an interface and
# semantics that actually work. :-)
-# huge-pattern - range overflow of fixed-point
# long-lines - range overflow of fixed-point
# self-copy-overlap - vector surfaces take snapshot of patterns in contrast
# to the raster backends which don't. One solution
@@ -971,7 +973,6 @@ degenerate-path$(EXEEXT) \
device-offset-scale$(EXEEXT) \
extend-pad$(EXEEXT) \
fallback-resolution$(EXEEXT) \
-huge-pattern$(EXEEXT) \
long-lines$(EXEEXT) \
self-copy-overlap$(EXEEXT) \
self-intersecting$(EXEEXT) \
diff --git a/test/huge-pattern-pdf-ref.png b/test/huge-pattern-pdf-ref.png
new file mode 100644
index 0000000..dfa8c5b
Binary files /dev/null and b/test/huge-pattern-pdf-ref.png differ
diff --git a/test/huge-pattern-pdf-rgb24-ref.png b/test/huge-pattern-pdf-rgb24-ref.png
new file mode 100644
index 0000000..a950f8b
Binary files /dev/null and b/test/huge-pattern-pdf-rgb24-ref.png differ
diff --git a/test/huge-pattern-ps3-ref.png b/test/huge-pattern-ps3-ref.png
new file mode 100644
index 0000000..d55239b
Binary files /dev/null and b/test/huge-pattern-ps3-ref.png differ
More information about the cairo-commit
mailing list