summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'src/display')
-rw-r--r--src/display/cairo-utils.cpp123
-rw-r--r--src/display/cairo-utils.h3
-rw-r--r--src/display/drawing-context.h1
-rw-r--r--src/display/drawing-group.cpp82
-rw-r--r--src/display/drawing-item.cpp88
-rw-r--r--src/display/drawing-item.h6
-rw-r--r--src/display/sp-canvas.cpp2
7 files changed, 209 insertions, 96 deletions
diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp
index d3ca85f7e..f560b9f19 100644
--- a/src/display/cairo-utils.cpp
+++ b/src/display/cairo-utils.cpp
@@ -1252,6 +1252,129 @@ private:
/* None */
};
+unsigned ink_cairo_operator_to_css_blend(cairo_operator_t cairo_operator)
+{
+ // All of the blend modes are implemented in Cairo as of 1.10.
+ // For a detailed description, see:
+ // http://cairographics.org/operators/
+ unsigned res = SP_CSS_BLEND_NORMAL;
+ switch (cairo_operator) {
+ case CAIRO_OPERATOR_MULTIPLY:
+ res = SP_CSS_BLEND_MULTIPLY;
+ break;
+ case CAIRO_OPERATOR_SCREEN:
+ res = SP_CSS_BLEND_SCREEN;
+ break;
+ case CAIRO_OPERATOR_DARKEN:
+ res = SP_CSS_BLEND_DARKEN;
+ break;
+ case CAIRO_OPERATOR_LIGHTEN:
+ res = SP_CSS_BLEND_LIGHTEN;
+ break;
+ case CAIRO_OPERATOR_OVERLAY:
+ res = SP_CSS_BLEND_OVERLAY;
+ break;
+ case CAIRO_OPERATOR_COLOR_DODGE:
+ res = SP_CSS_BLEND_COLORDODGE;
+ break;
+ case CAIRO_OPERATOR_COLOR_BURN:
+ res = SP_CSS_BLEND_COLORBURN;
+ break;
+ case CAIRO_OPERATOR_HARD_LIGHT:
+ res = SP_CSS_BLEND_HARDLIGHT;
+ break;
+ case CAIRO_OPERATOR_SOFT_LIGHT:
+ res = SP_CSS_BLEND_SOFTLIGHT;
+ break;
+ case CAIRO_OPERATOR_DIFFERENCE:
+ res = SP_CSS_BLEND_DIFFERENCE;
+ break;
+ case CAIRO_OPERATOR_EXCLUSION:
+ res = SP_CSS_BLEND_EXCLUSION;
+ break;
+ case CAIRO_OPERATOR_HSL_HUE:
+ res = SP_CSS_BLEND_HUE;
+ break;
+ case CAIRO_OPERATOR_HSL_SATURATION:
+ res = SP_CSS_BLEND_SATURATION;
+ break;
+ case CAIRO_OPERATOR_HSL_COLOR:
+ res = SP_CSS_BLEND_COLOR;
+ break;
+ case CAIRO_OPERATOR_HSL_LUMINOSITY:
+ res = SP_CSS_BLEND_LUMINOSITY;
+ break;
+ case CAIRO_OPERATOR_OVER:
+ default:
+ res = SP_CSS_BLEND_NORMAL;
+ break;
+ }
+ return res;
+}
+
+cairo_operator_t ink_css_blend_to_cairo_operator(unsigned css_blend)
+{
+ // All of the blend modes are implemented in Cairo as of 1.10.
+ // For a detailed description, see:
+ // http://cairographics.org/operators/
+
+ cairo_operator_t res = CAIRO_OPERATOR_OVER;
+ switch (css_blend) {
+ case SP_CSS_BLEND_MULTIPLY:
+ res = CAIRO_OPERATOR_MULTIPLY;
+ break;
+ case SP_CSS_BLEND_SCREEN:
+ res = CAIRO_OPERATOR_SCREEN;
+ break;
+ case SP_CSS_BLEND_DARKEN:
+ res = CAIRO_OPERATOR_DARKEN;
+ break;
+ case SP_CSS_BLEND_LIGHTEN:
+ res = CAIRO_OPERATOR_LIGHTEN;
+ break;
+ case SP_CSS_BLEND_OVERLAY:
+ res = CAIRO_OPERATOR_OVERLAY;
+ break;
+ case SP_CSS_BLEND_COLORDODGE:
+ res = CAIRO_OPERATOR_COLOR_DODGE;
+ break;
+ case SP_CSS_BLEND_COLORBURN:
+ res = CAIRO_OPERATOR_COLOR_BURN;
+ break;
+ case SP_CSS_BLEND_HARDLIGHT:
+ res = CAIRO_OPERATOR_HARD_LIGHT;
+ break;
+ case SP_CSS_BLEND_SOFTLIGHT:
+ res = CAIRO_OPERATOR_SOFT_LIGHT;
+ break;
+ case SP_CSS_BLEND_DIFFERENCE:
+ res = CAIRO_OPERATOR_DIFFERENCE;
+ break;
+ case SP_CSS_BLEND_EXCLUSION:
+ res = CAIRO_OPERATOR_EXCLUSION;
+ break;
+ case SP_CSS_BLEND_HUE:
+ res = CAIRO_OPERATOR_HSL_HUE;
+ break;
+ case SP_CSS_BLEND_SATURATION:
+ res = CAIRO_OPERATOR_HSL_SATURATION;
+ break;
+ case SP_CSS_BLEND_COLOR:
+ res = CAIRO_OPERATOR_HSL_COLOR;
+ break;
+ case SP_CSS_BLEND_LUMINOSITY:
+ res = CAIRO_OPERATOR_HSL_LUMINOSITY;
+ break;
+ case SP_CSS_BLEND_NORMAL:
+ default:
+ res = CAIRO_OPERATOR_OVER;
+ break;
+ }
+ return res;
+}
+
+
+
int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface)
{
cairo_surface_flush(surface);
diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h
index fbcee5413..36800f699 100644
--- a/src/display/cairo-utils.h
+++ b/src/display/cairo-utils.h
@@ -156,7 +156,8 @@ void ink_cairo_pattern_set_matrix(cairo_pattern_t *cp, Geom::Affine const &m);
void ink_matrix_to_2geom(Geom::Affine &, cairo_matrix_t const &);
void ink_matrix_to_cairo(cairo_matrix_t &, Geom::Affine const &);
-
+cairo_operator_t ink_css_blend_to_cairo_operator(unsigned blend_mode);
+unsigned ink_cairo_operator_to_css_blend(cairo_operator_t cairo_operator);
cairo_surface_t *ink_cairo_surface_copy(cairo_surface_t *s);
cairo_surface_t *ink_cairo_surface_create_identical(cairo_surface_t *s);
cairo_surface_t *ink_cairo_surface_create_same_size(cairo_surface_t *s, cairo_content_t c);
diff --git a/src/display/drawing-context.h b/src/display/drawing-context.h
index 1095fa1a3..aedb87ea2 100644
--- a/src/display/drawing-context.h
+++ b/src/display/drawing-context.h
@@ -101,6 +101,7 @@ public:
void setMiterLimit(double miter) { cairo_set_miter_limit(_ct, miter); }
void setFillRule(cairo_fill_rule_t rule) { cairo_set_fill_rule(_ct, rule); }
void setOperator(cairo_operator_t op) { cairo_set_operator(_ct, op); }
+ cairo_operator_t getOperator() { return cairo_get_operator(_ct); }
void setTolerance(double tol) { cairo_set_tolerance(_ct, tol); }
void setSource(cairo_pattern_t *source) { cairo_set_source(_ct, source); }
void setSource(cairo_surface_t *surface, double x, double y) {
diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp
index 0d6a2edfc..4fe84d7eb 100644
--- a/src/display/drawing-group.cpp
+++ b/src/display/drawing-group.cpp
@@ -10,10 +10,13 @@
* Released under GNU GPL v2+, read the file 'COPYING' for more information.
*/
-#include "display/drawing.h"
-#include "display/drawing-item.h"
#include "display/drawing-group.h"
-
+#include "display/cairo-utils.h"
+#include "display/drawing-context.h"
+#include "display/drawing-item.h"
+#include "display/drawing-surface.h"
+#include "display/drawing.h"
+#include "style.h"
namespace Inkscape {
@@ -90,29 +93,70 @@ DrawingGroup::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u
unsigned
DrawingGroup::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at)
{
- if (stop_at == nullptr) {
- // normal rendering
- for (auto & i : _children) {
- i.setAntialiasing(_antialias);
- i.render(dc, area, flags, stop_at);
+ if (!parent() || (_isolation == SP_CSS_ISOLATION_ISOLATE && !_mix_blend_mode)) {
+ int device_scale = dc.surface()->device_scale();
+ DrawingSurface intermediate(area, device_scale);
+ DrawingContext ict(intermediate);
+ ict.setOperator(CAIRO_OPERATOR_OVER);
+ if (parent()) {
+ flags = flags | RENDER_FILTER_BACKGROUND;
}
- } else {
- // background rendering
- for (auto & i : _children) {
- if (&i == stop_at) return RENDER_OK; // do not render the stop_at item at all
- if (i.isAncestorOf(stop_at)) {
- // render its ancestors without masks, opacity or filters
+ if (stop_at == nullptr) {
+ // normal rendering
+ for (auto &i : _children) {
i.setAntialiasing(_antialias);
- i.render(dc, area, flags | RENDER_FILTER_BACKGROUND, stop_at);
- // stop further rendering
- return RENDER_OK;
- } else {
+ i.render(ict, area, flags, stop_at);
+ }
+ } else {
+ // background rendering
+ for (auto &i : _children) {
+ if (&i == stop_at)
+ return RENDER_OK; // do not render the stop_at item at all
+ if (i.isAncestorOf(stop_at)) {
+ // render its ancestors without masks, opacity or filters
+ i.setAntialiasing(_antialias);
+ i.render(ict, area, flags | RENDER_FILTER_BACKGROUND, stop_at);
+ break;
+ } else {
+ i.setAntialiasing(_antialias);
+ i.render(ict, area, flags, stop_at);
+ }
+ }
+ }
+ dc.rectangle(area);
+ dc.setSource(&intermediate);
+ dc.setOperator(CAIRO_OPERATOR_OVER);
+ dc.fill();
+ return RENDER_OK;
+ } else {
+ /* cairo_operator_t current_op = CAIRO_OPERATOR_OVER;
+ if (parent()->_isolation == SP_CSS_ISOLATION_ISOLATE && !parent()->_mix_blend_mode) {
+ dc.setOperator(CAIRO_OPERATOR_OVER);
+ } */
+ if (stop_at == nullptr) {
+ // normal rendering
+ for (auto &i : _children) {
i.setAntialiasing(_antialias);
i.render(dc, area, flags, stop_at);
}
+ } else {
+ // background rendering
+ for (auto &i : _children) {
+ if (&i == stop_at)
+ return RENDER_OK; // do not render the stop_at item at all
+ if (i.isAncestorOf(stop_at)) {
+ // render its ancestors without masks, opacity or filters
+ i.setAntialiasing(_antialias);
+ i.render(dc, area, flags | RENDER_FILTER_BACKGROUND, stop_at);
+ break;
+ } else {
+ i.setAntialiasing(_antialias);
+ i.render(dc, area, flags, stop_at);
+ }
+ }
}
+ return RENDER_OK;
}
- return RENDER_OK;
}
void
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp
index 81d01846e..52939e301 100644
--- a/src/display/drawing-item.cpp
+++ b/src/display/drawing-item.cpp
@@ -28,65 +28,6 @@
#include "object/sp-item.h"
namespace Inkscape {
-
-void set_cairo_blend_operator( DrawingContext &dc, unsigned blend_mode ) {
-
- // All of the blend modes are implemented in Cairo as of 1.10.
- // For a detailed description, see:
- // http://cairographics.org/operators/
- switch (blend_mode) {
- case SP_CSS_BLEND_MULTIPLY:
- dc.setOperator(CAIRO_OPERATOR_MULTIPLY);
- break;
- case SP_CSS_BLEND_SCREEN:
- dc.setOperator(CAIRO_OPERATOR_SCREEN);
- break;
- case SP_CSS_BLEND_DARKEN:
- dc.setOperator(CAIRO_OPERATOR_DARKEN);
- break;
- case SP_CSS_BLEND_LIGHTEN:
- dc.setOperator(CAIRO_OPERATOR_LIGHTEN);
- break;
- case SP_CSS_BLEND_OVERLAY:
- dc.setOperator(CAIRO_OPERATOR_OVERLAY);
- break;
- case SP_CSS_BLEND_COLORDODGE:
- dc.setOperator(CAIRO_OPERATOR_COLOR_DODGE);
- break;
- case SP_CSS_BLEND_COLORBURN:
- dc.setOperator(CAIRO_OPERATOR_COLOR_BURN);
- break;
- case SP_CSS_BLEND_HARDLIGHT:
- dc.setOperator(CAIRO_OPERATOR_HARD_LIGHT);
- break;
- case SP_CSS_BLEND_SOFTLIGHT:
- dc.setOperator(CAIRO_OPERATOR_SOFT_LIGHT);
- break;
- case SP_CSS_BLEND_DIFFERENCE:
- dc.setOperator(CAIRO_OPERATOR_DIFFERENCE);
- break;
- case SP_CSS_BLEND_EXCLUSION:
- dc.setOperator(CAIRO_OPERATOR_EXCLUSION);
- break;
- case SP_CSS_BLEND_HUE:
- dc.setOperator(CAIRO_OPERATOR_HSL_HUE);
- break;
- case SP_CSS_BLEND_SATURATION:
- dc.setOperator(CAIRO_OPERATOR_HSL_SATURATION);
- break;
- case SP_CSS_BLEND_COLOR:
- dc.setOperator(CAIRO_OPERATOR_HSL_COLOR);
- break;
- case SP_CSS_BLEND_LUMINOSITY:
- dc.setOperator(CAIRO_OPERATOR_HSL_LUMINOSITY);
- break;
- case SP_CSS_BLEND_NORMAL:
- default:
- dc.setOperator(CAIRO_OPERATOR_OVER);
- break;
- }
-}
-
/**
* @class DrawingItem
* SVG drawing item for display.
@@ -629,7 +570,6 @@ DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigne
}
}
}
-
if (to_update & STATE_CACHE) {
// Update cache score for this item
if (_has_cache_iterator) {
@@ -773,8 +713,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
if (_cached && !(flags & RENDER_BYPASS_CACHE)) {
if (_cache) {
_cache->prepare();
- set_cairo_blend_operator( dc, _mix_blend_mode );
-
+ dc.setOperator(ink_css_blend_to_cairo_operator(_mix_blend_mode));
_cache->paintFromCache(dc, carea);
if (!carea) {
return RENDER_OK;
@@ -798,13 +737,13 @@ 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 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
+ 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
+ // Isolation is handled by the drawing-group
/* How the rendering is done.
*
@@ -817,12 +756,12 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
* the entire intermediate surface is painted with alpha corresponding
* to the opacity value.
*/
-
// Short-circuit the simple case.
// We also use this path for filter background rendering, because masking, clipping,
// filters and opacity do not apply when rendering the ancestors of the filtered
// element
if ((flags & RENDER_FILTER_BACKGROUND) || !needs_intermediate_rendering) {
+ dc.setOperator(ink_css_blend_to_cairo_operator(_mix_blend_mode));
return _renderItem(dc, *carea, flags & ~RENDER_FILTER_BACKGROUND, stop_at);
}
@@ -925,11 +864,16 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag
cachect.fill();
_cache->markClean(*carea);
}
+
dc.rectangle(*carea);
dc.setSource(&intermediate);
- set_cairo_blend_operator( dc, _mix_blend_mode );
+ // 7. Render blend mode
+ dc.setOperator(ink_css_blend_to_cairo_operator(_mix_blend_mode));
dc.fill();
dc.setSource(0,0,0,0);
+ // Web isolation only works if parent doesnt have transform
+
+
// the call above is to clear a ref on the intermediate surface held by dc
return render_result;
@@ -1115,7 +1059,7 @@ DrawingItem::_markForRendering()
bkg_root = i;
}
}
-
+
if (bkg_root) {
bkg_root->_invalidateFilterBackground(*dirty);
}
diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h
index f0107cdc7..809d6ae72 100644
--- a/src/display/drawing-item.h
+++ b/src/display/drawing-item.h
@@ -94,6 +94,9 @@ public:
DrawingItem(Drawing &drawing);
virtual ~DrawingItem();
+ unsigned _isolation : 1;
+ unsigned _mix_blend_mode : 4;
+
Geom::OptIntRect geometricBounds() const { return _bbox; }
Geom::OptIntRect visualBounds() const { return _drawbox; }
Geom::OptRect itemBounds() const { return _item_bbox; }
@@ -227,9 +230,6 @@ protected:
/// otherwise the group is returned
unsigned _antialias : 2; ///< antialiasing level (NONE/FAST/GOOD(DEFAULT)/BEST)
- unsigned _isolation : 1;
- unsigned _mix_blend_mode : 4;
-
friend class Drawing;
};
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp
index b33dd20b6..216c8437f 100644
--- a/src/display/sp-canvas.cpp
+++ b/src/display/sp-canvas.cpp
@@ -1838,7 +1838,6 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect
cairo_surface_set_device_scale(imgs, _device_scale, _device_scale);
buf.ct = cairo_create(imgs);
-
cairo_save(buf.ct);
cairo_translate(buf.ct, -paint_rect.left(), -paint_rect.top());
cairo_set_source(buf.ct, _background);
@@ -1850,6 +1849,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect
if (_root->visible) {
SP_CANVAS_ITEM_GET_CLASS(_root)->render(_root, &buf);
}
+
// cairo_surface_write_to_png( imgs, "debug2.png" );
// output to X