X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdisplay%2Fnr-arena-shape.cpp;h=6f38fd97d8d018d57a57af5bae793749235b0246;hb=0dc33d4ce43e0bb49c63aa53b826ec4a1ff68e28;hp=4c988be46b5153689f1461c966e6bbfbcfae99c9;hpb=e9b6af083e34e2397a8ddbe9781920733d09d151;p=inkscape.git diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 4c988be46..6f38fd97d 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -1,5 +1,3 @@ -#define __NR_ARENA_SHAPE_C__ - /* * RGBA display list system for inkscape * @@ -12,35 +10,36 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include +#include +#include +#include + #include <2geom/svg-path.h> #include <2geom/svg-path-parser.h> -#include -#include -#include -#include "display/curve.h" -#include -#include -#include -#include -#include #include <2geom/pathvector.h> #include <2geom/curves.h> -#include -#include -#include -#include +#include "display/sp-canvas.h" +#include "display/canvas-arena.h" +#include "display/nr-arena.h" +#include "display/nr-arena-shape.h" +#include "display/curve.h" +#include "libnr/nr-pixops.h" +#include "libnr/nr-blit.h" +#include "libnr/nr-convert2geom.h" +#include "livarot/Path.h" +#include "livarot/float-line.h" +#include "livarot/int-line.h" +#include "style.h" #include "inkscape-cairo.h" #include "helper/geom.h" #include "helper/geom-curves.h" #include "sp-filter.h" #include "sp-filter-reference.h" #include "display/nr-filter.h" -#include -#include +#include "preferences.h" -#include #include "svg/svg.h" -#include //int showRuns=0; void nr_pixblock_render_shape_mask_or(NRPixBlock &m,Shape* theS); @@ -229,7 +228,7 @@ nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *child, NRArena void nr_arena_shape_update_stroke(NRArenaShape *shape, NRGC* gc, NRRectL *area); void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape = false); -void nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox); +void nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::OptRect &bbox); /** * Updates the arena shape 'item' and all of its children, including the markers. @@ -237,7 +236,7 @@ void nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox); static guint nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset) { - Geom::Rect boundingbox; + Geom::OptRect boundingbox; NRArenaShape *shape = NR_ARENA_SHAPE(item); @@ -255,10 +254,14 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g if (state & NR_ARENA_ITEM_STATE_BBOX) { if (shape->curve) { boundingbox = bounds_exact_transformed(shape->curve->get_pathvector(), gc->transform); - item->bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - item->bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - item->bbox.x1 = (gint32)(boundingbox[0][1] + 1.9999F); - item->bbox.y1 = (gint32)(boundingbox[1][1] + 1.9999F); + if (boundingbox) { + item->bbox.x0 = static_cast(floor((*boundingbox)[0][0])); // Floor gives the coordinate in which the point resides + item->bbox.y0 = static_cast(floor((*boundingbox)[1][0])); + item->bbox.x1 = static_cast(ceil ((*boundingbox)[0][1])); // Ceil gives the first coordinate beyond the point + item->bbox.y1 = static_cast(ceil ((*boundingbox)[1][1])); + } else { + item->bbox = NR_RECT_L_EMPTY; + } } if (beststate & NR_ARENA_ITEM_STATE_BBOX) { for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { @@ -271,43 +274,44 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g shape->delayed_shp=true; shape->ctm = gc->transform; - boundingbox[0][0] = boundingbox[1][0] = NR_HUGE; - boundingbox[0][1] = boundingbox[1][1] = -NR_HUGE; + boundingbox = Geom::OptRect(); bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); if (shape->curve) { boundingbox = bounds_exact_transformed(shape->curve->get_pathvector(), gc->transform); - if (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE || outline) { + if (boundingbox && (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE || outline)) { float width, scale; scale = gc->transform.descrim(); width = MAX(0.125, shape->_stroke.width * scale); if ( fabs(shape->_stroke.width * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord - boundingbox.expandBy(width); + boundingbox->expandBy(width); } // those pesky miters, now float miterMax=width*shape->_stroke.mitre_limit; if ( miterMax > 0.01 ) { // grunt mode. we should compute the various miters instead (one for each point on the curve) - boundingbox.expandBy(miterMax); + boundingbox->expandBy(miterMax); } } + } + + /// \todo just write item->bbox = boundingbox + if (boundingbox) { + shape->approx_bbox.x0 = static_cast(floor((*boundingbox)[0][0])); + shape->approx_bbox.y0 = static_cast(floor((*boundingbox)[1][0])); + shape->approx_bbox.x1 = static_cast(ceil ((*boundingbox)[0][1])); + shape->approx_bbox.y1 = static_cast(ceil ((*boundingbox)[1][1])); } else { + shape->approx_bbox = NR_RECT_L_EMPTY; } - shape->approx_bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - shape->approx_bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - shape->approx_bbox.x1 = (gint32)(boundingbox[0][1] + 1.9999F); - shape->approx_bbox.y1 = (gint32)(boundingbox[1][1] + 1.9999F); if ( area && nr_rect_l_test_intersect_ptr(area, &shape->approx_bbox) ) shape->delayed_shp=false; /* Release state data */ - if (TRUE || !Geom::transform_equalp(gc->transform, shape->ctm, NR_EPSILON)) { - /* Concept test */ - if (shape->fill_shp) { - delete shape->fill_shp; - shape->fill_shp = NULL; - } + if (shape->fill_shp) { + delete shape->fill_shp; + shape->fill_shp = NULL; } if (shape->stroke_shp) { delete shape->stroke_shp; @@ -339,23 +343,28 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g nr_arena_shape_update_stroke(shape, gc, area); nr_arena_shape_update_fill(shape, gc, area); - boundingbox[0][0] = boundingbox[0][1] = boundingbox[1][0] = boundingbox[1][1] = 0.0; + boundingbox = Geom::OptRect(); nr_arena_shape_add_bboxes(shape, boundingbox); - shape->approx_bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - shape->approx_bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - shape->approx_bbox.x1 = (gint32)(boundingbox[0][1] + 1.9999F); - shape->approx_bbox.y1 = (gint32)(boundingbox[1][1] + 1.9999F); + /// \todo just write shape->approx_bbox = boundingbox + if (boundingbox) { + shape->approx_bbox.x0 = static_cast(floor((*boundingbox)[0][0])); + shape->approx_bbox.y0 = static_cast(floor((*boundingbox)[1][0])); + shape->approx_bbox.x1 = static_cast(ceil ((*boundingbox)[0][1])); + shape->approx_bbox.y1 = static_cast(ceil ((*boundingbox)[1][1])); + } else { + shape->approx_bbox = NR_RECT_L_EMPTY; + } } - if (boundingbox.isEmpty()) + if (!boundingbox) return NR_ARENA_ITEM_STATE_ALL; - item->bbox.x0 = (gint32)(boundingbox[0][0] - 1.0F); - item->bbox.y0 = (gint32)(boundingbox[1][0] - 1.0F); - item->bbox.x1 = (gint32)(boundingbox[0][1] + 1.0F); - item->bbox.y1 = (gint32)(boundingbox[1][1] + 1.0F); - nr_arena_request_render_rect(item->arena, &item->bbox); + /// \todo just write item->bbox = boundingbox + item->bbox.x0 = static_cast(floor((*boundingbox)[0][0])); + item->bbox.y0 = static_cast(floor((*boundingbox)[1][0])); + item->bbox.x1 = static_cast(ceil ((*boundingbox)[0][1])); + item->bbox.y1 = static_cast(ceil ((*boundingbox)[1][1])); item->render_opacity = TRUE; if ( shape->_fill.paint.type() == NRArenaShape::Paint::SERVER ) { @@ -442,9 +451,8 @@ void nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape) { if ((shape->_fill.paint.type() != NRArenaShape::Paint::NONE || force_shape) && -// ((shape->curve->get_length() > 2) || (SP_CURVE_BPATH(shape->curve)[1].code == NR_CURVETO)) ) { // <-- this used to be the old code, i think it has to determine that the path has a sort of 'internal region' where fill would occur has_inner_area(shape->curve->get_pathvector()) ) { - if (TRUE || !shape->fill_shp) { + Geom::Matrix cached_to_new = Geom::identity(); int isometry = 0; if ( shape->cached_fill ) { @@ -522,7 +530,6 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool fo shape->fill_shp->needEdgesSorting(); } shape->delayed_shp |= shape->cached_fpartialy; - } } } @@ -683,7 +690,7 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc, NRRectL *area) void -nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox) +nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::OptRect &bbox) { /* TODO: are these two if's mutually exclusive? ( i.e. "shape->stroke_shp <=> !shape->fill_shp" ) * if so, then this can be written much more compact ! */ @@ -715,7 +722,7 @@ nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox) // cairo outline rendering: static unsigned int -cairo_arena_shape_render_outline(cairo_t *ct, NRArenaItem *item, boost::optional area) +cairo_arena_shape_render_outline(cairo_t *ct, NRArenaItem *item, Geom::OptRect area) { NRArenaShape *shape = NR_ARENA_SHAPE(item); @@ -824,7 +831,6 @@ cairo_arena_shape_render_stroke(NRArenaItem *item, NRRectL *area, NRPixBlock *pb pb->empty = FALSE; } - /** * Renders the item. Markers are just composed into the parent buffer. */ @@ -837,6 +843,7 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock if (!shape->style) return item->state; bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); + bool print_colors_preview = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); if (outline) { // cairo outline rendering @@ -867,6 +874,7 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock } SPStyle const *style = shape->style; + if (shape->fill_shp) { NRPixBlock m; guint32 rgba; @@ -886,12 +894,18 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock if (shape->_fill.paint.type() == NRArenaShape::Paint::NONE) { // do not render fill in any way } else if (shape->_fill.paint.type() == NRArenaShape::Paint::COLOR) { + + const SPColor* fill_color = &shape->_fill.paint.color(); if ( item->render_opacity ) { - rgba = shape->_fill.paint.color().toRGBA32( shape->_fill.opacity * - SP_SCALE24_TO_FLOAT(style->opacity.value) ); + rgba = fill_color->toRGBA32( shape->_fill.opacity * + SP_SCALE24_TO_FLOAT(style->opacity.value) ); } else { - rgba = shape->_fill.paint.color().toRGBA32( shape->_fill.opacity ); + rgba = fill_color->toRGBA32( shape->_fill.opacity ); } + + if (print_colors_preview) + nr_arena_separate_color_plates(&rgba); + nr_blit_pixblock_mask_rgba32(pb, &m, rgba); pb->empty = FALSE; } else if (shape->_fill.paint.type() == NRArenaShape::Paint::SERVER) { @@ -922,14 +936,19 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock nr_pixblock_render_shape_mask_or(m, shape->stroke_shp); m.empty = FALSE; - if ( item->render_opacity ) { - rgba = shape->_stroke.paint.color().toRGBA32( shape->_stroke.opacity * - SP_SCALE24_TO_FLOAT(style->opacity.value) ); - } else { - rgba = shape->_stroke.paint.color().toRGBA32( shape->_stroke.opacity ); - } - nr_blit_pixblock_mask_rgba32(pb, &m, rgba); - pb->empty = FALSE; + const SPColor* stroke_color = &shape->_stroke.paint.color(); + if ( item->render_opacity ) { + rgba = stroke_color->toRGBA32( shape->_stroke.opacity * + SP_SCALE24_TO_FLOAT(style->opacity.value) ); + } else { + rgba = stroke_color->toRGBA32( shape->_stroke.opacity ); + } + + if (print_colors_preview) + nr_arena_separate_color_plates(&rgba); + + nr_blit_pixblock_mask_rgba32(pb, &m, rgba); + pb->empty = FALSE; nr_pixblock_release(&m); @@ -1328,7 +1347,7 @@ nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style) if (style->filter.set && style->getFilter()) { if (!shape->filter) { int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); - shape->filter = new NR::Filter(primitives); + shape->filter = new Inkscape::Filters::Filter(primitives); } sp_filter_build_renderer(SP_FILTER(style->getFilter()), shape->filter); } else { @@ -1489,4 +1508,4 @@ void nr_pixblock_render_shape_mask_or(NRPixBlock &m,Shape* theS) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :