diff --git a/src/eraser-context.cpp b/src/eraser-context.cpp
index 3ee75eb850a4a20a9f984ebe275dcd4091baa990..559ce28667e7ba224aaf630fd69d367caa3b74ae 100644 (file)
--- a/src/eraser-context.cpp
+++ b/src/eraser-context.cpp
#include "message-context.h"
#include "prefs-utils.h"
#include "pixmaps/cursor-eraser.xpm"
-#include "libnr/n-art-bpath.h"
-#include "libnr/nr-path.h"
-#include "libnr/nr-matrix-ops.h"
-#include "libnr/nr-scale-translate-ops.h"
#include "xml/repr.h"
#include "context-fns.h"
#include "sp-item.h"
#include "display/canvas-bpath.h"
#include "display/canvas-arena.h"
#include "livarot/Shape.h"
-#include "isnan.h"
+#include <2geom/isnan.h>
+#include <2geom/pathvector.h>
#include "eraser-context.h"
@@ -104,24 +101,25 @@ static NR::Point sp_eraser_get_vpoint(SPEraserContext const *erc, NR::Point n);
static void draw_temporary_box(SPEraserContext *dc);
-static SPEventContextClass *parent_class;
+static SPEventContextClass *eraser_parent_class = 0;
-GtkType
-sp_eraser_context_get_type(void)
+GType sp_eraser_context_get_type(void)
{
static GType type = 0;
if (!type) {
GTypeInfo info = {
sizeof(SPEraserContextClass),
- NULL, NULL,
- (GClassInitFunc) sp_eraser_context_class_init,
- NULL, NULL,
+ 0, // base_init
+ 0, // base_finalize
+ (GClassInitFunc)sp_eraser_context_class_init,
+ 0, // class_finalize
+ 0, // class_data
sizeof(SPEraserContext),
- 4,
- (GInstanceInitFunc) sp_eraser_context_init,
- NULL, /* value_table */
+ 0, // n_preallocs
+ (GInstanceInitFunc)sp_eraser_context_init,
+ 0 // value_table
};
- type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPEraserContext", &info, (GTypeFlags)0);
+ type = g_type_register_static(SP_TYPE_COMMON_CONTEXT, "SPEraserContext", &info, static_cast<GTypeFlags>(0));
}
return type;
}
GObjectClass *object_class = (GObjectClass *) klass;
SPEventContextClass *event_context_class = (SPEventContextClass *) klass;
- parent_class = (SPEventContextClass*)g_type_class_peek_parent(klass);
+ eraser_parent_class = (SPEventContextClass*)g_type_class_peek_parent(klass);
object_class->dispose = sp_eraser_context_dispose;
static void
sp_eraser_context_init(SPEraserContext *erc)
{
- SPEventContext *event_context = SP_EVENT_CONTEXT(erc);
-
- event_context->cursor_shape = cursor_eraser_xpm;
- event_context->hot_x = 4;
- event_context->hot_y = 4;
-
- erc->accumulated = NULL;
- erc->segments = NULL;
- erc->currentcurve = NULL;
- erc->currentshape = NULL;
- erc->npoints = 0;
- erc->cal1 = NULL;
- erc->cal2 = NULL;
- erc->repr = NULL;
-
- /* Eraser values */
- erc->cur = NR::Point(0,0);
- erc->last = NR::Point(0,0);
- erc->vel = NR::Point(0,0);
- erc->vel_max = 0;
- erc->acc = NR::Point(0,0);
- erc->ang = NR::Point(0,0);
- erc->del = NR::Point(0,0);
-
- /* attributes */
- erc->dragging = FALSE;
-
- erc->mass = 0.3;
- erc->drag = DRAG_DEFAULT;
- erc->angle = 30.0;
- erc->width = 0.2;
- erc->pressure = ERC_DEFAULT_PRESSURE;
-
- erc->vel_thin = 0.1;
- erc->flatness = 0.9;
- erc->cap_rounding = 0.0;
-
- erc->abs_width = false;
+ erc->cursor_shape = cursor_eraser_xpm;
+ erc->hot_x = 4;
+ erc->hot_y = 4;
}
static void
sp_eraser_context_dispose(GObject *object)
{
- SPEraserContext *erc = SP_ERASER_CONTEXT(object);
+ //SPEraserContext *erc = SP_ERASER_CONTEXT(object);
- if (erc->accumulated) {
- erc->accumulated = sp_curve_unref(erc->accumulated);
- }
-
- while (erc->segments) {
- gtk_object_destroy(GTK_OBJECT(erc->segments->data));
- erc->segments = g_slist_remove(erc->segments, erc->segments->data);
- }
-
- if (erc->currentcurve) erc->currentcurve = sp_curve_unref(erc->currentcurve);
- if (erc->cal1) erc->cal1 = sp_curve_unref(erc->cal1);
- if (erc->cal2) erc->cal2 = sp_curve_unref(erc->cal2);
-
- if (erc->currentshape) {
- gtk_object_destroy(GTK_OBJECT(erc->currentshape));
- erc->currentshape = 0;
- }
-
- if (erc->_message_context) {
- delete erc->_message_context;
- erc->_message_context = 0;
- }
-
- G_OBJECT_CLASS(parent_class)->dispose(object);
+ G_OBJECT_CLASS(eraser_parent_class)->dispose(object);
}
static void
{
SPEraserContext *erc = SP_ERASER_CONTEXT(ec);
- if (((SPEventContextClass *) parent_class)->setup)
- ((SPEventContextClass *) parent_class)->setup(ec);
+ if (((SPEventContextClass *) eraser_parent_class)->setup)
+ ((SPEventContextClass *) eraser_parent_class)->setup(ec);
- erc->accumulated = sp_curve_new_sized(32);
- erc->currentcurve = sp_curve_new_sized(4);
+ erc->accumulated = new SPCurve();
+ erc->currentcurve = new SPCurve();
- erc->cal1 = sp_curve_new_sized(32);
- erc->cal2 = sp_curve_new_sized(32);
+ erc->cal1 = new SPCurve();
+ erc->cal2 = new SPCurve();
erc->currentshape = sp_canvas_item_new(sp_desktop_sketch(ec->desktop), SP_TYPE_CANVAS_BPATH, NULL);
sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(erc->currentshape), ERC_RED_RGBA, SP_WIND_RULE_EVENODD);
static void
sp_eraser_context_set(SPEventContext *ec, gchar const *key, gchar const *val)
{
- SPEraserContext *erc = SP_ERASER_CONTEXT(ec);
-
- if (!strcmp(key, "mass")) {
- double const dval = ( val ? g_ascii_strtod (val, NULL) : 0.2 );
- erc->mass = CLAMP(dval, -1000.0, 1000.0);
- } else if (!strcmp(key, "wiggle")) {
- double const dval = ( val ? g_ascii_strtod (val, NULL) : (1 - DRAG_DEFAULT));
- erc->drag = CLAMP((1 - dval), DRAG_MIN, DRAG_MAX); // drag is inverse to wiggle
- } else if (!strcmp(key, "angle")) {
- double const dval = ( val ? g_ascii_strtod (val, NULL) : 0.0);
- erc->angle = CLAMP (dval, -90, 90);
- } else if (!strcmp(key, "width")) {
- double const dval = ( val ? g_ascii_strtod (val, NULL) : 0.1 );
- erc->width = CLAMP(dval, -1000.0, 1000.0);
- } else if (!strcmp(key, "thinning")) {
- double const dval = ( val ? g_ascii_strtod (val, NULL) : 0.1 );
- erc->vel_thin = CLAMP(dval, -1.0, 1.0);
- } else if (!strcmp(key, "tremor")) {
- double const dval = ( val ? g_ascii_strtod (val, NULL) : 0.0 );
- erc->tremor = CLAMP(dval, 0.0, 1.0);
- } else if (!strcmp(key, "flatness")) {
- double const dval = ( val ? g_ascii_strtod (val, NULL) : 1.0 );
- erc->flatness = CLAMP(dval, 0, 1.0);
- } else if (!strcmp(key, "usepressure")) {
- erc->usepressure = (val && strcmp(val, "0"));
- } else if (!strcmp(key, "usetilt")) {
- erc->usetilt = (val && strcmp(val, "0"));
- } else if (!strcmp(key, "abs_width")) {
- erc->abs_width = (val && strcmp(val, "0"));
- } else if (!strcmp(key, "cap_rounding")) {
- erc->cap_rounding = ( val ? g_ascii_strtod (val, NULL) : 0.0 );
+ //pass on up to parent class to handle common attributes.
+ if ( eraser_parent_class->set ) {
+ eraser_parent_class->set(ec, key, val);
}
-
- //g_print("ERC: %g %g %g %g\n", erc->mass, erc->drag, erc->angle, erc->width);
}
static double
dc->segments = g_slist_remove(dc->segments, dc->segments->data);
}
/* reset accumulated curve */
- sp_curve_reset(dc->accumulated);
+ dc->accumulated->reset();
clear_current(dc);
if (dc->repr) {
dc->repr = NULL;
sp_eraser_reset(dc, button_dt);
sp_eraser_extinput(dc, event);
sp_eraser_apply(dc, button_dt);
- sp_curve_reset(dc->accumulated);
+ dc->accumulated->reset();
if (dc->repr) {
dc->repr = NULL;
}
if (dc->dragging && event->button.button == 1 && !event_context->space_panning) {
dc->dragging = FALSE;
- NR::Maybe<NR::Rect> const b = Inkscape::Rubberband::get()->getRectangle();
+ boost::optional<NR::Rect> const b = Inkscape::Rubberband::get()->getRectangle();
sp_eraser_apply(dc, motion_dt);
set_to_accumulated(dc); // performs document_done
/* reset accumulated curve */
- sp_curve_reset(dc->accumulated);
+ dc->accumulated->reset();
clear_current(dc);
if (dc->repr) {
}
if (!ret) {
- if (((SPEventContextClass *) parent_class)->root_handler) {
- ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event);
+ if (((SPEventContextClass *) eraser_parent_class)->root_handler) {
+ ret = ((SPEventContextClass *) eraser_parent_class)->root_handler(event_context, event);
}
}
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->currentshape), NULL);
// reset curve
- sp_curve_reset(dc->currentcurve);
- sp_curve_reset(dc->cal1);
- sp_curve_reset(dc->cal2);
+ dc->currentcurve->reset();
+ dc->cal1->reset();
+ dc->cal2->reset();
// reset points
dc->npoints = 0;
SPDesktop *desktop = SP_EVENT_CONTEXT(dc)->desktop;
bool workDone = false;
- if (!sp_curve_empty(dc->accumulated)) {
- NArtBpath *abp;
- gchar *str;
-
+ if (!dc->accumulated->is_empty()) {
if (!dc->repr) {
/* Create object */
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());
item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
item->updateRepr();
}
- abp = nr_artpath_affine(sp_curve_first_bpath(dc->accumulated), sp_desktop_dt2root_affine(desktop));
- str = sp_svg_write_path(abp);
+ Geom::PathVector pathv = dc->accumulated->get_pathvector() * sp_desktop_dt2root_affine(desktop);
+ gchar *str = sp_svg_write_path(pathv);
g_assert( str != NULL );
- g_free(abp);
dc->repr->setAttribute("d", str);
g_free(str);
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());
SPItem* acid = SP_ITEM(desktop->doc()->getObjectByRepr(dc->repr));
- NR::Maybe<NR::Rect> eraserBbox = acid->getBounds(NR::identity());
+ boost::optional<NR::Rect> eraserBbox = acid->getBounds(NR::identity());
NR::Rect bounds = (*eraserBbox) * desktop->doc2dt();
std::vector<SPItem*> remainingItems;
GSList* toWorkOn = 0;
for (GSList *i = toWorkOn ; i ; i = i->next ) {
SPItem *item = SP_ITEM(i->data);
if ( eraserMode ) {
- NR::Maybe<NR::Rect> bbox = item->getBounds(NR::identity());
+ boost::optional<NR::Rect> bbox = item->getBounds(NR::identity());
if (bbox && bbox->intersects(*eraserBbox)) {
Inkscape::XML::Node* dup = dc->repr->duplicate(xml_doc);
dc->repr->parent()->appendChild(dup);
}
if ( NR::L2(v_in) > ERASER_EPSILON || NR::L2(v_out) > ERASER_EPSILON ) {
- sp_curve_curveto(curve, from + v_in, to + v_out, to);
+ curve->curveto(from + v_in, to + v_out, to);
}
}
static void
accumulate_eraser(SPEraserContext *dc)
{
- if ( !sp_curve_empty(dc->cal1) && !sp_curve_empty(dc->cal2) ) {
- sp_curve_reset(dc->accumulated); // Is this required ??
- SPCurve *rev_cal2 = sp_curve_reverse(dc->cal2);
+ if ( !dc->cal1->is_empty() && !dc->cal2->is_empty() ) {
+ dc->accumulated->reset(); /* Is this required ?? */
+ SPCurve *rev_cal2 = dc->cal2->create_reverse();
+
+ g_assert(dc->cal1->get_segment_count() > 0);
+ g_assert(rev_cal2->get_segment_count() > 0);
+ g_assert( ! dc->cal1->first_path()->closed() );
+ g_assert( ! rev_cal2->first_path()->closed() );
- g_assert(dc->cal1->end > 1);
- g_assert(rev_cal2->end > 1);
- g_assert(SP_CURVE_SEGMENT(dc->cal1, 0)->code == NR_MOVETO_OPEN);
- g_assert(SP_CURVE_SEGMENT(rev_cal2, 0)->code == NR_MOVETO_OPEN);
- g_assert(SP_CURVE_SEGMENT(dc->cal1, 1)->code == NR_CURVETO);
- g_assert(SP_CURVE_SEGMENT(rev_cal2, 1)->code == NR_CURVETO);
- g_assert(SP_CURVE_SEGMENT(dc->cal1, dc->cal1->end-1)->code == NR_CURVETO);
- g_assert(SP_CURVE_SEGMENT(rev_cal2, rev_cal2->end-1)->code == NR_CURVETO);
+ Geom::CubicBezier const * dc_cal1_firstseg = dynamic_cast<Geom::CubicBezier const *>( dc->cal1->first_segment() );
+ Geom::CubicBezier const * rev_cal2_firstseg = dynamic_cast<Geom::CubicBezier const *>( rev_cal2->first_segment() );
+ Geom::CubicBezier const * dc_cal1_lastseg = dynamic_cast<Geom::CubicBezier const *>( dc->cal1->last_segment() );
+ Geom::CubicBezier const * rev_cal2_lastseg = dynamic_cast<Geom::CubicBezier const *>( rev_cal2->last_segment() );
+ g_assert( dc_cal1_firstseg );
+ g_assert( rev_cal2_firstseg );
+ g_assert( dc_cal1_lastseg );
+ g_assert( rev_cal2_lastseg );
- sp_curve_append(dc->accumulated, dc->cal1, FALSE);
+ dc->accumulated->append(dc->cal1, FALSE);
- add_cap(dc->accumulated, SP_CURVE_SEGMENT(dc->cal1, dc->cal1->end-1)->c(2), SP_CURVE_SEGMENT(dc->cal1, dc->cal1->end-1)->c(3), SP_CURVE_SEGMENT(rev_cal2, 0)->c(3), SP_CURVE_SEGMENT(rev_cal2, 1)->c(1), dc->cap_rounding);
+ add_cap(dc->accumulated, (*dc_cal1_lastseg)[2], (*dc_cal1_lastseg)[3], (*rev_cal2_firstseg)[0], (*rev_cal2_firstseg)[1], dc->cap_rounding);
- sp_curve_append(dc->accumulated, rev_cal2, TRUE);
+ dc->accumulated->append(rev_cal2, TRUE);
- add_cap(dc->accumulated, SP_CURVE_SEGMENT(rev_cal2, rev_cal2->end-1)->c(2), SP_CURVE_SEGMENT(rev_cal2, rev_cal2->end-1)->c(3), SP_CURVE_SEGMENT(dc->cal1, 0)->c(3), SP_CURVE_SEGMENT(dc->cal1, 1)->c(1), dc->cap_rounding);
+ add_cap(dc->accumulated, (*rev_cal2_lastseg)[2], (*rev_cal2_lastseg)[3], (*dc_cal1_firstseg)[0], (*dc_cal1_firstseg)[1], dc->cap_rounding);
- sp_curve_closepath(dc->accumulated);
+ dc->accumulated->closepath();
- sp_curve_unref(rev_cal2);
+ rev_cal2->unref();
- sp_curve_reset(dc->cal1);
- sp_curve_reset(dc->cal2);
+ dc->cal1->reset();
+ dc->cal2->reset();
}
}
#endif
/* Current eraser */
- if ( dc->cal1->end == 0 || dc->cal2->end == 0 ) {
+ if ( dc->cal1->is_empty() || dc->cal2->is_empty() ) {
/* dc->npoints > 0 */
/* g_print("erasers(1|2) reset\n"); */
- sp_curve_reset(dc->cal1);
- sp_curve_reset(dc->cal2);
+ dc->cal1->reset();
+ dc->cal2->reset();
- sp_curve_moveto(dc->cal1, dc->point1[0]);
- sp_curve_moveto(dc->cal2, dc->point2[0]);
+ dc->cal1->moveto(dc->point1[0]);
+ dc->cal2->moveto(dc->point2[0]);
}
NR::Point b1[BEZIER_MAX_LENGTH];
#endif
/* CanvasShape */
if (! release) {
- sp_curve_reset(dc->currentcurve);
- sp_curve_moveto(dc->currentcurve, b1[0]);
+ dc->currentcurve->reset();
+ dc->currentcurve->moveto(b1[0]);
for (NR::Point *bp1 = b1; bp1 < b1 + BEZIER_SIZE * nb1; bp1 += BEZIER_SIZE) {
- sp_curve_curveto(dc->currentcurve, bp1[1],
+ dc->currentcurve->curveto(bp1[1],
bp1[2], bp1[3]);
}
- sp_curve_lineto(dc->currentcurve,
- b2[BEZIER_SIZE*(nb2-1) + 3]);
+ dc->currentcurve->lineto(b2[BEZIER_SIZE*(nb2-1) + 3]);
for (NR::Point *bp2 = b2 + BEZIER_SIZE * ( nb2 - 1 ); bp2 >= b2; bp2 -= BEZIER_SIZE) {
- sp_curve_curveto(dc->currentcurve, bp2[2], bp2[1], bp2[0]);
+ dc->currentcurve->curveto(bp2[2], bp2[1], bp2[0]);
}
// FIXME: dc->segments is always NULL at this point??
if (!dc->segments) { // first segment
add_cap(dc->currentcurve, b2[1], b2[0], b1[0], b1[1], dc->cap_rounding);
}
- sp_curve_closepath(dc->currentcurve);
+ dc->currentcurve->closepath();
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->currentshape), dc->currentcurve);
}
/* Current eraser */
for (NR::Point *bp1 = b1; bp1 < b1 + BEZIER_SIZE * nb1; bp1 += BEZIER_SIZE) {
- sp_curve_curveto(dc->cal1, bp1[1], bp1[2], bp1[3]);
+ dc->cal1->curveto(bp1[1], bp1[2], bp1[3]);
}
for (NR::Point *bp2 = b2; bp2 < b2 + BEZIER_SIZE * nb2; bp2 += BEZIER_SIZE) {
- sp_curve_curveto(dc->cal2, bp2[1], bp2[2], bp2[3]);
+ dc->cal2->curveto(bp2[1], bp2[2], bp2[3]);
}
} else {
/* fixme: ??? */
draw_temporary_box(dc);
for (gint i = 1; i < dc->npoints; i++) {
- sp_curve_lineto(dc->cal1, dc->point1[i]);
+ dc->cal1->lineto(dc->point1[i]);
}
for (gint i = 1; i < dc->npoints; i++) {
- sp_curve_lineto(dc->cal2, dc->point2[i]);
+ dc->cal2->lineto(dc->point2[i]);
}
}
#endif
if (!release) {
gint eraserMode = (prefs_get_int_attribute("tools.eraser", "mode", 0) != 0) ? 1 : 0;
- g_assert(!sp_curve_empty(dc->currentcurve));
+ g_assert(!dc->currentcurve->is_empty());
SPCanvasItem *cbp = sp_canvas_item_new(sp_desktop_sketch(SP_EVENT_CONTEXT(dc)->desktop),
SP_TYPE_CANVAS_BPATH,
NULL);
- SPCurve *curve = sp_curve_copy(dc->currentcurve);
+ SPCurve *curve = dc->currentcurve->copy();
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH (cbp), curve);
- sp_curve_unref(curve);
+ curve->unref();
guint32 fillColor = sp_desktop_get_color_tool (SP_ACTIVE_DESKTOP, "tools.eraser", true);
//guint32 strokeColor = sp_desktop_get_color_tool (SP_ACTIVE_DESKTOP, "tools.eraser", false);
static void
draw_temporary_box(SPEraserContext *dc)
{
- sp_curve_reset(dc->currentcurve);
+ dc->currentcurve->reset();
- sp_curve_moveto(dc->currentcurve, dc->point1[dc->npoints-1]);
+ dc->currentcurve->moveto(dc->point1[dc->npoints-1]);
for (gint i = dc->npoints-2; i >= 0; i--) {
- sp_curve_lineto(dc->currentcurve, dc->point1[i]);
+ dc->currentcurve->lineto(dc->point1[i]);
}
for (gint i = 0; i < dc->npoints; i++) {
- sp_curve_lineto(dc->currentcurve, dc->point2[i]);
+ dc->currentcurve->lineto(dc->point2[i]);
}
if (dc->npoints >= 2) {
add_cap(dc->currentcurve, dc->point2[dc->npoints-2], dc->point2[dc->npoints-1], dc->point1[dc->npoints-1], dc->point1[dc->npoints-2], dc->cap_rounding);
}
- sp_curve_closepath(dc->currentcurve);
+ dc->currentcurve->closepath();
sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->currentshape), dc->currentcurve);
}