summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2019-10-04 10:59:53 +0000
committerTavmjong Bah <tavmjong@free.fr>2019-10-04 10:59:53 +0000
commitb92592ab9ee056f0d1dc60727524d6f07f152f2d (patch)
tree03ae49c74a1622e8b14ce3ca2dbe92afbdf9f48c /src/display
parentAdd minor comments to file. (diff)
downloadinkscape-b92592ab9ee056f0d1dc60727524d6f07f152f2d.tar.gz
inkscape-b92592ab9ee056f0d1dc60727524d6f07f152f2d.zip
Fix rendering of hatches when hatching "overflow" tile.
Fix for https://gitlab.com/inkscape/inkscape/issues/309
Diffstat (limited to 'src/display')
-rw-r--r--src/display/drawing-item.cpp49
-rw-r--r--src/display/drawing-pattern.cpp9
2 files changed, 42 insertions, 16 deletions
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp
index 757a973fe..972a2bdc0 100644
--- a/src/display/drawing-item.cpp
+++ b/src/display/drawing-item.cpp
@@ -712,11 +712,18 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
bool render_filters = _drawing.renderFilters();
// stop_at is handled in DrawingGroup, but this check is required to handle the case
// where a filtered item with background-accessing filter has enable-background: new
- if (this == stop_at) return RENDER_STOP;
+ if (this == stop_at) {
+ return RENDER_STOP;
+ }
// If we are invisible, return immediately
- if (!_visible) return RENDER_OK;
- if (_ctm.isSingular(1e-18)) return RENDER_OK;
+ if (!_visible) {
+ return RENDER_OK;
+ }
+
+ if (_ctm.isSingular(1e-18)) {
+ return RENDER_OK;
+ }
// TODO convert outline rendering to a separate virtual function
if (outline) {
@@ -726,7 +733,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
// carea is the area to paint
Geom::OptIntRect carea = Geom::intersect(area, _drawbox);
-
+
// expand render on filtered items
Geom::OptIntRect cl = _cacheRect();
if (_filter != nullptr && render_filters && cl) {
@@ -734,7 +741,9 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
carea = cl;
}
- if (!carea) return RENDER_OK;
+ if (!carea) {
+ return RENDER_OK;
+ }
// Device scale for HiDPI screens (typically 1 or 2)
int device_scale = dc.surface()->device_scale();
@@ -756,14 +765,17 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
g_assert_not_reached();
}
- // render from cache if possible
- if (_cached) {
+ // Render from cache if possible
+ // Bypass in case of pattern, see below.
+ if (_cached && flags & ~RENDER_BYPASS_CACHE) {
if (_cache) {
_cache->prepare();
set_cairo_blend_operator( dc, _mix_blend_mode );
_cache->paintFromCache(dc, carea);
- if (!carea) return RENDER_OK;
+ if (!carea) {
+ return RENDER_OK;
+ }
} else {
// There is no cache. This could be because caching of this item
// was just turned on after the last update phase, or because
@@ -783,11 +795,11 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
bool needs_opacity = (_opacity < 0.995);
// this item needs an intermediate rendering if:
- nir |= (_clip != nullptr); // 1. it has a clipping path
- nir |= (_mask != nullptr); // 2. it has a mask
- nir |= (_filter != nullptr && render_filters); // 3. it has a filter
- nir |= needs_opacity; // 4. it is non-opaque
- nir |= (_cache != nullptr); // 5. it is cached
+ nir |= (_clip != nullptr); // 1. it has a clipping path
+ nir |= (_mask != nullptr); // 2. it has a mask
+ nir |= (_filter != nullptr && render_filters); // 3. it has a filter
+ nir |= needs_opacity; // 4. it is non-opaque
+ nir |= (_cache != nullptr); // 5. it is to be cached
nir |= (_mix_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal
nir |= (_isolation == SP_CSS_ISOLATION_ISOLATE); // 7. Explicit isolatiom
@@ -825,6 +837,17 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
DrawingSurface intermediate(*iarea, device_scale);
DrawingContext ict(intermediate);
+
+ // This path fails for patterns/hatches when stepping the pattern to handle overflows.
+ // The offsets are applied to drawing context (dc) but they are not copied to the
+ // intermediate context. Something like this is needed:
+ // Copy cairo matrix from dc to intermediate, needed for patterns/hatches
+ // cairo_matrix_t cairo_matrix;
+ // cairo_get_matrix(dc.raw(), &cairo_matrix);
+ // cairo_set_matrix(ict.raw(), &cairo_matrix);
+ // For the moment we disable caching for patterns,
+ // see https://gitlab.com/inkscape/inkscape/issues/309
+
unsigned render_result = RENDER_OK;
// 1. Render clipping path with alpha = opacity.
diff --git a/src/display/drawing-pattern.cpp b/src/display/drawing-pattern.cpp
index 15bdc6139..90bad039b 100644
--- a/src/display/drawing-pattern.cpp
+++ b/src/display/drawing-pattern.cpp
@@ -111,15 +111,18 @@ DrawingPattern::renderPattern(float opacity) {
Geom::Affine idt = pattern_surface.drawingTransform().inverse();
Geom::Affine initial_transform = idt * _overflow_initial_transform * dt;
Geom::Affine step_transform = idt * _overflow_step_transform * dt;
-
dc.transform(initial_transform);
for (int i = 0; i < _overflow_steps; i++) {
- render(dc, one_tile, RENDER_DEFAULT);
+ // render() fails to handle transforms applied here when using cache.
+ render(dc, one_tile, RENDER_BYPASS_CACHE);
dc.transform(step_transform);
+ // cairo_surface_t* raw = pattern_surface.raw();
+ // std::string filename = "drawing-pattern" + std::to_string(i) + ".png";
+ // cairo_surface_write_to_png( pattern_surface.raw(), filename.c_str() );
}
}
- //Uncomment to debug
+ // Uncomment to debug
// cairo_surface_t* raw = pattern_surface.raw();
// std::cout << " cairo_surface (sp-pattern): "
// << " width: " << cairo_image_surface_get_width( raw )