diff options
author | Behdad Esfahbod <behdad@behdad.org> | 2007-02-27 18:47:47 -0500 |
---|---|---|
committer | Behdad Esfahbod <behdad@behdad.org> | 2007-02-27 18:47:47 -0500 |
commit | e2ce27db302a185e6e80ead699c01e43921939ca (patch) | |
tree | 667cb20f735703ec01db43ffbdb169727d5bb92f | |
parent | de0a6522b00822305fa5a0e32c4821628425ebdc (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.c | 36 | ||||
-rw-r--r-- | src/cairo-ps-surface.c | 43 |
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" |