summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2007-02-27 18:47:47 -0500
committerBehdad Esfahbod <behdad@behdad.org>2007-02-27 18:47:47 -0500
commite2ce27db302a185e6e80ead699c01e43921939ca (patch)
tree667cb20f735703ec01db43ffbdb169727d5bb92f
parentde0a6522b00822305fa5a0e32c4821628425ebdc (diff)
[PS/PDF] Fix xstep/ystep values for CAIRO_EXTEND_NONE
This fixes the fallback-resolution test, as well as the two of surface-pattern-scale-up and surface-pattern-scale-down.
-rw-r--r--src/cairo-pdf-surface.c36
-rw-r--r--src/cairo-ps-surface.c43
2 files changed, 43 insertions, 36 deletions
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 3b8830d1..938a4f0f 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -878,7 +878,7 @@ emit_surface_pattern (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t alpha, image_resource = {0}; /* squelch bogus compiler warning */
cairo_matrix_t cairo_p2d, pdf_p2d;
cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base);
- int xstep, ystep;
+ double xstep, ystep;
cairo_rectangle_int16_t surface_extents;
/* XXX: Should do something clever here for PDF source surfaces ? */
@@ -905,36 +905,30 @@ emit_surface_pattern (cairo_pdf_surface_t *surface,
switch (extend) {
case CAIRO_EXTEND_NONE:
{
- /* In PDF, (as far as I can tell), all patterns are
+ /* In PS/PDF, (as far as I can tell), all patterns are
* repeating. So we support cairo's EXTEND_NONE semantics
* by setting the repeat step size to a size large enough
* to guarantee that no more than a single occurrence will
* be visible.
*
- * First, map the pattern's extents through the inverse
- * pattern matrix to compute the device-space bounds of
- * the desired single occurrence. Then consider the bounds
- * of (the union of this rectangle with the target surface
- * extents). If the repeat size is larger than the
- * diagonal of the bounds of the union, then it is
- * guaranteed to never repeat visibly.
+ * First, map the surface extents into pattern space (since
+ * xstep and ystep are in pattern space). Then use an upper
+ * bound on the length of the diagonal of the pattern image
+ * and the surface as repeat size. This guarantees to never
+ * repeat visibly.
*/
double x1 = 0.0, y1 = 0.0;
- double x2 = image->width, y2 = image->height;
- cairo_matrix_t surface_to_device = pattern->base.matrix;
- cairo_matrix_invert (&surface_to_device);
- _cairo_matrix_transform_bounding_box (&surface_to_device,
+ double x2 = surface->width, y2 = surface->height;
+ _cairo_matrix_transform_bounding_box (&pattern->base.matrix,
&x1, &y1, &x2, &y2,
NULL);
+
/* Rather than computing precise bounds of the union, just
* add the surface extents unconditionally. We only
* required an answer that's large enough, we don't really
- * care if it's not as tight as possible. */
- x1 = MAX (fabs(x1), fabs(x2)) + surface_extents.width;
- y1 = MAX (fabs(y1), fabs(y2)) + surface_extents.height;
- /* Similarly, don't bother computing the square root to
- * determine the length of the final diagonal. */
- xstep = ystep = _cairo_lround (ceil (x1 + y1));
+ * care if it's not as tight as possible.*/
+ xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
+ image->width + image->height);
}
break;
case CAIRO_EXTEND_REPEAT:
@@ -991,8 +985,8 @@ emit_surface_pattern (cairo_pdf_surface_t *surface,
stream = _cairo_pdf_surface_open_stream (surface,
FALSE,
" /BBox [0 0 %d %d]\r\n"
- " /XStep %d\r\n"
- " /YStep %d\r\n"
+ " /XStep %f\r\n"
+ " /YStep %f\r\n"
" /PatternType 1\r\n"
" /TilingType 1\r\n"
" /PaintType 1\r\n"
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index b55900c4..ac073956 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1704,7 +1704,7 @@ emit_surface_pattern (cairo_ps_surface_t *surface,
cairo_surface_pattern_t *pattern)
{
double bbox_width, bbox_height;
- int xstep, ystep;
+ double xstep, ystep;
cairo_matrix_t inverse = pattern->base.matrix;
cairo_matrix_invert (&inverse);
@@ -1732,22 +1732,35 @@ emit_surface_pattern (cairo_ps_surface_t *surface,
bbox_width = image->width;
bbox_height = image->height;
- /* In PostScript, (as far as I can tell), all patterns are
- * repeating. So we support cairo's EXTEND_NONE semantics by
- * setting the repeat step size to the larger of the image size
- * and the extents of the destination surface. That way we
- * guarantee the pattern will not repeat.
- */
switch (pattern->base.extend) {
case CAIRO_EXTEND_NONE:
- /* XXX We may need to update this to something like the code
- * that is in PDF. The point is, xstep/ystep are in pattern
- * space, not device space, so surface->width/height do not
- * make much sense. But most of the time patterns scale up,
- * not down, so this is less of a problem. */
- xstep = MAX (image->width, surface->width);
- ystep = MAX (image->height, surface->height);
+ {
+ /* In PS/PDF, (as far as I can tell), all patterns are
+ * repeating. So we support cairo's EXTEND_NONE semantics
+ * by setting the repeat step size to a size large enough
+ * to guarantee that no more than a single occurrence will
+ * be visible.
+ *
+ * First, map the surface extents into pattern space (since
+ * xstep and ystep are in pattern space). Then use an upper
+ * bound on the length of the diagonal of the pattern image
+ * and the surface as repeat size. This guarantees to never
+ * repeat visibly.
+ */
+ double x1 = 0.0, y1 = 0.0;
+ double x2 = surface->width, y2 = surface->height;
+ _cairo_matrix_transform_bounding_box (&pattern->base.matrix,
+ &x1, &y1, &x2, &y2,
+ NULL);
+
+ /* Rather than computing precise bounds of the union, just
+ * add the surface extents unconditionally. We only
+ * required an answer that's large enough, we don't really
+ * care if it's not as tight as possible.*/
+ xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
+ image->width + image->height);
break;
+ }
case CAIRO_EXTEND_REPEAT:
case CAIRO_EXTEND_REFLECT:
xstep = image->width;
@@ -1773,7 +1786,7 @@ emit_surface_pattern (cairo_ps_surface_t *surface,
" /BBox [0 0 %f %f]\n",
bbox_width, bbox_height);
_cairo_output_stream_printf (surface->stream,
- " /XStep %d /YStep %d\n",
+ " /XStep %f /YStep %f\n",
xstep, ystep);
_cairo_output_stream_printf (surface->stream,
" /PaintProc { MyPattern } bind\n"