diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2016-03-14 16:37:50 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2016-03-14 16:37:50 +0000 |
| commit | b8d22beef5345210ad27cdc2685083aeae6f8f3b (patch) | |
| tree | d69b8bfd19d3627a8425a1b265c2abf229b05354 /src/display | |
| parent | fixes for update to trunk (diff) | |
| parent | "Relative to" option for node alignment. (diff) | |
| download | inkscape-b8d22beef5345210ad27cdc2685083aeae6f8f3b.tar.gz inkscape-b8d22beef5345210ad27cdc2685083aeae6f8f3b.zip | |
update to trunk
(bzr r13708.1.39)
Diffstat (limited to 'src/display')
28 files changed, 348 insertions, 566 deletions
diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt index d4f8c16ff..0bf1d6e45 100644 --- a/src/display/CMakeLists.txt +++ b/src/display/CMakeLists.txt @@ -54,7 +54,6 @@ set(display_SRC sp-canvas.cpp sp-ctrlcurve.cpp sp-ctrlline.cpp - sp-ctrlpoint.cpp sp-ctrlquadr.cpp @@ -120,7 +119,6 @@ set(display_SRC sp-canvas.h sp-ctrlcurve.h sp-ctrlline.h - sp-ctrlpoint.h sp-ctrlquadr.h ) diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index 20e498981..419852f7d 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -115,8 +115,6 @@ ink_common_sources += \ display/sp-ctrlcurve.h \ display/sp-ctrlline.cpp \ display/sp-ctrlline.h \ - display/sp-ctrlpoint.cpp \ - display/sp-ctrlpoint.h \ display/sp-ctrlquadr.cpp \ display/sp-ctrlquadr.h diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 59e190676..24a75de4c 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -1120,9 +1120,9 @@ ink_cairo_pattern_create_checkerboard() cairo_t *ct = cairo_create(s); cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE); - cairo_set_source_rgb(ct, 0.75, 0.75, 0.75); + cairo_set_source_rgb(ct, 0.77, 0.77, 0.77); cairo_paint(ct); - cairo_set_source_rgb(ct, 0.5, 0.5, 0.5); + cairo_set_source_rgb(ct, 0.69, 0.69, 0.69); cairo_rectangle(ct, 0, 0, w, h); cairo_rectangle(ct, w, h, w, h); cairo_fill(ct); diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 1794ccbab..14f36376f 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -172,9 +172,9 @@ CanvasAxonomGrid::CanvasAxonomGrid (SPNamedView * nv, Inkscape::XML::Node * in_r angle_deg[Z] = prefs->getDouble("/options/grids/axonom/angle_z", 30.0); angle_deg[Y] = 0; - angle_rad[X] = Geom::deg_to_rad(angle_deg[X]); + angle_rad[X] = Geom::rad_from_deg(angle_deg[X]); tan_angle[X] = tan(angle_rad[X]); - angle_rad[Z] = Geom::deg_to_rad(angle_deg[Z]); + angle_rad[Z] = Geom::rad_from_deg(angle_deg[Z]); tan_angle[Z] = tan(angle_rad[Z]); snapper = new CanvasAxonomGridSnapper(this, &namedview->snap_manager, 0); @@ -272,7 +272,7 @@ CanvasAxonomGrid::readRepr() angle_deg[X] = g_ascii_strtod(value, NULL); if (angle_deg[X] < 0.) angle_deg[X] = 0.; if (angle_deg[X] > 89.0) angle_deg[X] = 89.0; - angle_rad[X] = Geom::deg_to_rad(angle_deg[X]); + angle_rad[X] = Geom::rad_from_deg(angle_deg[X]); tan_angle[X] = tan(angle_rad[X]); } @@ -280,7 +280,7 @@ CanvasAxonomGrid::readRepr() angle_deg[Z] = g_ascii_strtod(value, NULL); if (angle_deg[Z] < 0.) angle_deg[Z] = 0.; if (angle_deg[Z] > 89.0) angle_deg[Z] = 89.0; - angle_rad[Z] = Geom::deg_to_rad(angle_deg[Z]); + angle_rad[Z] = Geom::rad_from_deg(angle_deg[Z]); tan_angle[Z] = tan(angle_rad[Z]); } diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index 5ad87b4ef..7c019caf5 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -266,10 +266,10 @@ sp_canvastext_set_coords (SPCanvasText *ct, gdouble x0, gdouble y0) void sp_canvastext_set_coords (SPCanvasText *ct, const Geom::Point start) { - Geom::Point pos = ct->desktop->doc2dt(start); - - g_return_if_fail (ct != NULL); + g_return_if_fail (ct && ct->desktop); g_return_if_fail (SP_IS_CANVASTEXT (ct)); + + Geom::Point pos = ct->desktop->doc2dt(start); if (DIFFER (pos[0], ct->s[Geom::X]) || DIFFER (pos[1], ct->s[Geom::Y])) { ct->s[Geom::X] = pos[0]; diff --git a/src/display/curve.cpp b/src/display/curve.cpp index 3024d1276..b6c387034 100644 --- a/src/display/curve.cpp +++ b/src/display/curve.cpp @@ -496,7 +496,7 @@ SPCurve::append(SPCurve const *curve2, _pathv.push_back( (*it) ); } - for (it++; it != curve2->_pathv.end(); ++it) { + for (++it; it != curve2->_pathv.end(); ++it) { _pathv.push_back( (*it) ); } } else { diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 1594614ac..2a943d16c 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -132,7 +132,7 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar } } - dc.paint(_opacity); + dc.paint(1); } else { // outline; draw a rect instead diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 44bbd14bd..126fcf87c 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -17,17 +17,10 @@ #include <2geom/coord.h> #include <2geom/transforms.h> #include "sp-canvas-util.h" -#include "sp-ctrlpoint.h" #include "guideline.h" #include "display/cairo-utils.h" - -#include "inkscape.h" // for inkscape_active_desktop() -#include "desktop.h" -#include "sp-namedview.h" #include "display/sp-canvas.h" -#include "ui/control-manager.h" - -using Inkscape::ControlManager; +#include "display/sodipodi-ctrl.h" static void sp_guideline_destroy(SPCanvasItem *object); @@ -53,6 +46,7 @@ static void sp_guideline_init(SPGuideLine *gl) { gl->rgba = 0x0000ff7f; + gl->locked = false; gl->normal_to_line = Geom::Point(0,1); gl->angle = 3.14159265358979323846/2; gl->point_on_line = Geom::Point(0,0); @@ -66,16 +60,11 @@ static void sp_guideline_destroy(SPCanvasItem *object) { g_return_if_fail (object != NULL); g_return_if_fail (SP_IS_GUIDELINE (object)); - //g_return_if_fail (SP_GUIDELINE(object)->origin != NULL); - //g_return_if_fail (SP_IS_CTRLPOINT(SP_GUIDELINE(object)->origin)); SPGuideLine *gl = SP_GUIDELINE(object); - if (gl->origin != NULL && SP_IS_CTRLPOINT(gl->origin)) { - sp_canvas_item_destroy(gl->origin); - } else { - // FIXME: This branch shouldn't be reached (although it seems to be harmless). - //g_error("Why can it be that gl->origin is not a valid SPCtrlPoint?\n"); + if (gl->origin) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(gl->origin)); } if (gl->label) { @@ -175,12 +164,22 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, (SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update(item, affine, flags); } - gl->affine = affine; - - sp_ctrlpoint_set_coords(gl->origin, gl->point_on_line); - sp_canvas_item_request_update(SP_CANVAS_ITEM (gl->origin)); + if (item->visible) { + if (gl->locked) { + g_object_set(G_OBJECT(gl->origin), "stroke_color", 0x0000ff88, + "shape", SP_CTRL_SHAPE_CROSS, + "size", 6., NULL); + } else { + g_object_set(G_OBJECT(gl->origin), "stroke_color", 0xff000088, + "shape", SP_CTRL_SHAPE_CIRCLE, + "size", 4., NULL); + } + gl->origin->moveto(gl->point_on_line); + sp_canvas_item_request_update(SP_CANVAS_ITEM(gl->origin)); + } - Geom::Point pol_transformed = gl->point_on_line*affine; + gl->affine = affine; + Geom::Point pol_transformed = gl->point_on_line * affine; if (gl->is_horizontal()) { sp_canvas_update_bbox (item, -1000000, round(pol_transformed[Geom::Y] - 16), 1000000, round(pol_transformed[Geom::Y] + 1)); } else if (gl->is_vertical()) { @@ -210,20 +209,22 @@ static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point point_on_line, Geom::Point normal) { SPCanvasItem *item = sp_canvas_item_new(parent, SP_TYPE_GUIDELINE, NULL); - SPCanvasItem *origin = ControlManager::getManager().createControl(parent, Inkscape::CTRL_TYPE_ORIGIN); - ControlManager::getManager().track(origin); - SPGuideLine *gl = SP_GUIDELINE(item); - SPCtrlPoint *cp = SP_CTRLPOINT(origin); - gl->origin = cp; normal.normalize(); gl->label = label; + gl->locked = false; gl->normal_to_line = normal; gl->angle = tan( -gl->normal_to_line[Geom::X] / gl->normal_to_line[Geom::Y]); sp_guideline_set_position(gl, point_on_line); - sp_ctrlpoint_set_coords(cp, point_on_line); + gl->origin = (SPCtrl *) sp_canvas_item_new(parent, SP_TYPE_CTRL, + "anchor", SP_ANCHOR_CENTER, + "mode", SP_CTRL_MODE_COLOR, + "filled", FALSE, + "stroked", TRUE, + "stroke_color", 0x01000000, NULL); + gl->origin->pickable = false; return item; } @@ -238,6 +239,12 @@ void sp_guideline_set_label(SPGuideLine *gl, const char* label) sp_canvas_item_request_update(SP_CANVAS_ITEM (gl)); } +void sp_guideline_set_locked(SPGuideLine *gl, const bool locked) +{ + gl->locked = locked; + sp_canvas_item_request_update(SP_CANVAS_ITEM (gl)); +} + void sp_guideline_set_position(SPGuideLine *gl, Geom::Point point_on_line) { gl->point_on_line = point_on_line; @@ -255,8 +262,7 @@ void sp_guideline_set_normal(SPGuideLine *gl, Geom::Point normal_to_line) void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba) { gl->rgba = rgba; - sp_ctrlpoint_set_color(gl->origin, rgba); - + g_object_set(G_OBJECT(gl->origin), "stroke_color", rgba, NULL); sp_canvas_item_request_update(SP_CANVAS_ITEM(gl)); } @@ -267,7 +273,6 @@ void sp_guideline_set_sensitive(SPGuideLine *gl, int sensitive) void sp_guideline_delete(SPGuideLine *gl) { - //gtk_object_destroy(GTK_OBJECT(gl->origin)); sp_canvas_item_destroy(SP_CANVAS_ITEM(gl)); } diff --git a/src/display/guideline.h b/src/display/guideline.h index 2d9a87d9b..44aed88d9 100644 --- a/src/display/guideline.h +++ b/src/display/guideline.h @@ -21,17 +21,18 @@ #define SP_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_GUIDELINE, SPGuideLine)) #define SP_IS_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_GUIDELINE)) -struct SPCtrlPoint; +struct SPCtrl; struct SPGuideLine { SPCanvasItem item; Geom::Affine affine; - SPCtrlPoint *origin; // unlike 'item', this is only held locally + SPCtrl *origin; // unlike 'item', this is only held locally guint32 rgba; char* label; + bool locked; Geom::Point normal_to_line; Geom::Point point_on_line; double angle; @@ -51,6 +52,7 @@ GType sp_guideline_get_type(); SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point point_on_line, Geom::Point normal); void sp_guideline_set_label(SPGuideLine *gl, const char* label); +void sp_guideline_set_locked(SPGuideLine *gl, const bool locked); void sp_guideline_set_position(SPGuideLine *gl, Geom::Point point_on_line); void sp_guideline_set_normal(SPGuideLine *gl, Geom::Point normal_to_line); void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba); diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index dd90193fe..b2545b76f 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -30,6 +30,32 @@ FilterPrimitive * FilterComponentTransfer::create() { FilterComponentTransfer::~FilterComponentTransfer() {} +struct UnmultiplyAlpha { + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a, r, g, b); + if (a == 0 ) + return in; + r = unpremul_alpha(r, a); + g = unpremul_alpha(g, a); + b = unpremul_alpha(b, a); + ASSEMBLE_ARGB32(out, a, r, g, b); + return out; + } +}; + +struct MultiplyAlpha { + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a, r, g, b); + if (a == 0 ) + return in; + r = premul_alpha(r, a); + g = premul_alpha(g, a); + b = premul_alpha(b, a); + ASSEMBLE_ARGB32(out, a, r, g, b); + return out; + } +}; + struct ComponentTransfer { ComponentTransfer(guint32 color) : _shift(color * 8) @@ -40,11 +66,7 @@ protected: guint32 _mask; }; -template <bool alpha> -struct ComponentTransferTable; - -template <> -struct ComponentTransferTable<false> : public ComponentTransfer { +struct ComponentTransferTable : public ComponentTransfer { ComponentTransferTable(guint32 color, std::vector<double> const &values) : ComponentTransfer(color) , _v(values.size()) @@ -55,49 +77,17 @@ struct ComponentTransferTable<false> : public ComponentTransfer { } guint32 operator()(guint32 in) { guint32 component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - component = (255 * component + alpha/2) / alpha; guint32 k = (_v.size() - 1) * component; guint32 dx = k % 255; k /= 255; component = _v[k]*255 + (_v[k+1] - _v[k])*dx; component = (component + 127) / 255; - component = premul_alpha(component, alpha); return (in & ~_mask) | (component << _shift); } private: std::vector<guint32> _v; }; -template <> -struct ComponentTransferTable<true> { - ComponentTransferTable(std::vector<double> const &values) - : _v(values.size()) - { - for (unsigned i = 0; i< values.size(); ++i) { - _v[i] = round(CLAMP(values[i], 0.0, 1.0) * 255); - } - } - guint32 operator()(guint32 in) { - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - guint32 k = (_v.size() - 1) * alpha; - guint32 dx = k % 255; k /= 255; - alpha = _v[k]*255 + (_v[k+1] - _v[k])*dx; - alpha = (alpha + 127) / 255; - return (in & 0x00ffffff) | (alpha << 24); - } -private: - std::vector<guint32> _v; -}; - -template <bool alpha> -struct ComponentTransferDiscrete; - -template <> -struct ComponentTransferDiscrete<false> : public ComponentTransfer { +struct ComponentTransferDiscrete : public ComponentTransfer { ComponentTransferDiscrete(guint32 color, std::vector<double> const &values) : ComponentTransfer(color) , _v(values.size()) @@ -108,45 +98,16 @@ struct ComponentTransferDiscrete<false> : public ComponentTransfer { } guint32 operator()(guint32 in) { guint32 component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - component = (255 * component + alpha/2) / alpha; - guint32 k = (_v.size() - 1) * component / 255; + guint32 k = (_v.size()) * component / 255; + if( k == _v.size() ) --k; component = _v[k]; - component = premul_alpha(component, alpha); - return (in & ~_mask) | (component << _shift); + return (in & ~_mask) | ((guint32)component << _shift); } private: std::vector<guint32> _v; }; -template <> -struct ComponentTransferDiscrete<true> { - ComponentTransferDiscrete(std::vector<double> const &values) - : _v(values.size()) - { - for (unsigned i = 0; i< values.size(); ++i) { - _v[i] = round(CLAMP(values[i], 0.0, 1.0) * 255); - } - } - guint32 operator()(guint32 in) { - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return in; - - guint32 k = (_v.size() - 1) * alpha / 255; - alpha = _v[k]; - return (in & 0x00ffffff) | (alpha << 24); - } -private: - std::vector<guint32> _v; -}; - -template <bool alpha> -struct ComponentTransferLinear; - -template <> -struct ComponentTransferLinear<false> : public ComponentTransfer { +struct ComponentTransferLinear : public ComponentTransfer { ComponentTransferLinear(guint32 color, double intercept, double slope) : ComponentTransfer(color) , _intercept(round(intercept*255*255)) @@ -154,14 +115,10 @@ struct ComponentTransferLinear<false> : public ComponentTransfer { {} guint32 operator()(guint32 in) { gint32 component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return 0; // TODO: this can probably be reduced to something simpler - component = (255 * component + alpha/2) / alpha; component = pxclamp(_slope * component + _intercept, 0, 255*255); component = (component + 127) / 255; - component = premul_alpha(component, alpha); return (in & ~_mask) | (component << _shift); } private: @@ -169,28 +126,7 @@ private: gint32 _slope; }; -template <> -struct ComponentTransferLinear<true> { - ComponentTransferLinear(double intercept, double slope) - : _intercept(round(intercept*255*255)) - , _slope(round(slope*255)) - {} - guint32 operator()(guint32 in) { - gint32 alpha = (in & 0xff000000) >> 24; - alpha = pxclamp(_slope * alpha + _intercept, 0, 255*255); - alpha = (alpha + 127) / 255; - return (in & 0x00ffffff) | (alpha << 24); - } -private: - gint32 _intercept; - gint32 _slope; -}; - -template <bool alpha> -struct ComponentTransferGamma; - -template <> -struct ComponentTransferGamma<false> : public ComponentTransfer { +struct ComponentTransferGamma : public ComponentTransfer { ComponentTransferGamma(guint32 color, double amplitude, double exponent, double offset) : ComponentTransfer(color) , _amplitude(amplitude) @@ -199,13 +135,9 @@ struct ComponentTransferGamma<false> : public ComponentTransfer { {} guint32 operator()(guint32 in) { double component = (in & _mask) >> _shift; - guint32 alpha = (in & 0xff000000) >> 24; - if (alpha == 0) return 0; - - double alphaf = alpha; - component /= alphaf; + component /= 255.0; component = _amplitude * pow(component, _exponent) + _offset; - guint32 cpx = pxclamp(component * alphaf, 0, 255); + guint32 cpx = pxclamp(component * 255.0, 0, 255); return (in & ~_mask) | (cpx << _shift); } private: @@ -214,26 +146,6 @@ private: double _offset; }; -template <> -struct ComponentTransferGamma<true> { - ComponentTransferGamma(double amplitude, double exponent, double offset) - : _amplitude(amplitude) - , _exponent(exponent) - , _offset(offset) - {} - guint32 operator()(guint32 in) { - double alpha = (in & 0xff000000) >> 24; - alpha /= 255.0; - alpha = _amplitude * pow(alpha, _exponent) + _offset; - guint32 cpx = pxclamp(alpha * 255.0, 0, 255); - return (in & 0x00ffffff) | (cpx << 24); - } -private: - double _amplitude; - double _exponent; - double _offset; -}; - void FilterComponentTransfer::render_cairo(FilterSlot &slot) { cairo_surface_t *input = slot.getcairo(_input); @@ -252,31 +164,38 @@ void FilterComponentTransfer::render_cairo(FilterSlot &slot) //cairo_surface_t *outtemp = ink_cairo_surface_create_identical(out); ink_cairo_surface_blit(input, out); + // We need to operate on unmultipled by alpha color values otherwise a change in alpha screws + // up the premultiplied by alpha r, g, b values. + ink_cairo_surface_filter(out, out, UnmultiplyAlpha()); + // parameters: R = 0, G = 1, B = 2, A = 3 // Cairo: R = 2, G = 1, B = 0, A = 3 // If tableValues is empty, use identity. - for (unsigned i = 0; i < 3; ++i) { + for (unsigned i = 0; i < 4; ++i) { + guint32 color = 2 - i; + if(i==3) color = 3; // alpha + switch (type[i]) { case COMPONENTTRANSFER_TYPE_TABLE: if(!tableValues[i].empty()) { ink_cairo_surface_filter(out, out, - ComponentTransferTable<false>(color, tableValues[i])); + ComponentTransferTable(color, tableValues[i])); } break; case COMPONENTTRANSFER_TYPE_DISCRETE: if(!tableValues[i].empty()) { ink_cairo_surface_filter(out, out, - ComponentTransferDiscrete<false>(color, tableValues[i])); + ComponentTransferDiscrete(color, tableValues[i])); } break; case COMPONENTTRANSFER_TYPE_LINEAR: ink_cairo_surface_filter(out, out, - ComponentTransferLinear<false>(color, intercept[i], slope[i])); + ComponentTransferLinear(color, intercept[i], slope[i])); break; case COMPONENTTRANSFER_TYPE_GAMMA: ink_cairo_surface_filter(out, out, - ComponentTransferGamma<false>(color, amplitude[i], exponent[i], offset[i])); + ComponentTransferGamma(color, amplitude[i], exponent[i], offset[i])); break; case COMPONENTTRANSFER_TYPE_ERROR: case COMPONENTTRANSFER_TYPE_IDENTITY: @@ -286,33 +205,7 @@ void FilterComponentTransfer::render_cairo(FilterSlot &slot) //ink_cairo_surface_blit(out, outtemp); } - // fast paths for alpha channel - switch (type[3]) { - case COMPONENTTRANSFER_TYPE_TABLE: - if(!tableValues[3].empty()) { - ink_cairo_surface_filter(out, out, - ComponentTransferTable<true>(tableValues[3])); - } - break; - case COMPONENTTRANSFER_TYPE_DISCRETE: - if(!tableValues[3].empty()) { - ink_cairo_surface_filter(out, out, - ComponentTransferDiscrete<true>(tableValues[3])); - } - break; - case COMPONENTTRANSFER_TYPE_LINEAR: - ink_cairo_surface_filter(out, out, - ComponentTransferLinear<true>(intercept[3], slope[3])); - break; - case COMPONENTTRANSFER_TYPE_GAMMA: - ink_cairo_surface_filter(out, out, - ComponentTransferGamma<true>(amplitude[3], exponent[3], offset[3])); - break; - case COMPONENTTRANSFER_TYPE_ERROR: - case COMPONENTTRANSFER_TYPE_IDENTITY: - default: - break; - } + ink_cairo_surface_filter(out, out, MultiplyAlpha()); slot.set(_output, out); cairo_surface_destroy(out); diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 179ba0e0a..af89d98e0 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -56,6 +56,8 @@ void FilterImage::render_cairo(FilterSlot &slot) // Note: viewport calculation in non-trivial. Do not rely // on get_matrix_primitiveunits2pb(). Geom::Rect vp = filter_primitive_area( slot.get_units() ); + slot.set_primitive_area(_output, vp); // Needed for tiling + double feImageX = vp.min()[Geom::X]; double feImageY = vp.min()[Geom::Y]; double feImageWidth = vp.width(); diff --git a/src/display/nr-filter-offset.cpp b/src/display/nr-filter-offset.cpp index af1081abe..93bab7d39 100644 --- a/src/display/nr-filter-offset.cpp +++ b/src/display/nr-filter-offset.cpp @@ -37,9 +37,11 @@ void FilterOffset::render_cairo(FilterSlot &slot) cairo_surface_t *out = ink_cairo_surface_create_identical(in); // color_interpolation_filters for out same as in. See spec (DisplacementMap). copy_cairo_surface_ci(in, out); - cairo_t *ct = cairo_create(out); + Geom::Rect vp = filter_primitive_area( slot.get_units() ); + slot.set_primitive_area(_output, vp); // Needed for tiling + // Handle bounding box case double x = dx; double y = dy; diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp index c8b569036..ea72efff0 100644 --- a/src/display/nr-filter-primitive.cpp +++ b/src/display/nr-filter-primitive.cpp @@ -110,17 +110,12 @@ void FilterPrimitive::set_subregion(SVGLength const &x, SVGLength const &y, Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units) { - Geom::OptRect const bb_opt = units.get_item_bbox(); Geom::OptRect const fa_opt = units.get_filter_area(); - Geom::Rect bb; - Geom::Rect fa; - if (!bb_opt || !fa_opt) { + if (!fa_opt) { + std::cerr << "FilterPrimitive::filter_primitive_area: filter area undefined." << std::endl; return Geom::Rect (Geom::Point(0.,0.), Geom::Point(0.,0.)); - } else { - bb = *bb_opt; - fa = *fa_opt; } - + Geom::Rect fa = *fa_opt; // x, y, width, and height are independently defined (i.e. one can be defined, by default, to // the filter area (via default value ) while another is defined relative to the bounding @@ -138,6 +133,14 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units) if( units.get_primitive_units() == SP_FILTER_UNITS_OBJECTBOUNDINGBOX ) { + Geom::OptRect const bb_opt = units.get_item_bbox(); + if (!bb_opt) { + std::cerr << "FilterPrimitive::filter_primitive_area: bounding box undefined and 'primitiveUnits' is 'objectBoundingBox'." << std::endl; + return Geom::Rect (Geom::Point(0.,0.), Geom::Point(0.,0.)); + } + Geom::Rect bb = *bb_opt; + + // Update computed values for ex, em, %. // For %, assumes primitive unit is objectBoundingBox. // TODO: fetch somehow the object ex and em lengths; 12, 6 are just dummy values. diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp index e4c2f048e..a6e0c5c4e 100644 --- a/src/display/nr-filter-slot.cpp +++ b/src/display/nr-filter-slot.cpp @@ -232,6 +232,27 @@ void FilterSlot::set(int slot_nr, cairo_surface_t *surface) _last_out = slot_nr; } +void FilterSlot::set_primitive_area(int slot_nr, Geom::Rect &area) +{ + if (slot_nr == NR_FILTER_SLOT_NOT_SET) + slot_nr = NR_FILTER_UNNAMED_SLOT; + + _primitiveAreas[slot_nr] = area; +} + +Geom::Rect FilterSlot::get_primitive_area(int slot_nr) +{ + if (slot_nr == NR_FILTER_SLOT_NOT_SET) + slot_nr = _last_out; + + PrimitiveAreaMap::iterator s = _primitiveAreas.find(slot_nr); + + if (s == _primitiveAreas.end()) { + return *(_units.get_filter_area()); + } + return s->second; +} + int FilterSlot::get_slot_count() { return _slots.size(); diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index 987dedfd1..166b2e718 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -54,6 +54,9 @@ public: cairo_surface_t *get_result(int slot_nr); + void set_primitive_area(int slot, Geom::Rect &area); + Geom::Rect get_primitive_area(int slot); + /** Returns the number of slots in use. */ int get_slot_count(); @@ -75,6 +78,11 @@ public: private: typedef std::map<int, cairo_surface_t *> SlotMap; SlotMap _slots; + + // We need to keep track of the primitive area as this is needed in feTile + typedef std::map<int, Geom::Rect> PrimitiveAreaMap; + PrimitiveAreaMap _primitiveAreas; + DrawingItem *_item; //Geom::Rect _source_bbox; ///< bounding box of source graphic surface diff --git a/src/display/nr-filter-tile.cpp b/src/display/nr-filter-tile.cpp index 93ca50210..913812828 100644 --- a/src/display/nr-filter-tile.cpp +++ b/src/display/nr-filter-tile.cpp @@ -10,6 +10,8 @@ */ #include <glib.h> + +#include "display/cairo-utils.h" #include "display/nr-filter-tile.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" @@ -30,16 +32,105 @@ FilterTile::~FilterTile() void FilterTile::render_cairo(FilterSlot &slot) { + // FIX ME! static bool tile_warning = false; - -//IMPLEMENT ME! if (!tile_warning) { - g_warning("Renderer for feTile is not implemented."); + g_warning("Renderer for feTile has non-optimal implementation, expect slowness and bugs."); tile_warning = true; } + // Fixing isn't so easy as the Inkscape renderer breaks the canvas into "rendering" tiles for + // faster rendering. (The "rendering" tiles are not the same as the tiles in this primitive.) + // Only if the the feTile tile source falls inside the current "rendering" tile will the tile + // image be available. + + // This input source contains only the "rendering" tile. cairo_surface_t *in = slot.getcairo(_input); - slot.set(_output, in); + + // For debugging + // static int i = 0; + // ++i; + // std::stringstream filename; + // filename << "dump." << i << ".png"; + // cairo_surface_write_to_png( in, filename.str().c_str() ); + + // This is the feTile source area as determined by the input primitive area (see SVG spec). + Geom::Rect tile_area = slot.get_primitive_area(_input); + + if( tile_area.width() == 0.0 || tile_area.height() == 0.0 ) { + + slot.set(_output, in); + std::cerr << "FileTile::render_cairo: tile has zero width or height" << std::endl; + + } else { + + cairo_surface_t *out = ink_cairo_surface_create_identical(in); + // color_interpolation_filters for out same as in. + copy_cairo_surface_ci(in, out); + cairo_t *ct = cairo_create(out); + + // The rectangle of the "rendering" tile. + Geom::Rect sa = slot.get_slot_area(); + + Geom::Affine trans = slot.get_units().get_matrix_user2pb(); + + // Create feTile tile ---------------- + + // Get tile area in pixbuf units (tile transformed). + Geom::Rect tt = tile_area * trans; + + // Shift between "rendering" tile and feTile tile + Geom::Point shift = sa.min() - tt.min(); + + // Create feTile tile surface + cairo_surface_t *tile = cairo_surface_create_similar(in, cairo_surface_get_content(in), + tt.width(), tt.height()); + cairo_t *ct_tile = cairo_create(tile); + cairo_set_source_surface(ct_tile, in, shift[Geom::X], shift[Geom::Y]); + cairo_paint(ct_tile); + + // Paint tiles ------------------ + + // For debugging + // std::stringstream filename; + // filename << "tile." << i << ".png"; + // cairo_surface_write_to_png( tile, filename.str().c_str() ); + + // Determine number of feTile rows and columns + Geom::Rect pr = filter_primitive_area( slot.get_units() ); + int tile_cols = ceil( pr.width() / tile_area.width() ); + int tile_rows = ceil( pr.height() / tile_area.height() ); + + // Do tiling (TO DO: restrict to slot area.) + for( int col=0; col < tile_cols; ++col ) { + for( int row=0; row < tile_rows; ++row ) { + + Geom::Point offset( col*tile_area.width(), row*tile_area.height() ); + offset *= trans; + offset[Geom::X] -= trans[4]; + offset[Geom::Y] -= trans[5]; + + cairo_set_source_surface(ct, tile, offset[Geom::X], offset[Geom::Y]); + cairo_paint(ct); + } + } + slot.set(_output, out); + + // Clean up + cairo_destroy(ct); + cairo_surface_destroy(out); + cairo_destroy(ct_tile); + cairo_surface_destroy(tile); + } +} + +void FilterTile::area_enlarge(Geom::IntRect &area, Geom::Affine const &trans) +{ + // We need to enlarge enough to get tile source... we don't the area of the source tile in this + // function so we guess. This is VERY inefficient. + Geom::Point enlarge(200, 200); + enlarge *= trans; + area.expandBy( enlarge[Geom::X] < 100 ? 100: enlarge[Geom::X] ); } double FilterTile::complexity(Geom::Affine const &) diff --git a/src/display/nr-filter-tile.h b/src/display/nr-filter-tile.h index 29087f2d6..239ecff4b 100644 --- a/src/display/nr-filter-tile.h +++ b/src/display/nr-filter-tile.h @@ -26,6 +26,7 @@ public: virtual ~FilterTile(); virtual void render_cairo(FilterSlot &slot); + virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans); virtual double complexity(Geom::Affine const &ctm); }; diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index dec5b1f57..8591be7eb 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -200,7 +200,7 @@ void Filter::area_enlarge(Geom::IntRect &bbox, Inkscape::DrawingItem const *item Geom::Rect item_bbox; Geom::OptRect maybe_bbox = item->itemBounds(); - if (maybe_bbox.isEmpty()) { + if (maybe_bbox.empty()) { // Code below needs a bounding box return; } diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 1740785e2..8b82a1dff 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -68,7 +68,6 @@ NRStyle::NRStyle() , tspan_width(0) , ascender(0) , descender(0) - , line_gap(0) , underline_thickness(0) , underline_position(0) , line_through_thickness(0) @@ -330,7 +329,6 @@ void NRStyle::set(SPStyle *style, SPStyle *context_style) tspan_width = style->text_decoration_data.tspan_width; ascender = style->text_decoration_data.ascender; descender = style->text_decoration_data.descender; - line_gap = style->text_decoration_data.line_gap; underline_thickness = style->text_decoration_data.underline_thickness; underline_position = style->text_decoration_data.underline_position; line_through_thickness = style->text_decoration_data.line_through_thickness; diff --git a/src/display/nr-style.h b/src/display/nr-style.h index 5f78795d3..6c652311a 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -115,7 +115,6 @@ struct NRStyle { float tspan_width; float ascender; float descender; - float line_gap; float underline_thickness; float underline_position; float line_through_thickness; diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 926b35599..17deea16d 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -256,7 +256,12 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap "shape", SP_KNOT_SHAPE_CROSS, NULL ); - const int timeout_val = 4000; + double timeout_val = prefs->getDouble("/options/snapindicatorpersistence/value", 2.0); + if (timeout_val < 0.1) { + timeout_val = 0.1; // a zero value would mean infinite persistence (i.e. until new snap occurs) + // Besides, negatives values would ....? + } + // The snap indicator will be deleted after some time-out, and sp_canvas_item_dispose // will be called. This will set canvas->current_item to NULL if the snap indicator was @@ -272,7 +277,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap SP_CTRL(canvasitem)->pickable = false; SP_CTRL(canvasitem)->moveto(p.getPoint()); - _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val); + _snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val*1000.0); _snaptarget_is_presnap = pre_snap; // Display the tooltip, which reveals the type of snap source and the type of snap target @@ -307,7 +312,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap SP_CANVASTEXT(canvas_tooltip)->anchor_position = TEXT_ANCHOR_CENTER; g_free(tooltip_str); - _snaptarget_tooltip = _desktop->add_temporary_canvasitem(canvas_tooltip, timeout_val); + _snaptarget_tooltip = _desktop->add_temporary_canvasitem(canvas_tooltip, timeout_val*1000.0); } // Display the bounding box, if we snapped to one diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp index 75789ff50..ecc952c48 100644 --- a/src/display/sodipodi-ctrlrect.cpp +++ b/src/display/sodipodi-ctrlrect.cpp @@ -74,6 +74,8 @@ void CtrlRect::init() { _has_fill = false; _dashed = false; + _checkerboard = false; + _shadow = 0; _area = Geom::OptIntRect(); @@ -109,10 +111,17 @@ void CtrlRect::render(SPCanvasBuf *buf) cairo_rectangle(buf->ct, 0.5 + area[X].min(), 0.5 + area[Y].min(), area[X].max() - area[X].min(), area[Y].max() - area[Y].min()); + if (_checkerboard) { + cairo_pattern_t *cb = ink_cairo_pattern_create_checkerboard(); + cairo_set_source(buf->ct, cb); + cairo_pattern_destroy(cb); + cairo_fill_preserve(buf->ct); + } if (_has_fill) { ink_cairo_set_source_rgba32(buf->ct, _fill_color); cairo_fill_preserve(buf->ct); } + ink_cairo_set_source_rgba32(buf->ct, _border_color); cairo_stroke(buf->ct); @@ -297,6 +306,12 @@ void CtrlRect::setDashed(bool d) _requestUpdate(); } +void CtrlRect::setCheckerboard(bool d) +{ + _checkerboard = d; + _requestUpdate(); +} + void CtrlRect::_requestUpdate() { sp_canvas_item_request_update(SP_CANVAS_ITEM(this)); diff --git a/src/display/sodipodi-ctrlrect.h b/src/display/sodipodi-ctrlrect.h index ff6c55b06..08a085649 100644 --- a/src/display/sodipodi-ctrlrect.h +++ b/src/display/sodipodi-ctrlrect.h @@ -39,6 +39,7 @@ public: void setShadow(int s, guint c); void setRectangle(Geom::Rect const &r); void setDashed(bool d); + void setCheckerboard(bool d); void render(SPCanvasBuf *buf); void update(Geom::Affine const &affine, unsigned int flags); @@ -49,6 +50,8 @@ private: Geom::Rect _rect; bool _has_fill; bool _dashed; + bool _checkerboard; + Geom::OptIntRect _area; gint _shadow_size; guint32 _border_color; diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h index 3e9e085a0..66cd03dd9 100644 --- a/src/display/sp-canvas-item.h +++ b/src/display/sp-canvas-item.h @@ -116,7 +116,9 @@ G_END_DECLS void sp_canvas_item_affine_absolute(SPCanvasItem *item, Geom::Affine const &aff); void sp_canvas_item_raise(SPCanvasItem *item, int positions); +void sp_canvas_item_raise_to_top(SPCanvasItem *item); void sp_canvas_item_lower(SPCanvasItem *item, int positions); +void sp_canvas_item_lower_to_bottom(SPCanvasItem *item); bool sp_canvas_item_is_visible(SPCanvasItem *item); void sp_canvas_item_show(SPCanvasItem *item); void sp_canvas_item_hide(SPCanvasItem *item); diff --git a/src/display/sp-canvas-util.cpp b/src/display/sp-canvas-util.cpp index 79c8c614e..25b70824b 100644 --- a/src/display/sp-canvas-util.cpp +++ b/src/display/sp-canvas-util.cpp @@ -67,6 +67,9 @@ void sp_canvas_item_set_i2w_affine (SPCanvasItem * item, Geom::Affine const &i2 void sp_canvas_item_move_to_z (SPCanvasItem * item, gint z) { g_assert (item != NULL); + + if (z == 0) + return sp_canvas_item_lower_to_bottom(item); gint current_z = sp_canvas_item_order (item); diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 5efc4ce86..d17271752 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -58,7 +58,7 @@ struct SPCanvasGroupClass { }; /** - * A group of Items. + * A group of items. */ struct SPCanvasGroup { /** @@ -109,8 +109,8 @@ struct SPCanvasGroup { SPCanvasItem item; - GList *items; - GList *last; + std::list<SPCanvasItem *> items; + }; /** @@ -167,13 +167,6 @@ static guint object_signals[LAST_SIGNAL] = { 0 }; void sp_canvas_item_construct(SPCanvasItem *item, SPCanvasGroup *parent, gchar const *first_arg_name, va_list args); /** - * Convenience function to reorder items in a group's child list. - * - * This puts the specified link after the "before" link. - */ -void put_item_after(GList *link, GList *before); - -/** * Helper that returns true iff item is descendant of parent. */ bool is_descendant(SPCanvasItem const *item, SPCanvasItem const *parent); @@ -426,7 +419,7 @@ static void redraw_if_visible(SPCanvasItem *item) int y1 = (int)(item->y2); if (x0 !=0 || x1 !=0 || y0 !=0 || y1 !=0) { - item->canvas->requestRedraw((int)(item->x1), (int)(item->y1), (int)(item->x2 + 1), (int)(item->y2 + 1)); + item->canvas->requestRedraw((int)(item->x1 - 1), (int)(item->y1 -1), (int)(item->x2 + 1), (int)(item->y2 + 1)); } } } @@ -590,64 +583,6 @@ void sp_canvas_item_affine_absolute(SPCanvasItem *item, Geom::Affine const &affi item->canvas->need_repick = TRUE; } -namespace { - -void put_item_after(GList *link, GList *before) -{ - if (link == before) { - return; - } - - SPCanvasGroup *parent = SP_CANVAS_GROUP (SP_CANVAS_ITEM (link->data)->parent); - - if (before == NULL) { - if (link == parent->items) { - return; - } - - link->prev->next = link->next; - - if (link->next) { - link->next->prev = link->prev; - } else { - parent->last = link->prev; - } - - link->prev = before; - link->next = parent->items; - link->next->prev = link; - parent->items = link; - } else { - if ((link == parent->last) && (before == parent->last->prev)) { - return; - } - - if (link->next) { - link->next->prev = link->prev; - } - - if (link->prev) { - link->prev->next = link->next; - } else { - parent->items = link->next; - parent->items->prev = NULL; - } - - link->prev = before; - link->next = before->next; - - link->prev->next = link; - - if (link->next) { - link->next->prev = link; - } else { - parent->last = link; - } - } -} - -} // namespace - /** * Raises the item in its parent's stack by the specified number of positions. * @@ -668,24 +603,34 @@ void sp_canvas_item_raise(SPCanvasItem *item, int positions) } SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - GList *link = g_list_find (parent->items, item); - g_assert (link != NULL); + std::list<SPCanvasItem *>::iterator l = std::find(parent->items.begin(),parent->items.end(), item); + g_assert (l != parent->items.end()); - GList *before; - for (before = link; positions && before; positions--) - before = before->next; + for (int i=0; i<=positions && l != parent->items.end(); ++i) + ++l; - if (!before) { - before = parent->last; - } + parent->items.remove(item); + parent->items.insert(l, item); - put_item_after (link, before); + redraw_if_visible (item); + item->canvas->need_repick = TRUE; +} +void sp_canvas_item_raise_to_top(SPCanvasItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + if (!item->parent) + return; + SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); + parent->items.remove(item); + parent->items.push_back(item); redraw_if_visible (item); item->canvas->need_repick = TRUE; } + /** * Lowers the item in its parent's stack by the specified number of positions. * @@ -701,32 +646,41 @@ void sp_canvas_item_lower(SPCanvasItem *item, int positions) g_return_if_fail (SP_IS_CANVAS_ITEM (item)); g_return_if_fail (positions >= 1); - if (!item->parent || positions == 0) { + SPCanvasGroup *parent = SP_CANVAS_GROUP(item->parent); + + if (!parent || positions == 0 || item == parent->items.front() ) { return; } - SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); - GList *link = g_list_find (parent->items, item); - g_assert (link != NULL); + std::list<SPCanvasItem *>::iterator l = std::find(parent->items.begin(), parent->items.end(), item); + g_assert (l != parent->items.end()); - GList *before; - if (link->prev) { - for (before = link->prev; positions && before; positions--) { - before = before->prev; - } - } else { - before = NULL; - } - - put_item_after (link, before); + for (int i=0; i<positions && l != parent->items.begin(); ++i) + --l; + + parent->items.remove(item); + parent->items.insert(l, item); redraw_if_visible (item); item->canvas->need_repick = TRUE; } +void sp_canvas_item_lower_to_bottom(SPCanvasItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + if (!item->parent) + return; + SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); + parent->items.remove(item); + parent->items.push_front(item); + redraw_if_visible (item); + item->canvas->need_repick = TRUE; +} + bool sp_canvas_item_is_visible(SPCanvasItem *item) { - return item->visible; + return item->visible; } /** @@ -919,7 +873,15 @@ void sp_canvas_item_request_update(SPCanvasItem *item) */ gint sp_canvas_item_order (SPCanvasItem * item) { - return g_list_index (SP_CANVAS_GROUP (item->parent)->items, item); + SPCanvasGroup * p = SP_CANVAS_GROUP(item->parent); + size_t index = 0; + for (std::list<SPCanvasItem*>::const_iterator it = p->items.begin(); it != p->items.end(); ++it, ++index) { + if ((*it) == item) { + return index; + } + } + + return -1; } // SPCanvasGroup @@ -936,9 +898,9 @@ static void sp_canvas_group_class_init(SPCanvasGroupClass *klass) item_class->viewbox_changed = SPCanvasGroup::viewboxChanged; } -static void sp_canvas_group_init(SPCanvasGroup * /*group*/) +static void sp_canvas_group_init(SPCanvasGroup * group) { - // Nothing here + new (&group->items) std::list<SPCanvasItem *>; } void SPCanvasGroup::destroy(SPCanvasItem *object) @@ -946,16 +908,15 @@ void SPCanvasGroup::destroy(SPCanvasItem *object) g_return_if_fail(object != NULL); g_return_if_fail(SP_IS_CANVAS_GROUP(object)); - SPCanvasGroup const *group = SP_CANVAS_GROUP(object); - - GList *list = group->items; - while (list) { - SPCanvasItem *child = reinterpret_cast<SPCanvasItem *>(list->data); - list = list->next; + SPCanvasGroup *group = SP_CANVAS_GROUP(object); - sp_canvas_item_destroy(child); + for (std::list<SPCanvasItem *>::iterator it = group->items.begin(); it != group->items.end(); ++it) { + sp_canvas_item_destroy(*it); } + group->items.clear(); + group->items.~list(); // invoke manually + if (SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy) { (* SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy)(object); } @@ -966,8 +927,8 @@ void SPCanvasGroup::update(SPCanvasItem *item, Geom::Affine const &affine, unsig SPCanvasGroup const *group = SP_CANVAS_GROUP(item); Geom::OptRect bounds; - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *i = SP_CANVAS_ITEM(list->data); + for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + SPCanvasItem *i = *it; sp_canvas_item_invoke_update (i, affine, flags); @@ -1002,9 +963,8 @@ double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **ac *actual_item = NULL; double dist = 0.0; - - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *child = SP_CANVAS_ITEM(list->data); + for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + SPCanvasItem *child = *it; if ((child->x1 <= x2) && (child->y1 <= y2) && (child->x2 >= x1) && (child->y2 >= y1)) { SPCanvasItem *point_item = NULL; // cater for incomplete item implementations @@ -1037,8 +997,8 @@ void SPCanvasGroup::render(SPCanvasItem *item, SPCanvasBuf *buf) { SPCanvasGroup const *group = SP_CANVAS_GROUP(item); - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *child = SP_CANVAS_ITEM(list->data); + for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + SPCanvasItem *child = *it; if (child->visible) { if ((child->x1 < buf->rect.right()) && (child->y1 < buf->rect.bottom()) && @@ -1056,8 +1016,8 @@ void SPCanvasGroup::viewboxChanged(SPCanvasItem *item, Geom::IntRect const &new_ { SPCanvasGroup *group = SP_CANVAS_GROUP(item); - for (GList *list = group->items; list; list = list->next) { - SPCanvasItem *child = SP_CANVAS_ITEM(list->data); + for (std::list<SPCanvasItem *>::const_iterator it = group->items.begin(); it != group->items.end(); ++it) { + SPCanvasItem *child = *it; if (child->visible) { if (SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed) { SP_CANVAS_ITEM_GET_CLASS(child)->viewbox_changed(child, new_area); @@ -1071,37 +1031,21 @@ void SPCanvasGroup::add(SPCanvasItem *item) g_object_ref(item); g_object_ref_sink(item); - if (!items) { - items = g_list_append(items, item); - last = items; - } else { - last = g_list_append(last, item)->next; - } + items.push_back(item); sp_canvas_item_request_update(item); } void SPCanvasGroup::remove(SPCanvasItem *item) { + g_return_if_fail(item != NULL); + items.remove(item); - for (GList *children = items; children; children = children->next) { - if (children->data == item) { + // Unparent the child + item->parent = NULL; + g_object_unref(item); - // Unparent the child - item->parent = NULL; - g_object_unref(item); - - // Remove it from the list - if (children == last) { - last = children->prev; - } - - items = g_list_remove_link(items, children); - g_list_free(children); - break; - } - } } static void sp_canvas_dispose (GObject *object); diff --git a/src/display/sp-ctrlpoint.cpp b/src/display/sp-ctrlpoint.cpp deleted file mode 100644 index 1082cb1b3..000000000 --- a/src/display/sp-ctrlpoint.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Simple point - * - * Author: - * Maximilian Albert <maximilian.albert@gmail.com> - * Jon A. Cruz <jon@joncruz.org> - * - * Copyright (C) 2008 Maximilian Albert - * - * Released under GNU GPL - */ - -#include "sp-canvas-util.h" -#include "sp-ctrlpoint.h" - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <color.h> -#include "display/cairo-utils.h" -#include "display/sp-canvas.h" - -static void sp_ctrlpoint_destroy(SPCanvasItem *object); - -static void sp_ctrlpoint_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); -static void sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf); - -G_DEFINE_TYPE(SPCtrlPoint, sp_ctrlpoint, SP_TYPE_CANVAS_ITEM); - -static void sp_ctrlpoint_class_init(SPCtrlPointClass *klass) -{ - SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - - item_class->destroy = sp_ctrlpoint_destroy; - item_class->update = sp_ctrlpoint_update; - item_class->render = sp_ctrlpoint_render; -} - -static void -sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint) -{ - ctrlpoint->rgba = 0x0000ff7f; - ctrlpoint->pt[Geom::X] = ctrlpoint->pt[Geom::Y] = 0.0; - ctrlpoint->item=NULL; - ctrlpoint->radius = 2; -} - -static void sp_ctrlpoint_destroy(SPCanvasItem *object) -{ - g_return_if_fail (object != NULL); - g_return_if_fail (SP_IS_CTRLPOINT (object)); - - SPCtrlPoint *ctrlpoint = SP_CTRLPOINT (object); - - ctrlpoint->item=NULL; - - if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy) - SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy(object); -} - -static void -sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf) -{ - SPCtrlPoint *cp = SP_CTRLPOINT (item); - - if (!buf->ct) - return; - - sp_canvas_prepare_buffer (buf); - - guint32 rgba = cp->rgba; - cairo_set_source_rgba(buf->ct, SP_RGBA32_B_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_R_F(rgba), SP_RGBA32_A_F(rgba)); - - cairo_set_line_width(buf->ct, 1); - cairo_new_path(buf->ct); - - Geom::Point pt = cp->pt * cp->affine; - - cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->radius, 0.0, 2 * M_PI); - cairo_stroke(buf->ct); -} - -static void sp_ctrlpoint_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags) -{ - SPCtrlPoint *cp = SP_CTRLPOINT(item); - - item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - - if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update) { - SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update(item, affine, flags); - } - - sp_canvas_item_reset_bounds (item); - - cp->affine = affine; - - Geom::Point pt = cp->pt * affine; - - item->x1 = pt[Geom::X] - cp->radius; - item->y1 = pt[Geom::Y] - cp->radius; - item->x2 = pt[Geom::X] + cp->radius; - item->y2 = pt[Geom::Y] + cp->radius; - - item->canvas->requestRedraw((int)item->x1 - 15, (int)item->y1 - 15, - (int)item->x1 + 15, (int)item->y1 + 15); -} - -void -sp_ctrlpoint_set_color (SPCtrlPoint *cp, guint32 rgba) -{ - g_return_if_fail (cp != NULL); - g_return_if_fail (SP_IS_CTRLPOINT (cp)); - - if (rgba != cp->rgba) { - SPCanvasItem *item; - cp->rgba = rgba; - item = SP_CANVAS_ITEM (cp); - item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - } -} - -#define EPSILON 1e-6 -#define DIFFER(a,b) (fabs ((a) - (b)) > EPSILON) - -void -sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const gdouble x, const gdouble y) -{ - g_return_if_fail (cp != NULL); - g_return_if_fail (SP_IS_CTRLPOINT (cp)); - - if (DIFFER (x, cp->pt[Geom::X]) || DIFFER (y, cp->pt[Geom::Y])) { - cp->pt[Geom::X] = x; - cp->pt[Geom::Y] = y; - sp_canvas_item_request_update (SP_CANVAS_ITEM (cp)); - } -} - -void -sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt) -{ - sp_ctrlpoint_set_coords(cp, pt[Geom::X], pt[Geom::Y]); -} - -void -sp_ctrlpoint_set_radius (SPCtrlPoint *cp, const double r) -{ - cp->radius = r; -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/display/sp-ctrlpoint.h b/src/display/sp-ctrlpoint.h deleted file mode 100644 index a7a5475b7..000000000 --- a/src/display/sp-ctrlpoint.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef SEEN_INKSCAPE_CTRLPOINT_H -#define SEEN_INKSCAPE_CTRLPOINT_H - -/* - * A simple point - * - * Author: - * Maximilian Albert <maximilian.albert@gmail.com> - * - * Copyright (C) 2008 Maximilian Albert - * - * Released under GNU GPL - */ - -#include "sp-canvas-item.h" - -class SPItem; - -#define SP_TYPE_CTRLPOINT (sp_ctrlpoint_get_type ()) -#define SP_CTRLPOINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLPOINT, SPCtrlPoint)) -#define SP_IS_CTRLPOINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLPOINT)) - -struct SPCtrlPoint : public SPCanvasItem { - SPItem *item; // the item to which this line belongs in some sense; may be NULL for some users - guint32 rgba; - Geom::Point pt; - Geom::Affine affine; - double radius; -}; -struct SPCtrlPointClass : public SPCanvasItemClass{}; - -GType sp_ctrlpoint_get_type (void); - -void sp_ctrlpoint_set_color (SPCtrlPoint *cp, guint32 rgba); -void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const gdouble x, const gdouble y); -void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt); -void sp_ctrlpoint_set_radius (SPCtrlPoint *cp, const double r); - - - -#endif // SEEN_INKSCAPE_CTRLPOINT_H - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : |
