summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6b7fcc6)
raw | patch | inline | side by side (parent: 6b7fcc6)
author | tavmjong <tavmjong@users.sourceforge.net> | |
Sun, 31 Aug 2008 12:15:47 +0000 (12:15 +0000) | ||
committer | tavmjong <tavmjong@users.sourceforge.net> | |
Sun, 31 Aug 2008 12:15:47 +0000 (12:15 +0000) |
Avoid pattern size change due to rounding errors in ceil().
src/extension/internal/cairo-render-context.cpp | patch | blob | history |
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp
index 747054c7f7ffc3d8a70e61092d4509d449deebc0..09d4fc74c2b9a83cca03bb55d4cc8be1118b982d 100644 (file)
@@ -962,8 +962,10 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
pcs2dev[3] = pbox->y1 - pbox->y0;
}
- // calculate the size of the surface which has to be created
- // the scaling needs to be taken into account in the ctm after the pattern transformation
+ // Calculate the size of the surface which has to be created so that the pattern resolution
+ // matches the output resolution (i.e., if the pattern is scaled up by a factor of two,
+ // the surface width should be scaled by a factor of two).
+ // The scaling needs to be taken into account in the ctm after the pattern transformation.
Geom::Matrix temp;
temp = pattern_transform * _state->transform;
double width_scaler = sqrt(temp[0] * temp[0] + temp[2] * temp[2]);
@@ -974,8 +976,10 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
width_scaler *= 1.25;
height_scaler *= 1.25;
}
- double surface_width = ceil(bbox_width_scaler * width_scaler * width);
- double surface_height = ceil(bbox_height_scaler * height_scaler * height);
+ // Cairo requires an integer pattern surface width/height.
+ // Subtract 0.5 to prevent small rounding errors from increasing pattern size by one pixel.
+ double surface_width = ceil(bbox_width_scaler * width_scaler * width - 0.5);
+ double surface_height = ceil(bbox_height_scaler * height_scaler * height - 0.5);
TRACE(("surface size: %f x %f\n", surface_width, surface_height));
// create new rendering context
CairoRenderContext *pattern_ctx = cloneMe(surface_width, surface_height);
@@ -986,8 +990,8 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
double scale_height = surface_height / (bbox_height_scaler * height);
if (scale_width != 1.0 || scale_height != 1.0 || _vector_based_target) {
TRACE(("needed to scale with %f %f\n", scale_width, scale_height));
- pcs2dev *= Geom::Scale(1.0 / scale_width, 1.0 / scale_height);
- ps2user *= Geom::Scale(scale_width, scale_height);
+ pcs2dev *= Geom::Scale(scale_width, scale_height);
+ ps2user *= Geom::Scale(1.0 / scale_width, 1.0 / scale_height);
}
pattern_ctx->setTransform(&pcs2dev);