summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2016-03-14 16:37:50 +0000
committerJabiertxof <jtx@jtx.marker.es>2016-03-14 16:37:50 +0000
commitb8d22beef5345210ad27cdc2685083aeae6f8f3b (patch)
treed69b8bfd19d3627a8425a1b265c2abf229b05354 /src/display
parentfixes for update to trunk (diff)
parent"Relative to" option for node alignment. (diff)
downloadinkscape-b8d22beef5345210ad27cdc2685083aeae6f8f3b.tar.gz
inkscape-b8d22beef5345210ad27cdc2685083aeae6f8f3b.zip
update to trunk
(bzr r13708.1.39)
Diffstat (limited to 'src/display')
-rw-r--r--src/display/CMakeLists.txt2
-rw-r--r--src/display/Makefile_insert2
-rw-r--r--src/display/cairo-utils.cpp4
-rw-r--r--src/display/canvas-axonomgrid.cpp8
-rw-r--r--src/display/canvas-text.cpp6
-rw-r--r--src/display/curve.cpp2
-rw-r--r--src/display/drawing-image.cpp2
-rw-r--r--src/display/guideline.cpp63
-rw-r--r--src/display/guideline.h6
-rw-r--r--src/display/nr-filter-component-transfer.cpp203
-rw-r--r--src/display/nr-filter-image.cpp2
-rw-r--r--src/display/nr-filter-offset.cpp4
-rw-r--r--src/display/nr-filter-primitive.cpp19
-rw-r--r--src/display/nr-filter-slot.cpp21
-rw-r--r--src/display/nr-filter-slot.h8
-rw-r--r--src/display/nr-filter-tile.cpp99
-rw-r--r--src/display/nr-filter-tile.h1
-rw-r--r--src/display/nr-filter.cpp2
-rw-r--r--src/display/nr-style.cpp2
-rw-r--r--src/display/nr-style.h1
-rw-r--r--src/display/snap-indicator.cpp11
-rw-r--r--src/display/sodipodi-ctrlrect.cpp15
-rw-r--r--src/display/sodipodi-ctrlrect.h3
-rw-r--r--src/display/sp-canvas-item.h2
-rw-r--r--src/display/sp-canvas-util.cpp3
-rw-r--r--src/display/sp-canvas.cpp212
-rw-r--r--src/display/sp-ctrlpoint.cpp159
-rw-r--r--src/display/sp-ctrlpoint.h52
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 :