diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-02-19 10:48:41 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-02-19 10:48:41 +0000 |
| commit | f15ac06ffd9cc8dbb098b18a6b273b32fc904fc9 (patch) | |
| tree | 482bc967d7e637d3f8817aa2074362a461465603 /src/display | |
| parent | update to trunk (diff) | |
| parent | Add SVG2 property 'paint-order'. (diff) | |
| download | inkscape-f15ac06ffd9cc8dbb098b18a6b273b32fc904fc9.tar.gz inkscape-f15ac06ffd9cc8dbb098b18a6b273b32fc904fc9.zip | |
update to trunk
(bzr r11950.1.254)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/drawing-shape.cpp | 132 | ||||
| -rw-r--r-- | src/display/drawing-shape.h | 7 | ||||
| -rw-r--r-- | src/display/drawing-text.cpp | 19 | ||||
| -rw-r--r-- | src/display/nr-style.cpp | 26 | ||||
| -rw-r--r-- | src/display/nr-style.h | 12 |
5 files changed, 166 insertions, 30 deletions
diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index f99f9442f..92d71fad3 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -149,6 +149,51 @@ DrawingShape::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u return STATE_ALL; } +#ifdef WITH_SVG2 +void +DrawingShape::_renderFill(DrawingContext &dc) +{ + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); + + bool has_fill = _nrstyle.prepareFill(dc, _item_bbox); + + if( has_fill ) { + dc.path(_curve->get_pathvector()); + _nrstyle.applyFill(dc); + dc.fillPreserve(); + dc.newPath(); // clear path + } +} + +void +DrawingShape::_renderStroke(DrawingContext &dc) +{ + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); + + bool has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); + has_stroke &= (_nrstyle.stroke_width != 0); + + if( has_stroke ) { + // TODO: remove segments outside of bbox when no dashes present + dc.path(_curve->get_pathvector()); + _nrstyle.applyStroke(dc); + dc.strokePreserve(); + dc.newPath(); // clear path + } +} +#endif + +void +DrawingShape::_renderMarkers(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at) +{ + // marker rendering + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + i->render(dc, area, flags, stop_at); + } +} + unsigned DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at) { @@ -160,6 +205,7 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne if (outline) { guint32 rgba = _drawing.outlinecolor; + // paint-order doesn't matter { Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); dc.path(_curve->get_pathvector()); @@ -170,39 +216,67 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne dc.setTolerance(0.5); dc.stroke(); } - } else { - bool has_stroke, has_fill; - // we assume the context has no path - Inkscape::DrawingContext::Save save(dc); - dc.transform(_ctm); - - // update fill and stroke paints. - // this cannot be done during nr_arena_shape_update, because we need a Cairo context - // to render svg:pattern - has_fill = _nrstyle.prepareFill(dc, _item_bbox); - has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); - has_stroke &= (_nrstyle.stroke_width != 0); - - if (has_fill || has_stroke) { - // TODO: remove segments outside of bbox when no dashes present - dc.path(_curve->get_pathvector()); - if (has_fill) { - _nrstyle.applyFill(dc); - dc.fillPreserve(); - } - if (has_stroke) { - _nrstyle.applyStroke(dc); - dc.strokePreserve(); - } - dc.newPath(); // clear path - } // has fill or stroke pattern + + _renderMarkers(dc, area, flags, stop_at); + return RENDER_OK; + } - // marker rendering - for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { - i->render(dc, area, flags, stop_at); +#ifdef WITH_SVG2 + if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL ) { + // This is the most common case, special case so we don't call get_pathvector(), etc. twice +#endif + { + // we assume the context has no path + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); + + // update fill and stroke paints. + // this cannot be done during nr_arena_shape_update, because we need a Cairo context + // to render svg:pattern + bool has_fill = _nrstyle.prepareFill(dc, _item_bbox); + bool has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); + has_stroke &= (_nrstyle.stroke_width != 0); + + if (has_fill || has_stroke) { + // TODO: remove segments outside of bbox when no dashes present + dc.path(_curve->get_pathvector()); + if (has_fill) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } + if (has_stroke) { + _nrstyle.applyStroke(dc); + dc.strokePreserve(); + } + dc.newPath(); // clear path + } // has fill or stroke pattern + } + _renderMarkers(dc, area, flags, stop_at); + return RENDER_OK; + +#ifdef WITH_SVG2 + } + + // Handle different paint orders + for (unsigned i = 0; i < NRStyle::PAINT_ORDER_LAYERS; ++i) { + switch (_nrstyle.paint_order_layer[i]) { + case NRStyle::PAINT_ORDER_FILL: + _renderFill(dc); + break; + case NRStyle::PAINT_ORDER_STROKE: + _renderStroke(dc); + break; + case NRStyle::PAINT_ORDER_MARKER: + _renderMarkers(dc, area, flags, stop_at); + break; + default: + // PAINT_ORDER_AUTO Should not happen + break; + } } return RENDER_OK; +#endif } void DrawingShape::_clipItem(DrawingContext &dc, Geom::IntRect const & /*area*/) diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h index 47b9e807e..405c789e0 100644 --- a/src/display/drawing-shape.h +++ b/src/display/drawing-shape.h @@ -39,6 +39,13 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); +#ifdef WITH_SVG2 + void _renderFill(DrawingContext &dc); + void _renderStroke(DrawingContext &dc); +#endif + void _renderMarkers(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, + DrawingItem *stop_at); + SPCurve *_curve; SPStyle *_style; NRStyle _nrstyle; diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index f5a0f0af5..a280e221a 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -450,7 +450,20 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are // we need to apply this object's ctm again Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); + +#ifdef WITH_SVG2 + // Text doesn't have markers, we can do paint-order quick and dirty. + bool fill_first = false; + if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || + _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_FILL || + _nrstyle.paint_order_layer[2] == NRStyle::PAINT_ORDER_STROKE ) { + fill_first = true; + } // Won't get "stroke fill stroke" but that isn't 'valid' + + if (has_fill && fill_first) { +#else if (has_fill) { +#endif _nrstyle.applyFill(dc); dc.fillPreserve(); } @@ -458,6 +471,12 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are _nrstyle.applyStroke(dc); dc.strokePreserve(); } +#ifdef WITH_SVG2 + if (has_fill && !fill_first) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } +#endif dc.newPath(); // clear path // draw text decoration diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 403b139e0..570ccd31e 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -68,7 +68,11 @@ NRStyle::NRStyle() , line_through_thickness(0) , line_through_position(0) , font_size(0) -{} +{ +#ifdef WITH_SVG2 + paint_order_layer[0] = PAINT_ORDER_NORMAL; +#endif +} NRStyle::~NRStyle() { @@ -160,6 +164,26 @@ void NRStyle::set(SPStyle *style) dash = NULL; } + +#ifdef WITH_SVG2 + for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i) { + switch (style->paint_order.layer[i]) { + case SP_CSS_PAINT_ORDER_NORMAL: + paint_order_layer[i]=PAINT_ORDER_NORMAL; + break; + case SP_CSS_PAINT_ORDER_FILL: + paint_order_layer[i]=PAINT_ORDER_FILL; + break; + case SP_CSS_PAINT_ORDER_STROKE: + paint_order_layer[i]=PAINT_ORDER_STROKE; + break; + case SP_CSS_PAINT_ORDER_MARKER: + paint_order_layer[i]=PAINT_ORDER_MARKER; + break; + } + } +#endif + text_decoration_line = TEXT_DECORATION_LINE_CLEAR; if(style->text_decoration_line.inherit ){ text_decoration_line |= TEXT_DECORATION_LINE_INHERIT; } if(style->text_decoration_line.underline ){ text_decoration_line |= TEXT_DECORATION_LINE_UNDERLINE + TEXT_DECORATION_LINE_SET; } diff --git a/src/display/nr-style.h b/src/display/nr-style.h index e54eef547..717cda899 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -68,6 +68,18 @@ struct NRStyle { cairo_pattern_t *fill_pattern; cairo_pattern_t *stroke_pattern; +#ifdef WITH_SVG2 + enum PaintOrderType { + PAINT_ORDER_NORMAL, + PAINT_ORDER_FILL, + PAINT_ORDER_STROKE, + PAINT_ORDER_MARKER + }; + + static const size_t PAINT_ORDER_LAYERS = 3; + PaintOrderType paint_order_layer[PAINT_ORDER_LAYERS]; +#endif + #define TEXT_DECORATION_LINE_CLEAR 0x00 #define TEXT_DECORATION_LINE_SET 0x01 #define TEXT_DECORATION_LINE_INHERIT 0x02 |
