diff options
Diffstat (limited to 'src')
146 files changed, 1997 insertions, 1494 deletions
diff --git a/src/2geom/piecewise.cpp b/src/2geom/piecewise.cpp index 2d8638818..4c63b20df 100644 --- a/src/2geom/piecewise.cpp +++ b/src/2geom/piecewise.cpp @@ -158,7 +158,6 @@ std::vector<double> roots(Piecewise<SBasis> const &f){ std::vector<double> result; for (unsigned i=0; i<f.size(); i++){ std::vector<double> rts=roots(f.segs[i]); - rts=roots(f.segs[i]); for (unsigned r=0; r<rts.size(); r++){ result.push_back(f.mapToDomain(rts[r], i)); @@ -167,6 +166,18 @@ std::vector<double> roots(Piecewise<SBasis> const &f){ return result; } +std::vector<std::vector<double> > multi_roots(Piecewise<SBasis> const &f, std::vector<double> const &values) { + std::vector<std::vector<double> > result(values.size()); + for (unsigned i=0; i<f.size(); i++) { + std::vector<std::vector<double> > rts = multi_roots(f.segs[i], values); + for(unsigned j=0; j<rts.size(); j++) { + for(unsigned r=0; r<rts[j].size(); r++){ + result[j].push_back(f.mapToDomain(rts[j][r], i)); + } + } + } + return result; +} } /* diff --git a/src/2geom/piecewise.h b/src/2geom/piecewise.h index 3979643b2..d25c04bc4 100644 --- a/src/2geom/piecewise.h +++ b/src/2geom/piecewise.h @@ -706,6 +706,8 @@ Piecewise<T> derivative(Piecewise<T> const &a) { std::vector<double> roots(Piecewise<SBasis> const &f); +std::vector<std::vector<double> >multi_roots(Piecewise<SBasis> const &f, std::vector<double> const &values); + template<typename T> Piecewise<T> reverse(Piecewise<T> const &f) { Piecewise<T> ret = Piecewise<T>(); diff --git a/src/2geom/rect.h b/src/2geom/rect.h index f8ac7a2f7..ee1b0d764 100644 --- a/src/2geom/rect.h +++ b/src/2geom/rect.h @@ -140,6 +140,18 @@ inline Rect unify(Rect const & a, Rect const & b) { return Rect(unify(a[X], b[X]), unify(a[Y], b[Y])); } +/** Returns the smallest rectangle that encloses both rectangles. + * An empty argument is assumed to be an empty rectangle */ +inline boost::optional<Rect> unify(boost::optional<Rect> const & a, boost::optional<Rect> const & b) { + if (!a) { + return b; + } else if (!b) { + return a; + } else { + return unify(*a, *b); + } +} + inline Rect union_list(std::vector<Rect> const &r) { if(r.empty()) return Rect(Interval(0,0), Interval(0,0)); Rect ret = r[0]; diff --git a/src/2geom/sbasis.cpp b/src/2geom/sbasis.cpp index 377238d92..a7e049def 100644 --- a/src/2geom/sbasis.cpp +++ b/src/2geom/sbasis.cpp @@ -70,9 +70,9 @@ bool SBasis::isFinite() const { std::vector<double> SBasis::valueAndDerivatives(double t, unsigned n) const { std::vector<double> ret(n+1); - ret.push_back(valueAt(t)); + ret[0]=valueAt(t); SBasis tmp = *this; - for(unsigned i = 0; i < n; i++) { + for(unsigned i = 1; i < n+1; i++) { tmp.derive(); ret[i] = tmp.valueAt(t); } diff --git a/src/2geom/transforms.h b/src/2geom/transforms.h index 898b095b5..d21c5c617 100644 --- a/src/2geom/transforms.h +++ b/src/2geom/transforms.h @@ -84,6 +84,7 @@ class Rotate { explicit Rotate(Coord x, Coord y) { Rotate(Point(x, y)); } inline operator Matrix() const { return Matrix(vec[X], vec[Y], -vec[Y], vec[X], 0, 0); } + inline Point vector() const { return vec; } inline Coord operator[](Dim2 const dim) const { return vec[dim]; } inline Coord operator[](unsigned const dim) const { return vec[dim]; } inline bool operator==(Rotate const &o) const { return vec == o.vec; } diff --git a/src/box3d.cpp b/src/box3d.cpp index 3a2c09438..548132bdc 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -51,7 +51,7 @@ static void box3d_update(SPObject *object, SPCtx *ctx, guint flags); static Inkscape::XML::Node *box3d_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); static gchar *box3d_description(SPItem *item); -static NR::Matrix box3d_set_transform(SPItem *item, NR::Matrix const &xform); +static Geom::Matrix box3d_set_transform(SPItem *item, Geom::Matrix const &xform); static void box3d_convert_to_guides(SPItem *item); static void box3d_ref_changed(SPObject *old_ref, SPObject *ref, SPBox3D *box); @@ -327,8 +327,8 @@ box3d_position_set (SPBox3D *box) } } -static NR::Matrix -box3d_set_transform(SPItem *item, NR::Matrix const &xform) +static Geom::Matrix +box3d_set_transform(SPItem *item, Geom::Matrix const &xform) { SPBox3D *box = SP_BOX3D(item); @@ -363,7 +363,7 @@ box3d_set_transform(SPItem *item, NR::Matrix const &xform) persp3d_unset_transforms(transf_persp); } - NR::Matrix ret(NR::transform(xform)); + Geom::Matrix ret(Geom::Matrix(xform).without_translation()); gdouble const sw = hypot(ret[0], ret[1]); gdouble const sh = hypot(ret[2], ret[3]); @@ -385,7 +385,7 @@ box3d_set_transform(SPItem *item, NR::Matrix const &xform) } } - return NR::identity(); + return Geom::identity(); } Proj::Pt3 @@ -491,7 +491,7 @@ box3d_snap (SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &sta // determine the distances to all potential snapping points double snap_dists[num_snap_lines]; for (int i = 0; i < num_snap_lines; ++i) { - snap_dists[i] = NR::L2 (snap_pts[i] - pt) * zoom; + snap_dists[i] = Geom::L2 (snap_pts[i] - pt) * zoom; } // while we are within a given tolerance of the starting point, @@ -714,7 +714,7 @@ box3d_XY_axes_are_swapped (SPBox3D *box) { v1.normalize(); v2.normalize(); - return (v1[NR::X]*v2[NR::Y] - v1[NR::Y]*v2[NR::X] > 0); + return (v1[Geom::X]*v2[Geom::Y] - v1[Geom::Y]*v2[Geom::X] > 0); } static inline void @@ -1054,12 +1054,12 @@ box3d_recompute_z_orders (SPBox3D *box) { Geom::Point vp_x = persp3d_get_VP(persp, Proj::X).affine(); Geom::Point vp_y = persp3d_get_VP(persp, Proj::Y).affine(); Geom::Point vp_z = persp3d_get_VP(persp, Proj::Z).affine(); - Geom::Point vpx(vp_x[NR::X], vp_x[NR::Y]); - Geom::Point vpy(vp_y[NR::X], vp_y[NR::Y]); - Geom::Point vpz(vp_z[NR::X], vp_z[NR::Y]); + Geom::Point vpx(vp_x[Geom::X], vp_x[Geom::Y]); + Geom::Point vpy(vp_y[Geom::X], vp_y[Geom::Y]); + Geom::Point vpz(vp_z[Geom::X], vp_z[Geom::Y]); Geom::Point c3 = box3d_get_corner_screen(box, 3, false); - Geom::Point corner3(c3[NR::X], c3[NR::Y]); + Geom::Point corner3(c3[Geom::X], c3[Geom::Y]); if (box3d_half_line_crosses_joining_line (corner3, vpx, vpy, vpz)) { central_axis = Box3D::X; @@ -1081,9 +1081,9 @@ box3d_recompute_z_orders (SPBox3D *box) { Geom::Point c2(box3d_get_corner_screen(box, 2, false)); Geom::Point c7(box3d_get_corner_screen(box, 7, false)); - Geom::Point corner1(c1[NR::X], c1[NR::Y]); - Geom::Point corner2(c2[NR::X], c2[NR::Y]); - Geom::Point corner7(c7[NR::X], c7[NR::Y]); + Geom::Point corner1(c1[Geom::X], c1[Geom::Y]); + Geom::Point corner2(c2[Geom::X], c2[Geom::Y]); + Geom::Point corner7(c7[Geom::X], c7[Geom::Y]); // FIXME: At present we don't use the information about central_corner computed above. switch (central_axis) { case Box3D::Y: diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index a64708332..5a09f8765 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -193,7 +193,7 @@ static Avoid::Polygn avoid_item_poly(SPItem const *item) // by the sp_*_update functions, e.g., text. sp_document_ensure_up_to_date(item->document); - boost::optional<NR::Rect> rHull = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> rHull = item->getBounds(sp_item_i2doc_affine(item)); if (!rHull) { return Avoid::newPoly(0); } @@ -201,7 +201,8 @@ static Avoid::Polygn avoid_item_poly(SPItem const *item) double spacing = desktop->namedview->connector_spacing; // Add a little buffer around the edge of each object. - NR::Rect rExpandedHull = NR::expand(*rHull, -spacing); + Geom::Rect rExpandedHull = *rHull; + rExpandedHull.expandBy(-spacing); poly = Avoid::newPoly(4); for (unsigned n = 0; n < 4; ++n) { @@ -238,7 +239,7 @@ GSList *get_avoided_items(GSList *list, SPObject *from, SPDesktop *desktop, } -void avoid_item_move(NR::Matrix const */*mp*/, SPItem *moved_item) +void avoid_item_move(Geom::Matrix const */*mp*/, SPItem *moved_item) { Avoid::ShapeRef *shapeRef = moved_item->avoidRef->shapeRef; g_assert(shapeRef); diff --git a/src/conn-avoid-ref.h b/src/conn-avoid-ref.h index cd6b60542..d34d8ca2e 100644 --- a/src/conn-avoid-ref.h +++ b/src/conn-avoid-ref.h @@ -52,7 +52,7 @@ private: extern GSList *get_avoided_items(GSList *list, SPObject *from, SPDesktop *desktop, bool initialised = true); -extern void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item); +extern void avoid_item_move(Geom::Matrix const *mp, SPItem *moved_item); extern void init_avoided_shape_geometry(SPDesktop *desktop); static const double defaultConnSpacing = 3.0; diff --git a/src/connector-context.cpp b/src/connector-context.cpp index c982a8c89..527ba720f 100644 --- a/src/connector-context.cpp +++ b/src/connector-context.cpp @@ -1148,9 +1148,9 @@ static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item) } - boost::optional<NR::Rect> bbox = sp_item_bbox_desktop(cc->active_shape); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(cc->active_shape); if (bbox) { - NR::Point center = bbox->midpoint(); + Geom::Point center = bbox->midpoint(); sp_knot_set_position(cc->connpthandle, center, 0); sp_knot_show(cc->connpthandle); } else { diff --git a/src/desktop.cpp b/src/desktop.cpp index 004a0116e..eb4a50410 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -156,7 +156,7 @@ SPDesktop::SPDesktop() : _active( false ), _w2d(), _d2w(), - _doc2dt( NR::Matrix(NR::scale(1, -1)) ), + _doc2dt( NR::Matrix(Geom::Scale(1, -1)) ), grids_visible( false ) { _d2w.setIdentity(); @@ -534,9 +534,9 @@ bool SPDesktop::isLayer(SPObject *object) const { bool SPDesktop::isWithinViewport (SPItem *item) const { Geom::Rect const viewport = get_display_area(); - boost::optional<NR::Rect> const bbox = sp_item_bbox_desktop(item); + boost::optional<Geom::Rect> const bbox = sp_item_bbox_desktop(item); if (bbox) { - return viewport.contains(to_2geom(*bbox)); + return viewport.contains(*bbox); } else { return true; } @@ -773,8 +773,8 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double int clear = FALSE; if (!NR_DF_TEST_CLOSE (newscale, scale, 1e-4 * scale)) { /* Set zoom factors */ - _d2w = NR::Matrix(NR::scale(newscale, -newscale)); - _w2d = NR::Matrix(NR::scale(1/newscale, 1/-newscale)); + _d2w = NR::Matrix(Geom::Scale(newscale, -newscale)); + _w2d = NR::Matrix(Geom::Scale(1/newscale, 1/-newscale)); sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w); clear = TRUE; } @@ -939,7 +939,7 @@ SPDesktop::zoom_quick (bool enable) } if (!zoomed) { - boost::optional<Geom::Rect> const d = selection->bounds_2geom(); + boost::optional<Geom::Rect> const d = selection->bounds(); if (d && !d->isEmpty() && d->area() * 2.0 < _quick_zoom_stored_area.area()) { set_display_area(*d, 10); zoomed = true; @@ -1072,7 +1072,7 @@ SPDesktop::zoom_page_width() void SPDesktop::zoom_selection() { - boost::optional<Geom::Rect> const d = to_2geom(selection->bounds()); + boost::optional<Geom::Rect> const d = selection->bounds(); // FIXME: the original NR::Rect::isEmpty call contained an additional threshold of 0.1; is it safe to ignore it? if ( !d || d->isEmpty() ) { @@ -1101,7 +1101,7 @@ SPDesktop::zoom_drawing() SPItem *docitem = SP_ITEM (sp_document_root (doc())); g_return_if_fail (docitem != NULL); - boost::optional<Geom::Rect> d = to_2geom(sp_item_bbox_desktop(docitem)); + boost::optional<Geom::Rect> d = sp_item_bbox_desktop(docitem); /* Note that the second condition here indicates that ** there are no items in the drawing. diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp index 1094571f5..c27c2b666 100644 --- a/src/dialogs/clonetiler.cpp +++ b/src/dialogs/clonetiler.cpp @@ -896,10 +896,10 @@ clonetiler_trace_pick (NR::Rect box) if (!trace_arena) return 0; - NR::Matrix t(NR::scale(trace_zoom, trace_zoom)); + Geom::Matrix t(Geom::Scale(trace_zoom, trace_zoom)); nr_arena_item_set_transform(trace_root, &t); NRGC gc(NULL); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update( trace_root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE ); @@ -1248,13 +1248,13 @@ clonetiler_apply( GtkWidget */*widget*/, void * ) bool prefs_bbox = prefs->getBool("tools", "bounding_box", false); SPItem::BBoxType bbox_type = ( prefs_bbox ? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX ); - boost::optional<NR::Rect> r = SP_ITEM(obj)->getBounds(sp_item_i2doc_affine(SP_ITEM(obj)), + boost::optional<Geom::Rect> r = SP_ITEM(obj)->getBounds(sp_item_i2doc_affine(SP_ITEM(obj)), bbox_type); if (r) { - w = r->dimensions()[NR::X]; - h = r->dimensions()[NR::Y]; - x0 = r->min()[NR::X]; - y0 = r->min()[NR::Y]; + w = r->dimensions()[Geom::X]; + h = r->dimensions()[Geom::Y]; + x0 = r->min()[Geom::X]; + y0 = r->min()[Geom::Y]; center = desktop->dt2doc(SP_ITEM(obj)->getCenter()); sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", center[Geom::X]); diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp index 5e23f0656..816a50754 100644 --- a/src/dialogs/export.cpp +++ b/src/dialogs/export.cpp @@ -778,7 +778,7 @@ sp_export_selection_modified ( Inkscape::Application */*inkscape*/, if ( SP_ACTIVE_DESKTOP ) { SPDocument *doc; doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - boost::optional<Geom::Rect> bbox = to_2geom(sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)))); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); if (bbox) { sp_export_set_area (base, bbox->min()[Geom::X], bbox->min()[Geom::Y], @@ -847,7 +847,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) case SELECTION_SELECTION: if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - bbox = to_2geom((sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds()); + bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->bounds(); /* Only if there is a selection that we can set do we break, otherwise we fall through to the drawing */ @@ -859,7 +859,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) /** \todo * This returns wrong values if the document has a viewBox. */ - bbox = to_2geom(sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)))); + bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); /* If the drawing is valid, then we'll use it and break otherwise we drop through to the page settings */ if (bbox) { @@ -1407,7 +1407,7 @@ sp_export_detect_size(GtkObject * base) { switch (this_test[i]) { case SELECTION_SELECTION: if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - boost::optional<Geom::Rect> bbox = to_2geom((sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds()); + boost::optional<Geom::Rect> bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(); //std::cout << "Selection " << bbox; if ( bbox && sp_export_bbox_equal(*bbox,current_bbox)) { @@ -1418,7 +1418,7 @@ sp_export_detect_size(GtkObject * base) { case SELECTION_DRAWING: { SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - boost::optional<Geom::Rect> bbox = to_2geom(sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)))); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); // std::cout << "Drawing " << bbox2; if ( bbox && sp_export_bbox_equal(*bbox,current_bbox) ) { diff --git a/src/dialogs/layers-panel.cpp b/src/dialogs/layers-panel.cpp index c41d8ccb4..a8c55f9de 100644 --- a/src/dialogs/layers-panel.cpp +++ b/src/dialogs/layers-panel.cpp @@ -88,6 +88,17 @@ static gboolean layers_panel_activated( GtkObject */*object*/, GdkEvent * /*even return FALSE; } +static gboolean layers_panel_deactivated( GtkObject */*object*/, GdkEvent * /*event*/, gpointer data ) +{ + if ( data ) + { + LayersPanel* panel = reinterpret_cast<LayersPanel*>(data); + panel->setDesktop(NULL); + } + + return FALSE; +} + void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) { @@ -710,6 +721,7 @@ LayersPanel::LayersPanel() : } g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK( layers_panel_activated ), this ); + g_signal_connect( G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK( layers_panel_deactivated ), this ); setDesktop( targetDesktop ); show_all_children(); @@ -719,6 +731,8 @@ LayersPanel::LayersPanel() : LayersPanel::~LayersPanel() { + setDesktop(NULL); + _compositeSettings.setSubject(NULL); if ( _model ) diff --git a/src/dialogs/stroke-style.cpp b/src/dialogs/stroke-style.cpp index fe621e4f1..00e308278 100644 --- a/src/dialogs/stroke-style.cpp +++ b/src/dialogs/stroke-style.cpp @@ -592,7 +592,7 @@ sp_marker_prev_new(unsigned psize, gchar const *mname, // Find object's bbox in document Geom::Matrix const i2doc(sp_item_i2doc_affine(SP_ITEM(object))); - boost::optional<NR::Rect> dbox = SP_ITEM(object)->getBounds(i2doc); + boost::optional<Geom::Rect> dbox = SP_ITEM(object)->getBounds(i2doc); if (!dbox) { return NULL; @@ -608,7 +608,7 @@ sp_marker_prev_new(unsigned psize, gchar const *mname, Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(svg_preview_cache.get_preview_from_cache(key)); if (!pixbuf) { - pixbuf = Glib::wrap(render_pixbuf(root, sf, to_2geom(*dbox), psize)); + pixbuf = Glib::wrap(render_pixbuf(root, sf, *dbox, psize)); svg_preview_cache.set_preview_in_cache(key, pixbuf->gobj()); } diff --git a/src/dialogs/tiledialog.cpp b/src/dialogs/tiledialog.cpp index 99919d127..1643057e8 100644 --- a/src/dialogs/tiledialog.cpp +++ b/src/dialogs/tiledialog.cpp @@ -48,8 +48,8 @@ sp_compare_x_position(SPItem *first, SPItem *second) using Geom::X; using Geom::Y; - boost::optional<Geom::Rect> a = to_2geom(first->getBounds(sp_item_i2doc_affine(first))); - boost::optional<Geom::Rect> b = to_2geom(second->getBounds(sp_item_i2doc_affine(second))); + boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first)); + boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second)); if ( !a || !b ) { // FIXME? @@ -88,8 +88,8 @@ sp_compare_x_position(SPItem *first, SPItem *second) int sp_compare_y_position(SPItem *first, SPItem *second) { - boost::optional<Geom::Rect> a = to_2geom(first->getBounds(sp_item_i2doc_affine(first))); - boost::optional<Geom::Rect> b = to_2geom(second->getBounds(sp_item_i2doc_affine(second))); + boost::optional<Geom::Rect> a = first->getBounds(sp_item_i2doc_affine(first)); + boost::optional<Geom::Rect> b = second->getBounds(sp_item_i2doc_affine(second)); if ( !a || !b ) { // FIXME? @@ -168,7 +168,7 @@ void TileDialog::Grid_Arrange () cnt=0; for (; items != NULL; items = items->next) { SPItem *item = SP_ITEM(items->data); - boost::optional<Geom::Rect> b = to_2geom(item->getBounds(sp_item_i2doc_affine(item))); + boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item)); if (!b) { continue; } @@ -210,7 +210,7 @@ void TileDialog::Grid_Arrange () const GSList *sizes = sorted; for (; sizes != NULL; sizes = sizes->next) { SPItem *item = SP_ITEM(sizes->data); - boost::optional<Geom::Rect> b = to_2geom(item->getBounds(sp_item_i2doc_affine(item))); + boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item)); if (b) { width = b->dimensions()[Geom::X]; height = b->dimensions()[Geom::Y]; @@ -267,7 +267,7 @@ void TileDialog::Grid_Arrange () } - boost::optional<Geom::Rect> sel_bbox = to_2geom(selection->bounds()); + boost::optional<Geom::Rect> sel_bbox = selection->bounds(); // Fit to bbox, calculate padding between rows accordingly. if ( sel_bbox && !SpaceManualRadioButton.get_active() ){ #ifdef DEBUG_GRID_ARRANGE @@ -317,7 +317,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h for (; current_row != NULL; current_row = current_row->next) { SPItem *item=SP_ITEM(current_row->data); Inkscape::XML::Node *repr = SP_OBJECT_REPR(item); - boost::optional<Geom::Rect> b = to_2geom(item->getBounds(sp_item_i2doc_affine(item))); + boost::optional<Geom::Rect> b = item->getBounds(sp_item_i2doc_affine(item)); Geom::Point min; if (b) { width = b->dimensions()[Geom::X]; @@ -345,11 +345,8 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h g_slist_free (current_row); } - NRRect b; - selection->bounds(&b); - - sp_document_done (sp_desktop_document (desktop), SP_VERB_SELECTION_GRIDTILE, - _("Arrange in a grid")); + sp_document_done (sp_desktop_document (desktop), SP_VERB_SELECTION_GRIDTILE, + _("Arrange in a grid")); } diff --git a/src/dialogs/unclump.cpp b/src/dialogs/unclump.cpp index 9e4fce1e7..1329fdb5f 100644 --- a/src/dialogs/unclump.cpp +++ b/src/dialogs/unclump.cpp @@ -35,7 +35,7 @@ unclump_center (SPItem *item) return i->second; } - boost::optional<Geom::Rect> r = to_2geom(item->getBounds(sp_item_i2d_affine(item))); + boost::optional<Geom::Rect> r = item->getBounds(sp_item_i2d_affine(item)); if (r) { Geom::Point const c = r->midpoint(); c_cache[SP_OBJECT_ID(item)] = c; @@ -54,7 +54,7 @@ unclump_wh (SPItem *item) if ( i != wh_cache.end() ) { wh = i->second; } else { - boost::optional<Geom::Rect> r = to_2geom(item->getBounds(sp_item_i2d_affine(item))); + boost::optional<Geom::Rect> r = item->getBounds(sp_item_i2d_affine(item)); if (r) { wh = r->dimensions(); wh_cache[SP_OBJECT_ID(item)] = wh; diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index 8342ff7ff..1900ed961 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -160,7 +160,7 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) sp_canvas_prepare_buffer(buf); - NR::Rect area (NR::Point(buf->rect.x0, buf->rect.y0), NR::Point(buf->rect.x1, buf->rect.y1)); + Geom::Rect area (Geom::Point(buf->rect.x0, buf->rect.y0), Geom::Point(buf->rect.x1, buf->rect.y1)); if ( !cbp->curve || ((cbp->stroke_rgba & 0xff) == 0 && (cbp->fill_rgba & 0xff) == 0 ) || diff --git a/src/display/curve.cpp b/src/display/curve.cpp index 52ffe4f5b..5a1e2abeb 100644 --- a/src/display/curve.cpp +++ b/src/display/curve.cpp @@ -200,6 +200,7 @@ SPCurve::moveto(gdouble x, gdouble y) } /** * Perform a moveto to a point, thus starting a new subpath. + * Point p must be finite. */ void SPCurve::moveto(Geom::Point const &p) @@ -209,16 +210,17 @@ SPCurve::moveto(Geom::Point const &p) } /** - * Calls SPCurve::lineto() with a point's coordinates. + * Adds a line to the current subpath. + * Point p must be finite. */ void SPCurve::lineto(Geom::Point const &p) { - if (_pathv.empty()) g_message("SPCurve::lineto path is empty!"); + if (_pathv.empty()) g_message("SPCurve::lineto - path is empty!"); else _pathv.back().appendNew<Geom::LineSegment>( p ); } /** - * Adds a line to the current subpath. + * Calls SPCurve::lineto( Geom::Point(x,y) ) */ void SPCurve::lineto(gdouble x, gdouble y) @@ -227,16 +229,38 @@ SPCurve::lineto(gdouble x, gdouble y) } /** - * Calls SPCurve::curveto() with coordinates of three points. + * Adds a quadratic bezier segment to the current subpath. + * All points must be finite. + */ +void +SPCurve::quadto(Geom::Point const &p1, Geom::Point const &p2) +{ + if (_pathv.empty()) g_message("SPCurve::quadto - path is empty!"); + else _pathv.back().appendNew<Geom::QuadraticBezier>( p1, p2); +} +/** + * Calls SPCurve::quadto( Geom::Point(x1,y1), Geom::Point(x2,y2) ) + * All coordinates must be finite. + */ +void +SPCurve::quadto(gdouble x1, gdouble y1, gdouble x2, gdouble y2) +{ + quadto( Geom::Point(x1,y1), Geom::Point(x2,y2) ); +} + +/** + * Adds a bezier segment to the current subpath. + * All points must be finite. */ void SPCurve::curveto(Geom::Point const &p0, Geom::Point const &p1, Geom::Point const &p2) { - if (_pathv.empty()) g_message("SPCurve::lineto path is empty!"); + if (_pathv.empty()) g_message("SPCurve::curveto - path is empty!"); else _pathv.back().appendNew<Geom::CubicBezier>( p0, p1, p2 ); } /** - * Adds a bezier segment to the current subpath. + * Calls SPCurve::curveto( Geom::Point(x0,y0), Geom::Point(x1,y1), Geom::Point(x2,y2) ) + * All coordinates must be finite. */ void SPCurve::curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2) diff --git a/src/display/curve.h b/src/display/curve.h index 1b09c8c6e..79a385b09 100644 --- a/src/display/curve.h +++ b/src/display/curve.h @@ -59,6 +59,8 @@ public: void moveto(gdouble x, gdouble y); void lineto(Geom::Point const &p); void lineto(gdouble x, gdouble y); + void quadto(Geom::Point const &p1, Geom::Point const &p2); + void quadto(gdouble x1, gdouble y1, gdouble x2, gdouble y2); void curveto(Geom::Point const &p0, Geom::Point const &p1, Geom::Point const &p2); void curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void closepath(); diff --git a/src/display/inkscape-cairo.cpp b/src/display/inkscape-cairo.cpp index 2ef726aab..54f979f37 100644 --- a/src/display/inkscape-cairo.cpp +++ b/src/display/inkscape-cairo.cpp @@ -170,7 +170,7 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path) /** Feeds path-creating calls to the cairo context translating them from the Path, with the given transform and shift */ static void -feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, boost::optional<NR::Rect> area, bool optimize_stroke, double stroke_width) +feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, boost::optional<Geom::Rect> area, bool optimize_stroke, double stroke_width) { if (!area || area->isEmpty()) return; @@ -179,9 +179,9 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, boo // Transform all coordinates to coords within "area" Geom::Point shift = area->min(); - NR::Rect view = *area; - view.growBy (stroke_width); - view = view * (NR::Matrix)Geom::Translate(-shift); + Geom::Rect view = *area; + view.expandBy (stroke_width); + view = view * (Geom::Matrix)Geom::Translate(-shift); // Pass transformation to feed_curve, so that we don't need to create a whole new path. Geom::Matrix transshift(trans * Geom::Translate(-shift)); @@ -189,7 +189,7 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, boo cairo_move_to(ct, initial[0], initial[1] ); for(Geom::Path::const_iterator cit = path.begin(); cit != path.end_open(); ++cit) { - feed_curve_to_cairo(ct, *cit, transshift, to_2geom(view), optimize_stroke); + feed_curve_to_cairo(ct, *cit, transshift, view, optimize_stroke); } if (path.closed()) { @@ -214,7 +214,7 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path, Geom::Matrix trans, boo /** Feeds path-creating calls to the cairo context translating them from the PathVector, with the given transform and shift * One must have done cairo_new_path(ct); before calling this function. */ void -feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, boost::optional<NR::Rect> area, bool optimize_stroke, double stroke_width) +feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, boost::optional<Geom::Rect> area, bool optimize_stroke, double stroke_width) { if (!area || area->isEmpty()) return; diff --git a/src/display/inkscape-cairo.h b/src/display/inkscape-cairo.h index f3be94464..4a9c15ae3 100644 --- a/src/display/inkscape-cairo.h +++ b/src/display/inkscape-cairo.h @@ -21,7 +21,7 @@ class SPCanvasBuf; cairo_t *nr_create_cairo_context_canvasbuf (NRRectL *area, SPCanvasBuf *b); cairo_t *nr_create_cairo_context (NRRectL *area, NRPixBlock *pb); -void feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, boost::optional<NR::Rect> area, bool optimize_stroke, double stroke_width); +void feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv, Geom::Matrix trans, boost::optional<Geom::Rect> area, bool optimize_stroke, double stroke_width); void feed_pathvector_to_cairo (cairo_t *ct, Geom::PathVector const &pathv); #endif diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index 6bb64f8d0..5f20d077a 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -47,7 +47,7 @@ static void nr_arena_glyphs_finalize(NRObject *object); static guint nr_arena_glyphs_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset); static guint nr_arena_glyphs_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb); -static NRArenaItem *nr_arena_glyphs_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); +static NRArenaItem *nr_arena_glyphs_pick(NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky); static NRArenaItemClass *glyphs_parent_class; @@ -145,8 +145,8 @@ nr_arena_glyphs_update(NRArenaItem *item, NRRectL */*area*/, NRGC *gc, guint /*s float const scale = NR::expansion(gc->transform); if (!glyphs->style->fill.isNone()) { - NR::Matrix t; - t = glyphs->g_transform * gc->transform; + Geom::Matrix t; + t = to_2geom(glyphs->g_transform) * gc->transform; glyphs->x = t[4]; glyphs->y = t[5]; t[4]=0; @@ -167,8 +167,8 @@ nr_arena_glyphs_update(NRArenaItem *item, NRRectL */*area*/, NRGC *gc, guint /*s if (!glyphs->style->stroke.isNone()) { /* Build state data */ - NR::Matrix t; - t = glyphs->g_transform * gc->transform; + Geom::Matrix t; + t = to_2geom(glyphs->g_transform) * gc->transform; glyphs->x = t[4]; glyphs->y = t[5]; t[4]=0; @@ -237,7 +237,7 @@ nr_arena_glyphs_clip(NRArenaItem *item, NRRectL */*area*/, NRPixBlock */*pb*/) } static NRArenaItem * -nr_arena_glyphs_pick(NRArenaItem *item, NR::Point p, gdouble /*delta*/, unsigned int /*sticky*/) +nr_arena_glyphs_pick(NRArenaItem *item, Geom::Point p, gdouble /*delta*/, unsigned int /*sticky*/) { NRArenaGlyphs *glyphs; @@ -246,8 +246,8 @@ nr_arena_glyphs_pick(NRArenaItem *item, NR::Point p, gdouble /*delta*/, unsigned if (!glyphs->font ) return NULL; if (!glyphs->style) return NULL; - double const x = p[NR::X]; - double const y = p[NR::Y]; + double const x = p[Geom::X]; + double const y = p[Geom::Y]; /* With text we take a simple approach: pick if the point is in a characher bbox */ if ((x >= item->bbox.x0) && (y >= item->bbox.y0) && (x <= item->bbox.x1) && (y <= item->bbox.y1)) return item; @@ -323,7 +323,7 @@ static void nr_arena_glyphs_group_finalize(NRObject *object); static guint nr_arena_glyphs_group_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset); static unsigned int nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); static unsigned int nr_arena_glyphs_group_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb); -static NRArenaItem *nr_arena_glyphs_group_pick(NRArenaItem *item, NR::Point p, gdouble delta, unsigned int sticky); +static NRArenaItem *nr_arena_glyphs_group_pick(NRArenaItem *item, Geom::Point p, gdouble delta, unsigned int sticky); static NRArenaGroupClass *group_parent_class; @@ -465,8 +465,8 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi Geom::PathVector const * pathv = g->font->PathVector(g->glyph); cairo_new_path(ct); - Geom::Matrix transform = g->g_transform * group->ctm; - feed_pathvector_to_cairo (ct, *pathv, transform, (pb->area).upgrade(), false, 0); + Geom::Matrix transform = to_2geom(g->g_transform) * group->ctm; + feed_pathvector_to_cairo (ct, *pathv, transform, to_2geom((pb->area).upgrade()), false, 0); cairo_fill(ct); pb->empty = FALSE; } @@ -582,7 +582,7 @@ nr_arena_glyphs_group_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb) } static NRArenaItem * -nr_arena_glyphs_group_pick(NRArenaItem *item, NR::Point p, gdouble delta, unsigned int sticky) +nr_arena_glyphs_group_pick(NRArenaItem *item, Geom::Point p, gdouble delta, unsigned int sticky) { NRArenaItem *picked = NULL; diff --git a/src/display/nr-arena-group.cpp b/src/display/nr-arena-group.cpp index 716a9f9fd..8b388aa40 100644 --- a/src/display/nr-arena-group.cpp +++ b/src/display/nr-arena-group.cpp @@ -24,6 +24,7 @@ #include "display/nr-filter-blend.h" #include "libnr/nr-matrix-fns.h" #include "libnr/nr-matrix-ops.h" +#include "helper/geom.h" static void nr_arena_group_class_init (NRArenaGroupClass *klass); static void nr_arena_group_init (NRArenaGroup *group); @@ -37,7 +38,7 @@ static void nr_arena_group_set_child_position (NRArenaItem *item, NRArenaItem *c static unsigned int nr_arena_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); static unsigned int nr_arena_group_render (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); static unsigned int nr_arena_group_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); -static NRArenaItem *nr_arena_group_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); +static NRArenaItem *nr_arena_group_pick (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky); static NRArenaItemClass *parent_class; @@ -87,7 +88,7 @@ nr_arena_group_init (NRArenaGroup *group) group->children = NULL; group->last = NULL; group->style = NULL; - group->child_transform.set_identity(); + group->child_transform.setIdentity(); } static NRArenaItem * @@ -250,7 +251,7 @@ nr_arena_group_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb) } static NRArenaItem * -nr_arena_group_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky) +nr_arena_group_pick (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky) { NRArenaGroup *group = NR_ARENA_GROUP (item); @@ -272,17 +273,17 @@ nr_arena_group_set_transparent (NRArenaGroup *group, unsigned int transparent) group->transparent = transparent; } -void nr_arena_group_set_child_transform(NRArenaGroup *group, NR::Matrix const &t) +void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Matrix const &t) { - NR::Matrix nt(t); + Geom::Matrix nt(t); nr_arena_group_set_child_transform(group, &nt); } -void nr_arena_group_set_child_transform(NRArenaGroup *group, NR::Matrix const *t) +void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Matrix const *t) { - if (!t) t = &NR_MATRIX_IDENTITY; + if (!t) t = &GEOM_MATRIX_IDENTITY; - if (!NR::matrix_equalp(*t, group->child_transform, NR_EPSILON)) { + if (!Geom::matrix_equalp(*t, group->child_transform, NR_EPSILON)) { nr_arena_item_request_render (NR_ARENA_ITEM (group)); group->child_transform = *t; nr_arena_item_request_update (NR_ARENA_ITEM (group), NR_ARENA_ITEM_STATE_ALL, TRUE); diff --git a/src/display/nr-arena-group.h b/src/display/nr-arena-group.h index ff3ec02dd..ae1763e99 100644 --- a/src/display/nr-arena-group.h +++ b/src/display/nr-arena-group.h @@ -26,7 +26,7 @@ struct NRArenaGroup : public NRArenaItem{ unsigned int transparent : 1; NRArenaItem *children; NRArenaItem *last; - NR::Matrix child_transform; + Geom::Matrix child_transform; SPStyle *style; static NRArenaGroup *create(NRArena *arena) { @@ -42,8 +42,8 @@ struct NRArenaGroupClass { void nr_arena_group_set_transparent(NRArenaGroup *group, unsigned int transparent); -void nr_arena_group_set_child_transform(NRArenaGroup *group, NR::Matrix const &t); -void nr_arena_group_set_child_transform(NRArenaGroup *group, NR::Matrix const *t); +void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Matrix const &t); +void nr_arena_group_set_child_transform(NRArenaGroup *group, Geom::Matrix const *t); void nr_arena_group_set_style(NRArenaGroup *group, SPStyle *style); #endif diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp index 480322873..c8a988483 100644 --- a/src/display/nr-arena-image.cpp +++ b/src/display/nr-arena-image.cpp @@ -13,6 +13,7 @@ */ #include <libnr/nr-compose-transform.h> +#include <2geom/transforms.h> #include <libnr/nr-blit.h> #include "../prefs-utils.h" #include "nr-arena-image.h" @@ -40,7 +41,7 @@ static void nr_arena_image_finalize (NRObject *object); static unsigned int nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); static unsigned int nr_arena_image_render (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); -static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); +static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky); static NRArenaItemClass *parent_class; @@ -88,7 +89,7 @@ nr_arena_image_init (NRArenaImage *image) image->width = 256.0; image->height = 256.0; - image->grid2px.set_identity(); + image->grid2px.setIdentity(); image->style = 0; } @@ -106,7 +107,7 @@ nr_arena_image_finalize (NRObject *object) static unsigned int nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned int /*state*/, unsigned int /*reset*/ ) { - NR::Matrix grid2px; + Geom::Matrix grid2px; NRArenaImage *image = NR_ARENA_IMAGE (item); @@ -115,7 +116,7 @@ nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned /* Copy affine */ grid2px = gc->transform.inverse(); - double hscale, vscale; // todo: replace with NR::scale + double hscale, vscale; // todo: replace with Geom::Scale if (image->px) { hscale = image->pxw / image->width; vscale = image->pxh / image->height; @@ -143,12 +144,12 @@ nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned bbox.x1 = image->x + image->width; bbox.y1 = image->y + image->height; - image->c00 = (NR::Point(bbox.x0, bbox.y0) * gc->transform); - image->c01 = (NR::Point(bbox.x0, bbox.y1) * gc->transform); - image->c10 = (NR::Point(bbox.x1, bbox.y0) * gc->transform); - image->c11 = (NR::Point(bbox.x1, bbox.y1) * gc->transform); + image->c00 = (Geom::Point(bbox.x0, bbox.y0) * gc->transform); + image->c01 = (Geom::Point(bbox.x0, bbox.y1) * gc->transform); + image->c10 = (Geom::Point(bbox.x1, bbox.y0) * gc->transform); + image->c11 = (Geom::Point(bbox.x1, bbox.y1) * gc->transform); - nr_rect_d_matrix_transform (&bbox, &bbox, &gc->transform); + nr_rect_d_matrix_transform (&bbox, &bbox, from_2geom(gc->transform)); item->bbox.x0 = (int) floor (bbox.x0); item->bbox.y0 = (int) floor (bbox.y0); @@ -179,7 +180,7 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB NRArenaImage *image = NR_ARENA_IMAGE (item); - NR::Matrix d2s; + Geom::Matrix d2s; d2s[0] = b2i[0]; d2s[1] = b2i[1]; @@ -235,23 +236,23 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB cairo_set_line_width(ct, 0.5); cairo_new_path(ct); - NR::Point shift(pb->area.x0, pb->area.y0); - NR::Point c00 = image->c00 - shift; - NR::Point c01 = image->c01 - shift; - NR::Point c11 = image->c11 - shift; - NR::Point c10 = image->c10 - shift; + Geom::Point shift(pb->area.x0, pb->area.y0); + Geom::Point c00 = image->c00 - shift; + Geom::Point c01 = image->c01 - shift; + Geom::Point c11 = image->c11 - shift; + Geom::Point c10 = image->c10 - shift; - cairo_move_to (ct, c00[NR::X], c00[NR::Y]); + cairo_move_to (ct, c00[Geom::X], c00[Geom::Y]); // the box - cairo_line_to (ct, c10[NR::X], c10[NR::Y]); - cairo_line_to (ct, c11[NR::X], c11[NR::Y]); - cairo_line_to (ct, c01[NR::X], c01[NR::Y]); - cairo_line_to (ct, c00[NR::X], c00[NR::Y]); + cairo_line_to (ct, c10[Geom::X], c10[Geom::Y]); + cairo_line_to (ct, c11[Geom::X], c11[Geom::Y]); + cairo_line_to (ct, c01[Geom::X], c01[Geom::Y]); + cairo_line_to (ct, c00[Geom::X], c00[Geom::Y]); // the diagonals - cairo_line_to (ct, c11[NR::X], c11[NR::Y]); - cairo_move_to (ct, c10[NR::X], c10[NR::Y]); - cairo_line_to (ct, c01[NR::X], c01[NR::Y]); + cairo_line_to (ct, c11[Geom::X], c11[Geom::Y]); + cairo_move_to (ct, c10[Geom::X], c10[Geom::Y]); + cairo_line_to (ct, c01[Geom::X], c01[Geom::Y]); cairo_stroke(ct); @@ -263,14 +264,14 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB /** Calculates the closest distance from p to the segment a1-a2*/ double -distance_to_segment (NR::Point p, NR::Point a1, NR::Point a2) +distance_to_segment (Geom::Point p, Geom::Point a1, Geom::Point a2) { // calculate sides of the triangle and their squares - double d1 = NR::L2(p - a1); + double d1 = Geom::L2(p - a1); double d1_2 = d1 * d1; - double d2 = NR::L2(p - a2); + double d2 = Geom::L2(p - a2); double d2_2 = d2 * d2; - double a = NR::L2(a1 - a2); + double a = Geom::L2(a1 - a2); double a_2 = a * a; // if one of the angles at the base is > 90, return the corresponding side @@ -283,7 +284,7 @@ distance_to_segment (NR::Point p, NR::Point a1, NR::Point a2) } static NRArenaItem * -nr_arena_image_pick( NRArenaItem *item, NR::Point p, double delta, unsigned int /*sticky*/ ) +nr_arena_image_pick( NRArenaItem *item, Geom::Point p, double delta, unsigned int /*sticky*/ ) { NRArenaImage *image = NR_ARENA_IMAGE (item); @@ -311,9 +312,9 @@ nr_arena_image_pick( NRArenaItem *item, NR::Point p, double delta, unsigned int int const width = image->pxw; int const height = image->pxh; int const rowstride = image->pxrs; - NR::Point tp = p * image->grid2px; - int const ix = (int)(tp[NR::X]); - int const iy = (int)(tp[NR::Y]); + Geom::Point tp = p * image->grid2px; + int const ix = (int)(tp[Geom::X]); + int const iy = (int)(tp[Geom::Y]); if ((ix < 0) || (iy < 0) || (ix >= width) || (iy >= height)) return NULL; diff --git a/src/display/nr-arena-image.h b/src/display/nr-arena-image.h index 2d7328263..d4653a692 100644 --- a/src/display/nr-arena-image.h +++ b/src/display/nr-arena-image.h @@ -32,10 +32,10 @@ struct NRArenaImage : public NRArenaItem { double x, y; double width, height; - NR::Point c00, c01, c11, c10; // all 4 corners of the image, for outline mode rect + Geom::Point c00, c01, c11, c10; // all 4 corners of the image, for outline mode rect /* From GRID to PIXELS */ - NR::Matrix grid2px; + Geom::Matrix grid2px; SPStyle *style; diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index a236b866b..b9a0cc371 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -25,6 +25,7 @@ #include "nr-arena.h" #include "nr-arena-item.h" #include "gc-core.h" +#include "helper/geom.h" #include "nr-filter.h" #include "libnr/nr-rect.h" @@ -619,7 +620,7 @@ nr_arena_item_invoke_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb) } NRArenaItem * -nr_arena_item_invoke_pick (NRArenaItem *item, NR::Point p, double delta, +nr_arena_item_invoke_pick (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky) { nr_return_val_if_fail (item != NULL, NULL); @@ -633,9 +634,9 @@ nr_arena_item_invoke_pick (NRArenaItem *item, NR::Point p, double delta, if (!sticky && !(item->visible && item->sensitive)) return NULL; - // TODO: rewrite using NR::Rect - const double x = p[NR::X]; - const double y = p[NR::Y]; + // TODO: rewrite using Geom::Rect + const double x = p[Geom::X]; + const double y = p[Geom::Y]; if (((x + delta) >= item->bbox.x0) && ((x - delta) < item->bbox.x1) && @@ -711,14 +712,14 @@ nr_arena_item_append_child (NRArenaItem *parent, NRArenaItem *child) } void -nr_arena_item_set_transform (NRArenaItem *item, NR::Matrix const &transform) +nr_arena_item_set_transform (NRArenaItem *item, Geom::Matrix const &transform) { - NR::Matrix const t (transform); + Geom::Matrix const t (transform); nr_arena_item_set_transform (item, &t); } void -nr_arena_item_set_transform (NRArenaItem *item, NR::Matrix const *transform) +nr_arena_item_set_transform (NRArenaItem *item, Geom::Matrix const *transform) { nr_return_if_fail (item != NULL); nr_return_if_fail (NR_IS_ARENA_ITEM (item)); @@ -726,17 +727,17 @@ nr_arena_item_set_transform (NRArenaItem *item, NR::Matrix const *transform) if (!transform && !item->transform) return; - const NR::Matrix *md = (item->transform) ? item->transform : &NR_MATRIX_IDENTITY; - const NR::Matrix *ms = (transform) ? transform : &NR_MATRIX_IDENTITY; + const Geom::Matrix *md = (item->transform) ? item->transform : &GEOM_MATRIX_IDENTITY; + const Geom::Matrix *ms = (transform) ? transform : &GEOM_MATRIX_IDENTITY; - if (!NR::matrix_equalp(*md, *ms, NR_EPSILON)) { + if (!Geom::matrix_equalp(*md, *ms, NR_EPSILON)) { nr_arena_item_request_render (item); - if (!transform || transform->test_identity()) { + if (!transform || transform->isIdentity()) { /* Set to identity affine */ item->transform = NULL; } else { if (!item->transform) - item->transform = new (GC::ATOMIC) NR::Matrix (); + item->transform = new (GC::ATOMIC) Geom::Matrix (); *item->transform = *transform; } nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, TRUE); @@ -836,12 +837,12 @@ nr_arena_item_set_order (NRArenaItem *item, int order) } void -nr_arena_item_set_item_bbox (NRArenaItem *item, boost::optional<NR::Rect> &bbox) +nr_arena_item_set_item_bbox (NRArenaItem *item, boost::optional<Geom::Rect> &bbox) { nr_return_if_fail(item != NULL); nr_return_if_fail(NR_IS_ARENA_ITEM(item)); - item->item_bbox = bbox; + if(bbox) item->item_bbox = *bbox; } /** Returns a background image for use with filter effects. */ diff --git a/src/display/nr-arena-item.h b/src/display/nr-arena-item.h index b95fc5e72..9db8d7a40 100644 --- a/src/display/nr-arena-item.h +++ b/src/display/nr-arena-item.h @@ -60,11 +60,12 @@ #include "nr-arena-forward.h" #include "display/nr-filter.h" #include <cairo.h> +#include <libnr/nr-convert2geom.h> struct NRGC { NRGC(NRGC const *p) : parent(p) {} NRGC const *parent; - NR::Matrix transform; + Geom::Matrix transform; }; struct NRArenaItem : public NRObject { @@ -91,9 +92,9 @@ struct NRArenaItem : public NRObject { NRRectL bbox; /* BBox in item coordinates - this should be a bounding box as * specified in SVG standard. Required by filters. */ - boost::optional<NR::Rect> item_bbox; + boost::optional<Geom::Rect> item_bbox; /* Our affine */ - NR::Matrix *transform; + Geom::Matrix *transform; /* Clip item */ NRArenaItem *clip; /* Mask item */ @@ -107,7 +108,7 @@ struct NRArenaItem : public NRObject { void *data; /* Current Transformation Matrix */ - NR::Matrix ctm; + Geom::Matrix ctm; /* These hold background buffer state for filter rendering */ NRPixBlock *background_pb; @@ -128,7 +129,7 @@ struct NRArenaItemClass : public NRObjectClass { unsigned int (* update) (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); unsigned int (* render) (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); unsigned int (* clip) (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); - NRArenaItem * (* pick) (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); + NRArenaItem * (* pick) (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky); }; #define NR_ARENA_ITEM_ARENA(ai) (((NRArenaItem *) (ai))->arena) @@ -158,7 +159,7 @@ unsigned int nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC unsigned int nr_arena_item_invoke_render(cairo_t *ct, NRArenaItem *item, NRRectL const *area, NRPixBlock *pb, unsigned int flags); unsigned int nr_arena_item_invoke_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); -NRArenaItem *nr_arena_item_invoke_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); +NRArenaItem *nr_arena_item_invoke_pick (NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky); void nr_arena_item_request_update (NRArenaItem *item, unsigned int reset, unsigned int propagate); void nr_arena_item_request_render (NRArenaItem *item); @@ -169,15 +170,15 @@ NRArenaItem *nr_arena_item_unparent (NRArenaItem *item); void nr_arena_item_append_child (NRArenaItem *parent, NRArenaItem *child); -void nr_arena_item_set_transform(NRArenaItem *item, NR::Matrix const &transform); -void nr_arena_item_set_transform(NRArenaItem *item, NR::Matrix const *transform); +void nr_arena_item_set_transform(NRArenaItem *item, Geom::Matrix const &transform); +void nr_arena_item_set_transform(NRArenaItem *item, Geom::Matrix const *transform); void nr_arena_item_set_opacity (NRArenaItem *item, double opacity); void nr_arena_item_set_sensitive (NRArenaItem *item, unsigned int sensitive); void nr_arena_item_set_visible (NRArenaItem *item, unsigned int visible); void nr_arena_item_set_clip (NRArenaItem *item, NRArenaItem *clip); void nr_arena_item_set_mask (NRArenaItem *item, NRArenaItem *mask); void nr_arena_item_set_order (NRArenaItem *item, int order); -void nr_arena_item_set_item_bbox (NRArenaItem *item, boost::optional<NR::Rect> &bbox); +void nr_arena_item_set_item_bbox (NRArenaItem *item, boost::optional<Geom::Rect> &bbox); NRPixBlock *nr_arena_item_get_background (NRArenaItem const *item, int depth = 0); diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 751801c7e..6a252e5f5 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -58,7 +58,7 @@ static void nr_arena_shape_set_child_position(NRArenaItem *item, NRArenaItem *ch static guint nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset); static unsigned int nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); static guint nr_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb); -static NRArenaItem *nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); +static NRArenaItem *nr_arena_shape_pick(NRArenaItem *item, Geom::Point p, double delta, unsigned int sticky); static NRArenaItemClass *shape_parent_class; @@ -113,7 +113,7 @@ nr_arena_shape_init(NRArenaShape *shape) shape->paintbox.x0 = shape->paintbox.y0 = 0.0F; shape->paintbox.x1 = shape->paintbox.y1 = 256.0F; - shape->ctm.set_identity(); + shape->ctm.setIdentity(); shape->fill_painter = NULL; shape->stroke_painter = NULL; shape->cached_fill = NULL; @@ -127,8 +127,8 @@ nr_arena_shape_init(NRArenaShape *shape) shape->approx_bbox.x0 = shape->approx_bbox.y0 = 0; shape->approx_bbox.x1 = shape->approx_bbox.y1 = 0; - shape->cached_fctm.set_identity(); - shape->cached_sctm.set_identity(); + shape->cached_fctm.setIdentity(); + shape->cached_sctm.setIdentity(); shape->markers = NULL; @@ -282,7 +282,7 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g if (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE || outline) { float width, scale; - scale = NR::expansion(gc->transform); + scale = gc->transform.descrim(); width = MAX(0.125, shape->_stroke.width * scale); if ( fabs(shape->_stroke.width * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord boundingbox.expandBy(width); @@ -303,7 +303,7 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g if ( area && nr_rect_l_test_intersect_ptr(area, &shape->approx_bbox) ) shape->delayed_shp=false; /* Release state data */ - if (TRUE || !NR::transform_equalp(gc->transform, shape->ctm, NR_EPSILON)) { + if (TRUE || !Geom::transform_equalp(gc->transform, shape->ctm, NR_EPSILON)) { /* Concept test */ if (shape->fill_shp) { delete shape->fill_shp; @@ -393,8 +393,8 @@ nr_arena_shape_update(NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, g return NR_ARENA_ITEM_STATE_ALL; } -int matrix_is_isometry(NR::Matrix p) { - NR::Matrix tp; +int matrix_is_isometry(Geom::Matrix p) { + Geom::Matrix tp; // transposition tp[0]=p[0]; tp[1]=p[2]; @@ -402,9 +402,9 @@ int matrix_is_isometry(NR::Matrix p) { tp[3]=p[3]; for (int i = 4; i < 6; i++) // shut valgrind up :) tp[i] = p[i] = 0; - NR::Matrix isom = tp*p; // A^T * A = adjunct? + Geom::Matrix isom = tp*p; // A^T * A = adjunct? // Is the adjunct nearly an identity function? - if (isom.is_translation(0.01)) { + if (isom.isTranslation(0.01)) { // the transformation is an isometry -> no need to recompute // the uncrossed polygon if ( p.det() < 0 ) @@ -446,7 +446,7 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool fo // ((shape->curve->get_length() > 2) || (SP_CURVE_BPATH(shape->curve)[1].code == NR_CURVETO)) ) { // <-- this used to be the old code, i think it has to determine that the path has a sort of 'internal region' where fill would occur has_inner_area(shape->curve->get_pathvector()) ) { if (TRUE || !shape->fill_shp) { - NR::Matrix cached_to_new = NR::identity(); + Geom::Matrix cached_to_new = Geom::identity(); int isometry = 0; if ( shape->cached_fill ) { if (shape->cached_fctm == gc->transform) { @@ -508,7 +508,7 @@ nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool fo shape->fill_shp->Reset(shape->cached_fill->numberOfPoints(), shape->cached_fill->numberOfEdges()); for (int i = 0; i < shape->cached_fill->numberOfPoints(); i++) - shape->fill_shp->AddPoint(shape->cached_fill->getPoint(i).x * cached_to_new); + shape->fill_shp->AddPoint(to_2geom(shape->cached_fill->getPoint(i).x) * cached_to_new); if ( isometry == 1 ) { for (int i = 0; i < shape->cached_fill->numberOfEdges(); i++) shape->fill_shp->AddEdge(shape->cached_fill->getEdge(i).st, @@ -532,7 +532,7 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc, NRRectL *area) { SPStyle* style = shape->style; - float const scale = NR::expansion(gc->transform); + float const scale = gc->transform.descrim(); bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); @@ -556,7 +556,7 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc, NRRectL *area) width = style_width; } - NR::Matrix cached_to_new = NR::identity(); + Geom::Matrix cached_to_new = Geom::identity(); int isometry = 0; if ( shape->cached_stroke ) { @@ -664,7 +664,7 @@ nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc, NRRectL *area) shape->stroke_shp=new Shape; shape->stroke_shp->Reset(shape->cached_stroke->numberOfPoints(), shape->cached_stroke->numberOfEdges()); for (int i = 0; i < shape->cached_stroke->numberOfPoints(); i++) - shape->stroke_shp->AddPoint(shape->cached_stroke->getPoint(i).x * cached_to_new); + shape->stroke_shp->AddPoint(to_2geom(shape->cached_stroke->getPoint(i).x) * cached_to_new); if ( isometry == 1 ) { for (int i = 0; i < shape->cached_stroke->numberOfEdges(); i++) shape->stroke_shp->AddEdge(shape->cached_stroke->getEdge(i).st, @@ -716,7 +716,7 @@ nr_arena_shape_add_bboxes(NRArenaShape* shape, Geom::Rect &bbox) // cairo outline rendering: static unsigned int -cairo_arena_shape_render_outline(cairo_t *ct, NRArenaItem *item, boost::optional<NR::Rect> area) +cairo_arena_shape_render_outline(cairo_t *ct, NRArenaItem *item, boost::optional<Geom::Rect> area) { NRArenaShape *shape = NR_ARENA_SHAPE(item); @@ -748,7 +748,7 @@ cairo_arena_shape_render_stroke(NRArenaItem *item, NRRectL *area, NRPixBlock *pb NRArenaShape *shape = NR_ARENA_SHAPE(item); SPStyle const *style = shape->style; - float const scale = NR::expansion(shape->ctm); + float const scale = shape->ctm.descrim(); if (fabs(shape->_stroke.width * scale) < 0.01) return; @@ -813,7 +813,7 @@ cairo_arena_shape_render_stroke(NRArenaItem *item, NRRectL *area, NRPixBlock *pb cairo_set_tolerance(ct, 0.1); cairo_new_path(ct); - feed_pathvector_to_cairo (ct, shape->curve->get_pathvector(), shape->ctm, area->upgrade(), true, style_width); + feed_pathvector_to_cairo (ct, shape->curve->get_pathvector(), shape->ctm, to_2geom(area->upgrade()), true, style_width); cairo_stroke(ct); @@ -842,7 +842,7 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock if (outline) { // cairo outline rendering pb->empty = FALSE; - unsigned int ret = cairo_arena_shape_render_outline (ct, item, (&pb->area)->upgrade()); + unsigned int ret = cairo_arena_shape_render_outline (ct, item, to_2geom((&pb->area)->upgrade())); if (ret & NR_ARENA_ITEM_STATE_INVALID) return ret; } else { @@ -1056,7 +1056,7 @@ nr_arena_shape_clip(NRArenaItem *item, NRRectL *area, NRPixBlock *pb) } static NRArenaItem * -nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int /*sticky*/) +nr_arena_shape_pick(NRArenaItem *item, Geom::Point p, double delta, unsigned int /*sticky*/) { NRArenaShape *shape = NR_ARENA_SHAPE(item); @@ -1082,7 +1082,7 @@ nr_arena_shape_pick(NRArenaItem *item, NR::Point p, double delta, unsigned int / if (outline) { width = 0.5; } else if (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE && shape->_stroke.opacity > 1e-3) { - float const scale = NR::expansion(shape->ctm); + float const scale = shape->ctm.descrim(); width = MAX(0.125, shape->_stroke.width * scale) / 2; } else { width = 0; @@ -1359,12 +1359,12 @@ nr_arena_shape_set_paintbox(NRArenaShape *shape, NRRect const *pbox) nr_arena_item_request_update(shape, NR_ARENA_ITEM_STATE_ALL, FALSE); } -void NRArenaShape::setPaintBox(NR::Rect const &pbox) +void NRArenaShape::setPaintBox(Geom::Rect const &pbox) { - paintbox.x0 = pbox.min()[NR::X]; - paintbox.y0 = pbox.min()[NR::Y]; - paintbox.x1 = pbox.max()[NR::X]; - paintbox.y1 = pbox.max()[NR::Y]; + paintbox.x0 = pbox.min()[Geom::X]; + paintbox.y0 = pbox.min()[Geom::Y]; + paintbox.x1 = pbox.max()[Geom::X]; + paintbox.y1 = pbox.max()[Geom::Y]; nr_arena_item_request_update(this, NR_ARENA_ITEM_STATE_ALL, FALSE); } diff --git a/src/display/nr-arena-shape.h b/src/display/nr-arena-shape.h index 2b56fbf75..8ff8c476a 100644 --- a/src/display/nr-arena-shape.h +++ b/src/display/nr-arena-shape.h @@ -113,7 +113,7 @@ struct NRArenaShape : public NRArenaItem { SPStyle *style; NRRect paintbox; /* State data */ - NR::Matrix ctm; + Geom::Matrix ctm; SPPainter *fill_painter; SPPainter *stroke_painter; @@ -136,8 +136,8 @@ struct NRArenaShape : public NRArenaItem { // polygon to get the *_shp polygon. Otherwise, recompute so this // works fine for translation and rotation, but not scaling and // skewing - NR::Matrix cached_fctm; - NR::Matrix cached_sctm; + Geom::Matrix cached_fctm; + Geom::Matrix cached_sctm; NRRectL cached_farea; NRRectL cached_sarea; bool cached_fpartialy; @@ -170,7 +170,7 @@ struct NRArenaShape : public NRArenaItem { void setLineJoin(JoinType join); void setMitreLimit(double limit); - void setPaintBox(NR::Rect const &pbox); + void setPaintBox(Geom::Rect const &pbox); void _invalidateCachedFill() { if (cached_fill) { diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 65958f0d2..7837770ed 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -62,7 +62,7 @@ int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { Matrix identity(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); - boost::optional<NR::Rect> area = SVGElem->getBounds(identity); + boost::optional<Geom::Rect> area = SVGElem->getBounds(identity); NRRectL rect; rect.x0=area->min()[NR::X]; @@ -80,9 +80,9 @@ int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { NRGC gc(NULL); /* Update to renderable state */ double sf = 1.0; - NR::Matrix t(NR::scale(sf, sf)); + Geom::Matrix t(Geom::Scale(sf, sf)); nr_arena_item_set_transform(ai, &t); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update( ai, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE ); diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index 3fd577309..1a3a8d1f1 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -14,7 +14,7 @@ * http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 * * Copyright (C) 2007 authors - * Released under GNU GPL, read the file 'COPYING' for more information + * Released under GNU GPL version 2 (or later), read the file 'COPYING' for more information */ #include "display/nr-arena-item.h" diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 0e608e901..8930a74df 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -114,13 +114,13 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) Matrix trans = item->ctm; FilterSlot slot(_slot_count, item); - Rect item_bbox; + Geom::Rect item_bbox; if (item->item_bbox) { item_bbox = *(item->item_bbox); } else { // Bounding box might not exist, so create a dummy one. - Point zero(0, 0); - item_bbox = Rect(zero, zero); + Geom::Point zero(0, 0); + item_bbox = Geom::Rect(zero, zero); } if (item_bbox.min()[X] > item_bbox.max()[X] || item_bbox.min()[Y] > item_bbox.max()[Y]) @@ -129,7 +129,7 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) return 1; } - Rect filter_area = filter_effect_area(item_bbox); + Geom::Rect filter_area = filter_effect_area(item_bbox); if (item_bbox.isEmpty()) { // It's no use to try and filter an empty object. return 1; @@ -137,8 +137,8 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) FilterUnits units(_filter_units, _primitive_units); units.set_ctm(trans); - units.set_item_bbox(item_bbox); - units.set_filter_area(filter_area); + units.set_item_bbox(from_2geom(item_bbox)); + units.set_filter_area(from_2geom(filter_area)); // TODO: with filterRes of 0x0 should return an empty image if (_x_pixels > 0) { @@ -224,11 +224,11 @@ void Filter::bbox_enlarge(NRRectL &bbox) { /* TODO: this is wrong. Should use bounding box in user coordinates * and find its extents in display coordinates. */ - Point min(bbox.x0, bbox.y0); - Point max(bbox.x1, bbox.y1); - Rect tmp_bbox(min, max); + Geom::Point min(bbox.x0, bbox.y0); + Geom::Point max(bbox.x1, bbox.y1); + Geom::Rect tmp_bbox(min, max); - Rect enlarged = filter_effect_area(tmp_bbox); + Geom::Rect enlarged = filter_effect_area(tmp_bbox); bbox.x0 = (ICoord)enlarged.min()[X]; bbox.y0 = (ICoord)enlarged.min()[Y]; @@ -236,7 +236,7 @@ void Filter::bbox_enlarge(NRRectL &bbox) { bbox.y1 = (ICoord)enlarged.max()[Y]; } -Rect Filter::filter_effect_area(Rect const &bbox) +Geom::Rect Filter::filter_effect_area(Geom::Rect const &bbox) { Point minp, maxp; double len_x = bbox.max()[X] - bbox.min()[X]; @@ -277,7 +277,7 @@ Rect Filter::filter_effect_area(Rect const &bbox) } else { g_warning("Error in NR::Filter::bbox_enlarge: unrecognized value of _filter_units"); } - Rect area(minp, maxp); + Geom::Rect area(minp, maxp); return area; } diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index 267f242d1..1dbdfd1ef 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -155,7 +155,7 @@ public: * The given bounding box should be a bounding box as specified in * SVG standard and in user coordinate system. */ - Rect filter_effect_area(Rect const &bbox); + Geom::Rect filter_effect_area(Geom::Rect const &bbox); /** Creates a new filter with space for one filter element */ Filter(); diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 0dd5d996a..28d29b59c 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -30,17 +30,6 @@ static cairo_user_data_key_t key; - -/** - * Felipe, - * Cairo is changing its userfont api a little bit for 1.7+, 1.8, - * etc. This switch makes your code compile both on 1.6 and 1.7. Is - * this ok? - * - * Bob - */ -#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 7, 0)) - static cairo_status_t font_init_cb (cairo_scaled_font_t *scaled_font, cairo_t */*cairo*/, cairo_font_extents_t *metrics){ cairo_font_face_t* face; @@ -52,42 +41,18 @@ static cairo_status_t font_init_cb (cairo_scaled_font_t *scaled_font, static cairo_status_t font_text_to_glyphs_cb ( cairo_scaled_font_t *scaled_font, const char *utf8, - int /*utf8_len*/, + int utf8_len, cairo_glyph_t **glyphs, int *num_glyphs, - cairo_text_cluster_t **/*clusters*/, - int */*num_clusters*/, - cairo_bool_t */*backward*/){ - cairo_font_face_t* face; - face = cairo_scaled_font_get_font_face(scaled_font); - SvgFont* instance = (SvgFont*) cairo_font_face_get_user_data(face, &key); - return instance->scaled_font_text_to_glyphs(scaled_font, utf8, glyphs, num_glyphs); -} - - -#else - -static cairo_status_t font_init_cb (cairo_scaled_font_t *scaled_font, - cairo_font_extents_t *metrics){ + cairo_text_cluster_t **clusters, + int *num_clusters, + cairo_text_cluster_flags_t *flags){ cairo_font_face_t* face; face = cairo_scaled_font_get_font_face(scaled_font); SvgFont* instance = (SvgFont*) cairo_font_face_get_user_data(face, &key); - return instance->scaled_font_init(scaled_font, metrics); -} - -static cairo_status_t font_text_to_glyphs_cb (cairo_scaled_font_t *scaled_font, - const char *utf8, - cairo_glyph_t **glyphs, - int *num_glyphs){ - cairo_font_face_t* face; - face = cairo_scaled_font_get_font_face(scaled_font); - SvgFont* instance = (SvgFont*) cairo_font_face_get_user_data(face, &key); - return instance->scaled_font_text_to_glyphs(scaled_font, utf8, glyphs, num_glyphs); + return instance->scaled_font_text_to_glyphs(scaled_font, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, flags); } -#endif - - static cairo_status_t font_render_glyph_cb (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, @@ -136,12 +101,16 @@ unsigned int compare_them(char* s1, char* s2){ cairo_status_t SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, const char *utf8, + int utf8_len, cairo_glyph_t **glyphs, - int *num_glyphs) + int *num_glyphs, + cairo_text_cluster_t **clusters, + int *num_clusters, + cairo_text_cluster_flags_t *flags) { //This function receives a text string to be rendered. It then defines what is the sequence of glyphs that - // is used to properly render this string. It alse defines the respective coordinates of each glyph. Thus, it - // has to read the attributes od the SVGFont hkern and vkern nodes in order to adjust the glyph kerning. + // is used to properly render this string. It also defines the respective coordinates of each glyph. Thus, it + // has to read the attributes of the SVGFont hkern and vkern nodes in order to adjust the glyph kerning. //It also determines the usage of the missing-glyph in portions of the string that does not match any of the declared glyphs. unsigned long i; @@ -258,8 +227,8 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, //This glyph has a path description on its d attribute, so we render it: cairo_new_path(cr); Geom::Scale s(1.0/((SPFont*) node->parent)->horiz_adv_x); - NRRect area(0,0,1,1); //I need help here! - feed_pathvector_to_cairo (cr, pathv, s, area.upgrade(), false, 0); + Geom::Rect area( Geom::Point(0,0), Geom::Point(1,1) ); //I need help here! (reaction: note that the 'area' parameter is an *optional* rect, so you can pass an empty boost::optional<Geom::Rect>() ) + feed_pathvector_to_cairo (cr, pathv, s, area, false, 0); cairo_fill(cr); } diff --git a/src/display/nr-svgfonts.h b/src/display/nr-svgfonts.h index e3bac7d7a..a41627f86 100644 --- a/src/display/nr-svgfonts.h +++ b/src/display/nr-svgfonts.h @@ -34,7 +34,7 @@ public: SvgFont(SPFont* spfont); cairo_font_face_t* get_font_face(); cairo_status_t scaled_font_init (cairo_scaled_font_t *scaled_font, cairo_font_extents_t *metrics); -cairo_status_t scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, const char *utf8, cairo_glyph_t **glyphs, int *num_glyphs); +cairo_status_t scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, const char *utf8, int utf8_len, cairo_glyph_t **glyphs, int *num_glyphs, cairo_text_cluster_t **clusters, int *num_clusters, cairo_text_cluster_flags_t *flags); cairo_status_t scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *metrics); private: diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index fd124aa1e..d82e39238 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -29,6 +29,7 @@ #include <gtkmm.h> #include <helper/sp-marshal.h> +#include <helper/recthull.h> #include <display/sp-canvas.h> #include "display-forward.h" #include <libnr/nr-matrix-fns.h> @@ -773,7 +774,7 @@ static void sp_canvas_group_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned int flags) { SPCanvasGroup const *group = SP_CANVAS_GROUP (item); - NR::ConvexHull corners(Geom::Point(0, 0)); + Geom::RectHull corners(Geom::Point(0, 0)); bool empty=true; for (GList *list = group->items; list; list = list->next) { @@ -783,7 +784,7 @@ sp_canvas_group_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned if ( i->x2 > i->x1 && i->y2 > i->y1 ) { if (empty) { - corners = NR::ConvexHull(Geom::Point(i->x1, i->y1)); + corners = Geom::RectHull(Geom::Point(i->x1, i->y1)); empty = false; } else { corners.add(Geom::Point(i->x1, i->y1)); @@ -792,12 +793,12 @@ sp_canvas_group_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned } } - boost::optional<NR::Rect> const bounds = corners.bounds(); + boost::optional<Geom::Rect> const bounds = corners.bounds(); if (bounds) { - item->x1 = bounds->min()[NR::X]; - item->y1 = bounds->min()[NR::Y]; - item->x2 = bounds->max()[NR::X]; - item->y2 = bounds->max()[NR::Y]; + item->x1 = bounds->min()[Geom::X]; + item->y1 = bounds->min()[Geom::Y]; + item->x2 = bounds->max()[Geom::X]; + item->y2 = bounds->max()[Geom::Y]; } else { // FIXME ? item->x1 = item->x2 = item->y1 = item->y2 = 0; diff --git a/src/document.cpp b/src/document.cpp index c3ebdcdb2..b27d8d1cb 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -897,7 +897,7 @@ static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, s = find_items_in_area(s, SP_GROUP(o), dkey, area, test); } else { SPItem *child = SP_ITEM(o); - boost::optional<Geom::Rect> box = to_2geom(sp_item_bbox_desktop(child)); + boost::optional<Geom::Rect> box = sp_item_bbox_desktop(child); if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { s = g_slist_append(s, child); } diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp index b8f069073..2d4782f9b 100644 --- a/src/dyna-draw-context.cpp +++ b/src/dyna-draw-context.cpp @@ -747,21 +747,21 @@ sp_dyna_draw_context_root_handler(SPEventContext *event_context, if (dc->hatch_spacing == 0 && hatch_dist != 0) { // Haven't set spacing yet: gray, center free, update radius live Geom::Point c = desktop->w2d(motion_w); - NR::Matrix const sm (NR::scale(hatch_dist, hatch_dist) * NR::translate(c)); + NR::Matrix const sm (Geom::Scale(hatch_dist, hatch_dist) * Geom::Translate(c)); sp_canvas_item_affine_absolute(dc->hatch_area, sm); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0x7f7f7fff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_item_show(dc->hatch_area); } else if (dc->dragging && !dc->hatch_escaped) { // Tracking: green, center snapped, fixed radius Geom::Point c = motion_dt; - NR::Matrix const sm (NR::scale(dc->hatch_spacing, dc->hatch_spacing) * NR::translate(c)); + NR::Matrix const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c)); sp_canvas_item_affine_absolute(dc->hatch_area, sm); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0x00FF00ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_item_show(dc->hatch_area); } else if (dc->dragging && dc->hatch_escaped) { // Tracking escaped: red, center free, fixed radius Geom::Point c = desktop->w2d(motion_w); - NR::Matrix const sm (NR::scale(dc->hatch_spacing, dc->hatch_spacing) * NR::translate(c)); + NR::Matrix const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c)); sp_canvas_item_affine_absolute(dc->hatch_area, sm); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0xFF0000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); @@ -770,7 +770,7 @@ sp_dyna_draw_context_root_handler(SPEventContext *event_context, // Not drawing but spacing set: gray, center snapped, fixed radius Geom::Point c = (nearest + dc->hatch_spacing * hatch_unit_vector) * motion_to_curve.inverse(); if (!IS_NAN(c[NR::X]) && !IS_NAN(c[NR::Y])) { - NR::Matrix const sm (NR::scale(dc->hatch_spacing, dc->hatch_spacing) * NR::translate(c)); + NR::Matrix const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c)); sp_canvas_item_affine_absolute(dc->hatch_area, sm); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0x7f7f7fff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_item_show(dc->hatch_area); diff --git a/src/eraser-context.cpp b/src/eraser-context.cpp index 382a50edc..d82d7ea89 100644 --- a/src/eraser-context.cpp +++ b/src/eraser-context.cpp @@ -739,7 +739,7 @@ set_to_accumulated(SPEraserContext *dc) Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc()); SPItem* acid = SP_ITEM(desktop->doc()->getObjectByRepr(dc->repr)); - boost::optional<Geom::Rect> eraserBbox = to_2geom(acid->getBounds(Geom::identity())); + boost::optional<Geom::Rect> eraserBbox = acid->getBounds(Geom::identity()); Geom::Rect bounds = (*eraserBbox) * desktop->doc2dt(); std::vector<SPItem*> remainingItems; GSList* toWorkOn = 0; @@ -761,7 +761,7 @@ set_to_accumulated(SPEraserContext *dc) for (GSList *i = toWorkOn ; i ; i = i->next ) { SPItem *item = SP_ITEM(i->data); if ( eraserMode ) { - boost::optional<Geom::Rect> bbox = to_2geom(item->getBounds(Geom::identity())); + boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); if (bbox && bbox->intersects(*eraserBbox)) { Inkscape::XML::Node* dup = dc->repr->duplicate(xml_doc); dc->repr->parent()->appendChild(dup); diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index f308ce157..6bbaa5c06 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -116,7 +116,7 @@ CairoRenderContext::CairoRenderContext(CairoRenderer *parent) : _stream(NULL), _is_valid(FALSE), _vector_based_target(FALSE), - _cr(NULL), + _cr(NULL), // Cairo context _surface(NULL), _target(CAIRO_SURFACE_TYPE_IMAGE), _target_format(CAIRO_FORMAT_ARGB32), @@ -481,8 +481,8 @@ void CairoRenderContext::setClipMode(CairoClipMode mode) { switch (mode) { - case CLIP_MODE_PATH: - case CLIP_MODE_MASK: + case CLIP_MODE_PATH: // Clip is rendered as a path for vector output + case CLIP_MODE_MASK: // Clip is rendered as a bitmap for raster output. _clip_mode = mode; break; default: @@ -538,9 +538,23 @@ CairoRenderContext::popLayer(void) g_assert( _is_valid ); float opacity = _state->opacity; - TRACE(("--popLayer w/ %f\n", opacity)); + TRACE(("--popLayer w/ opacity %f\n", opacity)); + + /* + At this point, the Cairo source is ready. A Cairo mask must be created if required. + Care must be taken of transformatons as Cairo, like PS and PDF, treats clip paths and + masks independently of the objects they effect while in SVG the clip paths and masks + are defined relative to the objects they are attached to. + Notes: + 1. An SVG object may have both a clip path and a mask! + 2. An SVG clip path can be composed of an object with a clip path. This is not handled properly. + 3. An SVG clipped or masked object may be first drawn off the page and then translated onto + the page (document). This is also not handled properly. + 4. The code converts all SVG masks to bitmaps. This shouldn't be necessary. + 5. Cairo expects a mask to use only the alpha channel. SVG masks combine the RGB luminance with + alpha. This is handled here by doing a pixel by pixel conversion. + */ - // apply clipPath or mask if present SPClipPath *clip_path = _state->clip_path; SPMask *mask = _state->mask; if (clip_path || mask) { @@ -548,15 +562,17 @@ CairoRenderContext::popLayer(void) CairoRenderContext *clip_ctx = 0; cairo_surface_t *clip_mask = 0; + // Apply any clip path first if (clip_path) { + TRACE((" Applying clip\n")); if (_render_mode == RENDER_MODE_CLIP) mask = NULL; // disable mask when performing nested clipping if (_vector_based_target) { - setClipMode(CLIP_MODE_PATH); + setClipMode(CLIP_MODE_PATH); // Vector if (!mask) { cairo_pop_group_to_source(_cr); - _renderer->applyClipPath(this, clip_path); + _renderer->applyClipPath(this, clip_path); // Uses cairo_clip() if (opacity == 1.0) cairo_paint(_cr); else @@ -570,7 +586,10 @@ CairoRenderContext::popLayer(void) // setup a new rendering context clip_ctx = _renderer->createContext(); clip_ctx->setImageTarget(CAIRO_FORMAT_A8); - clip_ctx->setClipMode(CLIP_MODE_MASK); + clip_ctx->setClipMode(CLIP_MODE_MASK); // Raster + // This code ties the clipping to the document coordinates. It doesn't allow + // for a clipped object intially drawn off the page and then translated onto + // the page. if (!clip_ctx->setupSurface(_width, _height)) { TRACE(("clip: setupSurface failed\n")); _renderer->destroyContext(clip_ctx); @@ -583,7 +602,7 @@ CairoRenderContext::popLayer(void) cairo_paint(clip_ctx->_cr); cairo_restore(clip_ctx->_cr); - // if a mask won't be applied set opacity too + // If a mask won't be applied set opacity too. (The clip is represented by a solid Cairo mask.) if (!mask) cairo_set_source_rgba(clip_ctx->_cr, 1.0, 1.0, 1.0, opacity); else @@ -614,7 +633,9 @@ CairoRenderContext::popLayer(void) } } + // Apply any mask second if (mask) { + TRACE((" Applying mask\n")); // create rendering context for mask CairoRenderContext *mask_ctx = _renderer->createContext(); @@ -685,6 +706,7 @@ CairoRenderContext::popLayer(void) _renderer->destroyContext(mask_ctx); } } else { + // No clip path or mask cairo_pop_group_to_source(_cr); if (opacity == 1.0) cairo_paint(_cr); diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 72a1790cf..23845598e 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -48,7 +48,7 @@ struct CairoGlyphInfo { struct CairoRenderState { unsigned int merge_opacity : 1; // whether fill/stroke opacity can be mul'd with item opacity - unsigned int need_layer : 1; + unsigned int need_layer : 1; // whether object is masked, clipped, and/or has a non-zero opacity unsigned int has_overflow : 1; unsigned int parent_has_userspace : 1; // whether the parent's ctm should be applied float opacity; @@ -164,7 +164,7 @@ protected: unsigned int _is_valid : 1; unsigned int _vector_based_target : 1; - cairo_t *_cr; + cairo_t *_cr; // Cairo context cairo_surface_t *_surface; cairo_surface_type_t _target; cairo_format_t _target_format; diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index cccb10a8d..07d799b0f 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -28,19 +28,7 @@ #include <signal.h> #include <errno.h> -#include <libnr/nr-matrix-ops.h> -#include <libnr/nr-matrix-fns.h> -#include <libnr/nr-matrix-translate-ops.h> -#include <libnr/nr-scale-matrix-ops.h> - -#include "libnr/nr-matrix-rotate-ops.h" -#include "libnr/nr-matrix-translate-ops.h" -#include "libnr/nr-rotate-fns.h" -#include "libnr/nr-scale-ops.h" -#include "libnr/nr-scale-translate-ops.h" -#include "libnr/nr-translate-matrix-ops.h" -#include "libnr/nr-translate-scale-ops.h" -#include "libnr/nr-convert2geom.h" +#include "libnr/nr-rect.h" #include <2geom/transforms.h> #include <2geom/pathvector.h> diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index cdd02882a..366bab000 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -85,9 +85,9 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc bounding_area = Geom::Rect( Geom::Point(0,0), Geom::Point(sp_document_width(doc), sp_document_height(doc)) ); } else { - boost::optional<NR::Rect> bounds = selection->bounds(); + boost::optional<Geom::Rect> bounds = selection->bounds(); if (bounds) { - bounding_area = to_2geom(*bounds); + bounding_area = *bounds; } gdouble doc_height = sp_document_height(document->doc()); diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index 016906289..a74e17a10 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -964,10 +964,10 @@ static Geom::Matrix getODFTransform(const SPItem *item) */ static boost::optional<Geom::Rect> getODFBoundingBox(const SPItem *item) { - boost::optional<NR::Rect> bbox_temp = sp_item_bbox_desktop((SPItem *)item); + boost::optional<Geom::Rect> bbox_temp = sp_item_bbox_desktop((SPItem *)item); boost::optional<Geom::Rect> bbox; if (bbox_temp) { - bbox = to_2geom(*bbox_temp); + bbox = *bbox_temp; double doc_height = sp_document_height(SP_ACTIVE_DOCUMENT); Geom::Matrix doc2dt_tf = Geom::Matrix(Geom::Scale(1.0, -1.0)); doc2dt_tf = doc2dt_tf * Geom::Matrix(Geom::Translate(0, doc_height)); diff --git a/src/extension/internal/ps.cpp b/src/extension/internal/ps.cpp index 97582bd13..f8b3d999e 100644 --- a/src/extension/internal/ps.cpp +++ b/src/extension/internal/ps.cpp @@ -553,7 +553,7 @@ PrintPS::finish(Inkscape::Extension::Print *mod) int const width = (int) (_width * dots_per_pt + 0.5); int const height = (int) (_height * dots_per_pt + 0.5); - NR::Matrix affine; + Geom::Matrix affine; affine[0] = width / ((x1 - x0) * PX_PER_PT); affine[1] = 0.0; affine[2] = 0.0; @@ -575,7 +575,7 @@ PrintPS::finish(Inkscape::Extension::Print *mod) /* Update to renderable state. */ NRGC gc(NULL); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update(mod->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); /* Render */ /* This should take guchar* instead of unsigned char*) */ diff --git a/src/extension/internal/win32.cpp b/src/extension/internal/win32.cpp index 85f502f00..ecf66ca1f 100644 --- a/src/extension/internal/win32.cpp +++ b/src/extension/internal/win32.cpp @@ -251,7 +251,6 @@ PrintWin32::finish (Inkscape::Extension::Print *mod) float scalex, scaley; int x0, y0, x1, y1; int width, height; - NR::Matrix affine; unsigned char *px; int sheight, row; BITMAPINFO bmInfo = { @@ -293,14 +292,9 @@ PrintWin32::finish (Inkscape::Extension::Print *mod) scaley = dpiY / 72.0; // We simply map document 0,0 to physical page 0,0 - affine[0] = scalex / 1.25; - affine[1] = 0.0; - affine[2] = 0.0; - affine[3] = scaley / 1.25; - affine[4] = 0.0; - affine[5] = 0.0; + Geom::Matrix affine = Geom::Scale(scalex / 1.25, scaley / 1.25); - nr_arena_item_set_transform (mod->root, &affine); + nr_arena_item_set_transform (mod->root, affine); // Calculate printable area in device coordinates x0 = pPhysicalOffsetX; @@ -333,7 +327,7 @@ PrintWin32::finish (Inkscape::Extension::Print *mod) bbox.x1 = bbox.x0 + width; bbox.y1 = bbox.y0 + num_rows; /* Update to renderable state */ - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update (mod->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); nr_pixblock_setup_extern (&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, bbox.x0, bbox.y0, bbox.x1, bbox.y1, px, 4 * (bbox.x1 - bbox.x0), FALSE, FALSE); diff --git a/src/file.cpp b/src/file.cpp index d38efb304..b2f53b967 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -990,7 +990,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, bool const saved_pref = prefs->getBool("options.transform", "pattern", true); prefs->setBool("options.transform", "pattern", true); sp_document_ensure_up_to_date(sp_desktop_document(desktop)); - boost::optional<Geom::Rect> sel_bbox = selection->bounds_2geom(); + boost::optional<Geom::Rect> sel_bbox = selection->bounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); sp_selection_move_relative(selection, m); diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index 0c516aa27..5bb34415d 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -319,20 +319,20 @@ new_filter_blend_gaussian_blur (SPDocument *document, const char *blendmode, gdo SPFilter * new_filter_simple_from_item (SPDocument *document, SPItem *item, const char *mode, gdouble radius) { - boost::optional<NR::Rect> const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); + boost::optional<Geom::Rect> const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); double width; double height; if (r) { - width = r->extent(NR::X); - height= r->extent(NR::Y); + width = r->dimensions()[Geom::X]; + height= r->dimensions()[Geom::Y]; } else { width = height = 0; } - NR::Matrix i2d (sp_item_i2d_affine (item) ); + Geom::Matrix i2d (sp_item_i2d_affine (item) ); - return (new_filter_blend_gaussian_blur (document, mode, radius, NR::expansion(i2d), NR::expansionX(i2d), NR::expansionY(i2d), width, height)); + return (new_filter_blend_gaussian_blur (document, mode, radius, i2d.descrim(), i2d.expansionX(), i2d.expansionY(), width, height)); } /** @@ -374,12 +374,12 @@ modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *item, stdDeviation /= expansion; // Get the object size - boost::optional<NR::Rect> const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); + boost::optional<Geom::Rect> const r = sp_item_bbox_desktop(item, SPItem::GEOMETRIC_BBOX); double width; double height; if (r) { - width = r->extent(NR::X); - height= r->extent(NR::Y); + width = r->dimensions()[Geom::X]; + height= r->dimensions()[Geom::Y]; } else { width = height = 0; } diff --git a/src/flood-context.cpp b/src/flood-context.cpp index d2e6290b2..47e3d3d2b 100644 --- a/src/flood-context.cpp +++ b/src/flood-context.cpp @@ -801,7 +801,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even sp_document_ensure_up_to_date (document); SPItem *document_root = SP_ITEM(SP_DOCUMENT_ROOT(document)); - boost::optional<Geom::Rect> bbox = to_2geom(document_root->getBounds(Geom::identity())); + boost::optional<Geom::Rect> bbox = document_root->getBounds(Geom::identity()); if (!bbox) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("<b>Area is not bounded</b>, cannot fill.")); @@ -833,7 +833,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even nr_arena_item_set_transform(NR_ARENA_ITEM(root), affine); NRGC gc(NULL); - gc.transform.set_identity(); + gc.transform.setIdentity(); NRRectL final_bbox; final_bbox.x0 = 0; diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 26945def6..7b32b37d7 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -284,21 +284,21 @@ sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item) // calculate the bbox of the item sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); - boost::optional<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine + boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine if ( !bbox || bbox->isEmpty() ) return gr; - NR::Coord const width = bbox->dimensions()[NR::X]; - NR::Coord const height = bbox->dimensions()[NR::Y]; + Geom::Coord const width = bbox->dimensions()[Geom::X]; + Geom::Coord const height = bbox->dimensions()[Geom::Y]; - NR::Point const center = bbox->midpoint(); + Geom::Point const center = bbox->midpoint(); if (SP_IS_RADIALGRADIENT(gr)) { - sp_repr_set_svg_double(repr, "cx", center[NR::X]); - sp_repr_set_svg_double(repr, "cy", center[NR::Y]); - sp_repr_set_svg_double(repr, "fx", center[NR::X]); - sp_repr_set_svg_double(repr, "fy", center[NR::Y]); + sp_repr_set_svg_double(repr, "cx", center[Geom::X]); + sp_repr_set_svg_double(repr, "cy", center[Geom::Y]); + sp_repr_set_svg_double(repr, "fx", center[Geom::X]); + sp_repr_set_svg_double(repr, "fy", center[Geom::Y]); sp_repr_set_svg_double(repr, "r", width/2); // we want it to be elliptic, not circular @@ -313,10 +313,10 @@ sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item) g_free(c); } } else { - sp_repr_set_svg_double(repr, "x1", (center - NR::Point(width/2, 0))[NR::X]); - sp_repr_set_svg_double(repr, "y1", (center - NR::Point(width/2, 0))[NR::Y]); - sp_repr_set_svg_double(repr, "x2", (center + NR::Point(width/2, 0))[NR::X]); - sp_repr_set_svg_double(repr, "y2", (center + NR::Point(width/2, 0))[NR::Y]); + sp_repr_set_svg_double(repr, "x1", (center - Geom::Point(width/2, 0))[Geom::X]); + sp_repr_set_svg_double(repr, "y1", (center - Geom::Point(width/2, 0))[Geom::Y]); + sp_repr_set_svg_double(repr, "x2", (center + Geom::Point(width/2, 0))[Geom::X]); + sp_repr_set_svg_double(repr, "y2", (center + Geom::Point(width/2, 0))[Geom::Y]); } // set the gradientUnits @@ -344,15 +344,15 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop // calculate the bbox of the item sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); - NR::Matrix bbox2user; - boost::optional<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine + Geom::Matrix bbox2user; + boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine if ( bbox && !bbox->isEmpty() ) { - bbox2user = NR::Matrix(bbox->dimensions()[NR::X], 0, - 0, bbox->dimensions()[NR::Y], - bbox->min()[NR::X], bbox->min()[NR::Y]); + bbox2user = Geom::Matrix(bbox->dimensions()[Geom::X], 0, + 0, bbox->dimensions()[Geom::Y], + bbox->min()[Geom::X], bbox->min()[Geom::Y]); } else { // would be degenerate otherwise - bbox2user = NR::identity(); + bbox2user = Geom::identity(); } /* skew is the additional transform, defined by the proportions of the item, that we need @@ -369,8 +369,8 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop * gradient vector in user space due to application of the non-uniform scaling * transformation from bounding box space to user space. */ - NR::Matrix skew = bbox2user; - double exp = NR::expansion(skew); + Geom::Matrix skew = bbox2user; + double exp = skew.descrim(); skew[0] /= exp; skew[1] /= exp; skew[2] /= exp; @@ -388,40 +388,40 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop // Matrix to convert points to userspace coords; postmultiply by inverse of skew so // as to cancel it out when it's applied to the gradient during rendering - NR::Matrix point_convert = bbox2user * skew.inverse(); + Geom::Matrix point_convert = bbox2user * skew.inverse(); if (SP_IS_RADIALGRADIENT(gr)) { SPRadialGradient *rg = SP_RADIALGRADIENT(gr); // original points in the bbox coords - NR::Point c_b = NR::Point(rg->cx.computed, rg->cy.computed); - NR::Point f_b = NR::Point(rg->fx.computed, rg->fy.computed); + Geom::Point c_b = Geom::Point(rg->cx.computed, rg->cy.computed); + Geom::Point f_b = Geom::Point(rg->fx.computed, rg->fy.computed); double r_b = rg->r.computed; // converted points in userspace coords - NR::Point c_u = c_b * point_convert; - NR::Point f_u = f_b * point_convert; - double r_u = r_b * NR::expansion(point_convert); - - sp_repr_set_svg_double(repr, "cx", c_u[NR::X]); - sp_repr_set_svg_double(repr, "cy", c_u[NR::Y]); - sp_repr_set_svg_double(repr, "fx", f_u[NR::X]); - sp_repr_set_svg_double(repr, "fy", f_u[NR::Y]); + Geom::Point c_u = c_b * point_convert; + Geom::Point f_u = f_b * point_convert; + double r_u = r_b * point_convert.descrim(); + + sp_repr_set_svg_double(repr, "cx", c_u[Geom::X]); + sp_repr_set_svg_double(repr, "cy", c_u[Geom::Y]); + sp_repr_set_svg_double(repr, "fx", f_u[Geom::X]); + sp_repr_set_svg_double(repr, "fy", f_u[Geom::Y]); sp_repr_set_svg_double(repr, "r", r_u); } else { SPLinearGradient *lg = SP_LINEARGRADIENT(gr); - NR::Point p1_b = NR::Point(lg->x1.computed, lg->y1.computed); - NR::Point p2_b = NR::Point(lg->x2.computed, lg->y2.computed); + Geom::Point p1_b = Geom::Point(lg->x1.computed, lg->y1.computed); + Geom::Point p2_b = Geom::Point(lg->x2.computed, lg->y2.computed); - NR::Point p1_u = p1_b * point_convert; - NR::Point p2_u = p2_b * point_convert; + Geom::Point p1_u = p1_b * point_convert; + Geom::Point p2_u = p2_b * point_convert; - sp_repr_set_svg_double(repr, "x1", p1_u[NR::X]); - sp_repr_set_svg_double(repr, "y1", p1_u[NR::Y]); - sp_repr_set_svg_double(repr, "x2", p2_u[NR::X]); - sp_repr_set_svg_double(repr, "y2", p2_u[NR::Y]); + sp_repr_set_svg_double(repr, "x1", p1_u[Geom::X]); + sp_repr_set_svg_double(repr, "y1", p1_u[Geom::Y]); + sp_repr_set_svg_double(repr, "x2", p2_u[Geom::X]); + sp_repr_set_svg_double(repr, "y2", p2_u[Geom::Y]); } // set the gradientUnits @@ -935,12 +935,12 @@ sp_item_gradient_set_coords (SPItem *item, guint point_type, guint point_i, NR:: double move_angle = NR::atan2(p_w - c_w) - r1_angle; double move_stretch = NR::L2(p_w - c_w) / NR::L2(r1_w - c_w); - NR::Matrix move = NR::Matrix (NR::translate (-c_w)) * - NR::Matrix (NR::rotate(-r1_angle)) * - NR::Matrix (NR::scale(move_stretch, scale? move_stretch : 1)) * - NR::Matrix (NR::rotate(r1_angle)) * - NR::Matrix (NR::rotate(move_angle)) * - NR::Matrix (NR::translate (c_w)); + NR::Matrix move = NR::Matrix (Geom::Translate (-c_w)) * + NR::Matrix (Geom::Rotate(-r1_angle)) * + NR::Matrix (Geom::Scale(move_stretch, scale? move_stretch : 1)) * + NR::Matrix (Geom::Rotate(r1_angle)) * + NR::Matrix (Geom::Rotate(move_angle)) * + NR::Matrix (Geom::Translate (c_w)); new_transform = gradient->gradientTransform * i2d * move * i2d.inverse(); transform_set = true; @@ -954,12 +954,12 @@ sp_item_gradient_set_coords (SPItem *item, guint point_type, guint point_i, NR:: double move_angle = NR::atan2(p_w - c_w) - r2_angle; double move_stretch = NR::L2(p_w - c_w) / NR::L2(r2_w - c_w); - NR::Matrix move = NR::Matrix (NR::translate (-c_w)) * - NR::Matrix (NR::rotate(-r2_angle)) * - NR::Matrix (NR::scale(move_stretch, scale? move_stretch : 1)) * - NR::Matrix (NR::rotate(r2_angle)) * - NR::Matrix (NR::rotate(move_angle)) * - NR::Matrix (NR::translate (c_w)); + NR::Matrix move = NR::Matrix (Geom::Translate (-c_w)) * + NR::Matrix (Geom::Rotate(-r2_angle)) * + NR::Matrix (Geom::Scale(move_stretch, scale? move_stretch : 1)) * + NR::Matrix (Geom::Rotate(r2_angle)) * + NR::Matrix (Geom::Rotate(move_angle)) * + NR::Matrix (Geom::Translate (c_w)); new_transform = gradient->gradientTransform * i2d * move * i2d.inverse(); transform_set = true; @@ -1044,10 +1044,10 @@ sp_item_gradient_get_coords (SPItem *item, guint point_type, guint point_i, bool { SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); - NR::Point p (0, 0); + Geom::Point p (0, 0); if (!gradient) - return p; + return from_2geom(p); if (SP_IS_LINEARGRADIENT(gradient)) { SPLinearGradient *lg = SP_LINEARGRADIENT(gradient); @@ -1061,7 +1061,7 @@ sp_item_gradient_get_coords (SPItem *item, guint point_type, guint point_i, bool case POINT_LG_MID: { gdouble offset = lg->vector.stops.at(point_i).offset; - p = (1-offset) * NR::Point(lg->x1.computed, lg->y1.computed) + offset * NR::Point(lg->x2.computed, lg->y2.computed); + p = (1-offset) * Geom::Point(lg->x1.computed, lg->y1.computed) + offset * Geom::Point(lg->x2.computed, lg->y2.computed); } break; } @@ -1069,27 +1069,27 @@ sp_item_gradient_get_coords (SPItem *item, guint point_type, guint point_i, bool SPRadialGradient *rg = SP_RADIALGRADIENT(gradient); switch (point_type) { case POINT_RG_CENTER: - p = NR::Point (rg->cx.computed, rg->cy.computed); + p = Geom::Point (rg->cx.computed, rg->cy.computed); break; case POINT_RG_FOCUS: - p = NR::Point (rg->fx.computed, rg->fy.computed); + p = Geom::Point (rg->fx.computed, rg->fy.computed); break; case POINT_RG_R1: - p = NR::Point (rg->cx.computed + rg->r.computed, rg->cy.computed); + p = Geom::Point (rg->cx.computed + rg->r.computed, rg->cy.computed); break; case POINT_RG_R2: - p = NR::Point (rg->cx.computed, rg->cy.computed - rg->r.computed); + p = Geom::Point (rg->cx.computed, rg->cy.computed - rg->r.computed); break; case POINT_RG_MID1: { gdouble offset = rg->vector.stops.at(point_i).offset; - p = (1-offset) * NR::Point (rg->cx.computed, rg->cy.computed) + offset * NR::Point(rg->cx.computed + rg->r.computed, rg->cy.computed); + p = (1-offset) * Geom::Point (rg->cx.computed, rg->cy.computed) + offset * Geom::Point(rg->cx.computed + rg->r.computed, rg->cy.computed); } break; case POINT_RG_MID2: { gdouble offset = rg->vector.stops.at(point_i).offset; - p = (1-offset) * NR::Point (rg->cx.computed, rg->cy.computed) + offset * NR::Point(rg->cx.computed, rg->cy.computed - rg->r.computed); + p = (1-offset) * Geom::Point (rg->cx.computed, rg->cy.computed) + offset * Geom::Point(rg->cx.computed, rg->cy.computed - rg->r.computed); } break; } @@ -1097,15 +1097,15 @@ sp_item_gradient_get_coords (SPItem *item, guint point_type, guint point_i, bool if (SP_GRADIENT(gradient)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); - boost::optional<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine + boost::optional<Geom::Rect> bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine if (bbox) { - p *= NR::Matrix(bbox->dimensions()[NR::X], 0, - 0, bbox->dimensions()[NR::Y], - bbox->min()[NR::X], bbox->min()[NR::Y]); + p *= Geom::Matrix(bbox->dimensions()[Geom::X], 0, + 0, bbox->dimensions()[Geom::Y], + bbox->min()[Geom::X], bbox->min()[Geom::Y]); } } - p *= NR::Matrix(gradient->gradientTransform) * (NR::Matrix)sp_item_i2d_affine(item); - return p; + p *= Geom::Matrix(gradient->gradientTransform) * (Geom::Matrix)sp_item_i2d_affine(item); + return from_2geom(p); } diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index 9432d4b5a..994171d13 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -1723,15 +1723,15 @@ GrDrag::updateLevels () for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { SPItem *item = SP_ITEM(i->data); - boost::optional<NR::Rect> rect = sp_item_bbox_desktop (item); + boost::optional<Geom::Rect> rect = sp_item_bbox_desktop (item); if (rect) { // Remember the edges of the bbox and the center axis - hor_levels.push_back(rect->min()[NR::Y]); - hor_levels.push_back(rect->max()[NR::Y]); - hor_levels.push_back(0.5 * (rect->min()[NR::Y] + rect->max()[NR::Y])); - vert_levels.push_back(rect->min()[NR::X]); - vert_levels.push_back(rect->max()[NR::X]); - vert_levels.push_back(0.5 * (rect->min()[NR::X] + rect->max()[NR::X])); + hor_levels.push_back(rect->min()[Geom::Y]); + hor_levels.push_back(rect->max()[Geom::Y]); + hor_levels.push_back(0.5 * (rect->min()[Geom::Y] + rect->max()[Geom::Y])); + vert_levels.push_back(rect->min()[Geom::X]); + vert_levels.push_back(rect->max()[Geom::X]); + vert_levels.push_back(0.5 * (rect->min()[Geom::X] + rect->max()[Geom::X])); } } } diff --git a/src/graphlayout/graphlayout.cpp b/src/graphlayout/graphlayout.cpp index 2fb641316..d0ba2d20e 100644 --- a/src/graphlayout/graphlayout.cpp +++ b/src/graphlayout/graphlayout.cpp @@ -68,7 +68,7 @@ struct CheckProgress : TestConvergence { NR::Rect const item_box(sp_item_bbox_desktop(u)); NR::Point const curr(item_box.midpoint()); NR::Point const dest(r->getCentreX(),r->getCentreY()); - sp_item_move_rel(u, NR::translate(dest - curr)); + sp_item_move_rel(u, Geom::Translate(dest - curr)); } } */ @@ -124,10 +124,10 @@ void graphlayout(GSList const *const items) { ++i) { SPItem *u=*i; - boost::optional<NR::Rect> const item_box(sp_item_bbox_desktop(u)); + boost::optional<Geom::Rect> const item_box(sp_item_bbox_desktop(u)); if(item_box) { - NR::Point ll(item_box->min()); - NR::Point ur(item_box->max()); + Geom::Point ll(item_box->min()); + Geom::Point ur(item_box->max()); nodelookup[u->id]=rs.size(); rs.push_back(new Rectangle(ll[0]-spacing,ur[0]+spacing, ll[1]-spacing,ur[1]+spacing)); @@ -226,10 +226,10 @@ void graphlayout(GSList const *const items) { map<string,unsigned>::iterator i=nodelookup.find(u->id); if(i!=nodelookup.end()) { Rectangle* r=rs[i->second]; - boost::optional<NR::Rect> item_box(sp_item_bbox_desktop(u)); + boost::optional<Geom::Rect> item_box(sp_item_bbox_desktop(u)); if(item_box) { - NR::Point const curr(item_box->midpoint()); - NR::Point const dest(r->getCentreX(),r->getCentreY()); + Geom::Point const curr(item_box->midpoint()); + Geom::Point const dest(r->getCentreX(),r->getCentreY()); sp_item_move_rel(u, Geom::Translate(dest - curr)); } } diff --git a/src/helper/geom.cpp b/src/helper/geom.cpp index caa169a27..84f967860 100644 --- a/src/helper/geom.cpp +++ b/src/helper/geom.cpp @@ -494,8 +494,32 @@ pathv_to_linear_and_cubic_beziers( Geom::PathVector const &pathv ) return output; } +namespace Geom { + +bool transform_equalp(Geom::Matrix const &m0, Geom::Matrix const &m1, Geom::Coord const epsilon) { + return + NR_DF_TEST_CLOSE(m0[0], m1[0], epsilon) && + NR_DF_TEST_CLOSE(m0[1], m1[1], epsilon) && + NR_DF_TEST_CLOSE(m0[2], m1[2], epsilon) && + NR_DF_TEST_CLOSE(m0[3], m1[3], epsilon); +} + + +bool translate_equalp(Geom::Matrix const &m0, Geom::Matrix const &m1, Geom::Coord const epsilon) { + return NR_DF_TEST_CLOSE(m0[4], m1[4], epsilon) && NR_DF_TEST_CLOSE(m0[5], m1[5], epsilon); +} +bool matrix_equalp(Geom::Matrix const &m0, Geom::Matrix const &m1, Geom::Coord const epsilon) { + return transform_equalp(m0, m1, epsilon) && translate_equalp(m0, m1, epsilon); +} + +} //end namespace Geom +/* +The following predefined objects are for reference +and comparison. +*/ +Geom::Matrix GEOM_MATRIX_IDENTITY = Geom::identity(); /* Local Variables: diff --git a/src/helper/geom.h b/src/helper/geom.h index e4cb38fa7..4cda22a1c 100644 --- a/src/helper/geom.h +++ b/src/helper/geom.h @@ -25,6 +25,17 @@ void pathv_matrix_point_bbox_wind_distance ( Geom::PathVector const & pathv, Geo Geom::PathVector pathv_to_linear_and_cubic_beziers( Geom::PathVector const &pathv ); +/* +The following predefined objects are for reference +and comparison. They are defined in helper/geom.cpp +*/ +extern Geom::Matrix GEOM_MATRIX_IDENTITY; + +namespace Geom{ +bool transform_equalp(Geom::Matrix const &m0, Geom::Matrix const &m1, Geom::Coord const epsilon); +bool translate_equalp(Geom::Matrix const &m0, Geom::Matrix const &m1, Geom::Coord const epsilon); +bool matrix_equalp(Geom::Matrix const &m0, Geom::Matrix const &m1, Geom::Coord const epsilon); +} #endif // INKSCAPE_HELPER_GEOM_H /* diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index ee5f72161..9d795c575 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -123,7 +123,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, nr_arena_item_set_transform(NR_ARENA_ITEM(root), affine); NRGC gc(NULL); - gc.transform.set_identity(); + gc.transform.setIdentity(); // We show all and then hide all items we don't want, instead of showing only requested items, // because that would not work if the shown item references something in defs diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index 10fa7d403..dd405b7d9 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -325,7 +325,7 @@ sp_export_get_rows(guchar const **rows, int row, int num_rows, void *data) bbox.y1 = row + num_rows; /* Update to renderable state */ NRGC gc(NULL); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update(ebp->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); diff --git a/src/helper/recthull.h b/src/helper/recthull.h new file mode 100644 index 000000000..59649cfb6 --- /dev/null +++ b/src/helper/recthull.h @@ -0,0 +1,59 @@ +#ifndef SEEN_GEOM_RECT_HULL_H +#define SEEN_GEOM_RECT_HULL_H + +/* ex:set et ts=4 sw=4: */ + +/* + * A class representing the convex hull of a set of points. + * + * Copyright 2004 MenTaLguY <mental@rydia.net> + * + * This code is licensed under the GNU GPL; see COPYING for more information. + */ + +#include <2geom/rect.h> + +namespace Geom { + +class RectHull { +public: + RectHull() : _bounds() {} + explicit RectHull(Point const &p) : _bounds(Rect(p, p)) {} + + boost::optional<Point> midpoint() const { + if (_bounds) { + return _bounds->midpoint(); + } else { + return boost::optional<Point>(); + } + } + + void add(Point const &p) { + if (_bounds) { + _bounds->expandTo(p); + } else { + _bounds = Rect(p, p); + } + } + void add(Rect const &r) { + // Note that this is a hack. when convexhull actually works + // you will need to add all four points. + _bounds = unify(_bounds, r); + } + void add(RectHull const &h) { + if (h._bounds) { + add(*h._bounds); + } + } + + boost::optional<Rect> const &bounds() const { + return _bounds; + } + +private: + boost::optional<Rect> _bounds; +}; + +} /* namespace Geom */ + +#endif diff --git a/src/inkscape.cpp b/src/inkscape.cpp index dca23d539..bf3c25e94 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -148,6 +148,7 @@ static void (* ill_handler) (int) = SIG_DFL; static void (* bus_handler) (int) = SIG_DFL; #define INKSCAPE_PROFILE_DIR "Inkscape" +#define INKSCAPE_LEGACY_PROFILE_DIR ".inkscape" #define MENUS_FILE "menus.xml" @@ -326,8 +327,8 @@ static gint inkscape_autosave(gpointer) gint docnum = 0; SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosaving documents...")); - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); + iter != inkscape->document_set.end(); ++iter) { SPDocument *doc = iter->first; @@ -588,8 +589,8 @@ inkscape_crash_handler (int /*signum*/) gint count = 0; GSList *savednames = NULL; GSList *failednames = NULL; - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); + iter != inkscape->document_set.end(); ++iter) { SPDocument *doc = iter->first; Inkscape::XML::Node *repr; @@ -763,8 +764,8 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui) sp_input_load_from_preferences(); /* DebugDialog redirection. On Linux, default to OFF, on Win32, default to ON. - * Use only if use_gui is enabled - */ + * Use only if use_gui is enabled + */ #ifdef WIN32 #define DEFAULT_LOG_REDIRECT true #else @@ -773,7 +774,7 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui) if (use_gui == TRUE && prefs->getBool("dialogs.debug", "redirect", DEFAULT_LOG_REDIRECT)) { - Inkscape::UI::Dialogs::DebugDialog::getInstance()->captureLogMessages(); + Inkscape::UI::Dialogs::DebugDialog::getInstance()->captureLogMessages(); } /* Check for global remapping of Alt key */ @@ -1186,8 +1187,8 @@ inkscape_add_document (SPDocument *document) // try to insert the pair into the list if (!(inkscape->document_set.insert(std::make_pair(document, 1)).second)) { //insert failed, this key (document) is already in the list - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); + iter != inkscape->document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, increase its count @@ -1211,8 +1212,8 @@ inkscape_remove_document (SPDocument *document) if (!Inkscape::NSApplication::Application::getNewGui()) { - for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); - iter != inkscape->document_set.end(); + for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin(); + iter != inkscape->document_set.end(); ++iter) { if (iter->first == document) { // found this document in list, decrease its count @@ -1384,13 +1385,27 @@ profile_path(const char *filename) } */ } + + if (prefdir) { + prefdir = g_build_filename(prefdir, INKSCAPE_PROFILE_DIR, NULL); + } } #endif if (!prefdir) { - prefdir = homedir_path(".config"); + prefdir = g_build_filename(g_get_user_config_dir(), INKSCAPE_PROFILE_DIR, NULL); + gchar * legacyDir = homedir_path(INKSCAPE_LEGACY_PROFILE_DIR); + + // TODO here is a point to hook in preference migration + + if ( !Inkscape::IO::file_test( prefdir, G_FILE_TEST_EXISTS ) && Inkscape::IO::file_test( legacyDir, G_FILE_TEST_EXISTS ) ) { + prefdir = legacyDir; + } else { + g_free(legacyDir); + legacyDir = 0; + } } } - return g_build_filename(prefdir, INKSCAPE_PROFILE_DIR, filename, NULL); + return g_build_filename(prefdir, filename, NULL); } Inkscape::XML::Node * diff --git a/src/interface.cpp b/src/interface.cpp index 35e7bf957..1bc00a250 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -1256,7 +1256,7 @@ sp_ui_drag_data_received(GtkWidget *widget, int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1); prefs_set_int_attribute("options.transform", "pattern", 1); sp_document_ensure_up_to_date(sp_desktop_document(desktop)); - boost::optional<Geom::Rect> sel_bbox = selection->bounds_2geom(); + boost::optional<Geom::Rect> sel_bbox = selection->bounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); sp_selection_move_relative(selection, m); diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp index 46f21965b..1fd6bc4b5 100644 --- a/src/knot-holder-entity.cpp +++ b/src/knot-holder-entity.cpp @@ -137,7 +137,7 @@ PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &ori if (state) { Geom::Point const q = p_snapped - sp_pattern_extract_trans(pat); - sp_item_adjust_pattern(item, NR::Matrix(NR::translate(q))); + sp_item_adjust_pattern(item, NR::Matrix(Geom::Translate(q))); } item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -182,7 +182,7 @@ PatternKnotHolderEntityAngle::knot_set(Geom::Point const &p, Geom::Point const & // get the scale from the current transform so we can keep it. Geom::Point scl = sp_pattern_extract_scale(pat); - NR::Matrix rot = NR::Matrix(NR::scale(scl)) * NR::Matrix(NR::rotate(theta)); + NR::Matrix rot = NR::Matrix(Geom::Scale(scl)) * NR::Matrix(Geom::Rotate(theta)); Geom::Point const t = sp_pattern_extract_trans(pat); rot[4] = t[NR::X]; rot[5] = t[NR::Y]; diff --git a/src/libnr/nr-convert2geom.h b/src/libnr/nr-convert2geom.h index c8a139aa2..7b501cddc 100644 --- a/src/libnr/nr-convert2geom.h +++ b/src/libnr/nr-convert2geom.h @@ -61,12 +61,6 @@ inline Geom::Scale to_2geom(NR::scale const & in) { return Geom::Scale(in[NR::X], in[NR::Y]); } -inline void to_2geom(std::vector<NR::Point> const &in_NR, std::vector<Geom::Point> &out_2geom) { - for (std::vector<NR::Point>::const_iterator it = in_NR.begin(); it != in_NR.end(); it++) { - out_2geom.push_back(to_2geom(*it)); - } -} - #endif /* diff --git a/src/libnr/nr-rect.cpp b/src/libnr/nr-rect.cpp index 77af27417..620782996 100644 --- a/src/libnr/nr-rect.cpp +++ b/src/libnr/nr-rect.cpp @@ -28,6 +28,17 @@ NRRect::NRRect(boost::optional<NR::Rect> const &rect) { } } +NRRect::NRRect(boost::optional<Geom::Rect> const &rect) { + if (rect) { + x0 = rect->min()[Geom::X]; + y0 = rect->min()[Geom::Y]; + x1 = rect->max()[Geom::X]; + y1 = rect->max()[Geom::Y]; + } else { + nr_rect_d_set_empty(this); + } +} + boost::optional<NR::Rect> NRRect::upgrade() const { if (nr_rect_d_test_empty_ptr(this)) { return boost::optional<NR::Rect>(); @@ -36,6 +47,14 @@ boost::optional<NR::Rect> NRRect::upgrade() const { } } +boost::optional<Geom::Rect> NRRect::upgrade_2geom() const { + if (nr_rect_d_test_empty_ptr(this)) { + return boost::optional<Geom::Rect>(); + } else { + return Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)); + } +} + /** * \param r0 Rectangle. * \param r1 Another rectangle. diff --git a/src/libnr/nr-rect.h b/src/libnr/nr-rect.h index 7d130fd18..83f780efd 100644 --- a/src/libnr/nr-rect.h +++ b/src/libnr/nr-rect.h @@ -25,6 +25,7 @@ #include <boost/optional.hpp> #include <libnr/nr-point-matrix-ops.h> #include <libnr/nr-forward.h> +#include <2geom/rect.h> namespace NR { @@ -243,6 +244,9 @@ struct NRRect { explicit NRRect(boost::optional<NR::Rect> const &rect); operator boost::optional<NR::Rect>() const { return upgrade(); } boost::optional<NR::Rect> upgrade() const; + explicit NRRect(boost::optional<Geom::Rect> const &rect); + operator boost::optional<Geom::Rect>() const { return upgrade_2geom(); } + boost::optional<Geom::Rect> upgrade_2geom() const; NR::Coord x0, y0, x1, y1; }; diff --git a/src/livarot/PathConversion.cpp b/src/livarot/PathConversion.cpp index 7c741ac4c..a7f5a8fd1 100644 --- a/src/livarot/PathConversion.cpp +++ b/src/livarot/PathConversion.cpp @@ -11,8 +11,7 @@ #include "livarot/path-description.h" #include <libnr/nr-matrix.h> -#include <libnr/nr-rotate-ops.h> -#include <libnr/nr-scale-ops.h> +#include <2geom/transforms.h> /* * path description -> polyline @@ -1089,23 +1088,24 @@ void Path::DoArc(NR::Point const &iS, NR::Point const &iE, double sang; double eang; - NR::Point dr; - ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr); + NR::Point dr_temp; + ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr_temp); + Geom::Point dr = dr_temp; /* TODO: This isn't as good numerically as treating iS and iE as primary. E.g. consider the case of low curvature (i.e. very large radius). */ - NR::scale const ar(rx, ry); - NR::rotate cb( angle + sang ); + Geom::Scale const ar(rx, ry); + Geom::Rotate cb( angle + sang ); if (wise) { double const incr = -0.1; if ( sang < eang ) { sang += 2*M_PI; } - NR::rotate const omega(incr); + Geom::Rotate const omega(incr); for (double b = sang + incr ; b > eang ; b += incr) { cb = omega * cb; - AddPoint( cb.vec * ar + dr ); + AddPoint( cb.vector() * ar + dr ); } } else { @@ -1114,10 +1114,10 @@ void Path::DoArc(NR::Point const &iS, NR::Point const &iE, if ( sang > eang ) { sang -= 2*M_PI; } - NR::rotate const omega(incr); + Geom::Rotate const omega(incr); for (double b = sang + incr ; b < eang ; b += incr) { cb = omega * cb; - AddPoint( cb.vec * ar + dr); + AddPoint( cb.vector() * ar + dr); } } } @@ -1231,23 +1231,24 @@ void Path::DoArc(NR::Point const &iS, NR::Point const &iE, double sang; double eang; - NR::Point dr; - ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr); + NR::Point dr_temp; + ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr_temp); + Geom::Point dr = dr_temp; /* TODO: This isn't as good numerically as treating iS and iE as primary. E.g. consider the case of low curvature (i.e. very large radius). */ - NR::scale const ar(rx, ry); - NR::rotate cb(angle + sang); + Geom::Scale const ar(rx, ry); + Geom::Rotate cb(angle + sang); if (wise) { double const incr = -0.1; if ( sang < eang ) { sang += 2*M_PI; } - NR::rotate const omega(incr); + Geom::Rotate const omega(incr); for (double b = sang + incr; b > eang; b += incr) { cb = omega * cb; - AddPoint(cb.vec * ar + dr, piece, (sang - b) / (sang - eang)); + AddPoint(cb.vector() * ar + dr, piece, (sang - b) / (sang - eang)); } } else { @@ -1256,10 +1257,10 @@ void Path::DoArc(NR::Point const &iS, NR::Point const &iE, if ( sang > eang ) { sang -= 2 * M_PI; } - NR::rotate const omega(incr); + Geom::Rotate const omega(incr); for (double b = sang + incr ; b < eang ; b += incr) { cb = omega * cb; - AddPoint(cb.vec * ar + dr, piece, (b - sang) / (eang - sang)); + AddPoint(cb.vector() * ar + dr, piece, (b - sang) / (eang - sang)); } } } @@ -1348,23 +1349,24 @@ void Path::DoArc(NR::Point const &iS, NR::Point const &iE, double sang; double eang; - NR::Point dr; - ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr); + NR::Point dr_temp; + ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr_temp); + Geom::Point dr = dr_temp; /* TODO: This isn't as good numerically as treating iS and iE as primary. E.g. consider the case of low curvature (i.e. very large radius). */ - NR::scale const ar(rx, ry); - NR::rotate cb(angle + sang); + Geom::Scale const ar(rx, ry); + Geom::Rotate cb(angle + sang); if (wise) { double const incr = -0.1; if ( sang < eang ) { sang += 2*M_PI; } - NR::rotate const omega(incr); + Geom::Rotate const omega(incr); for (double b = sang + incr; b > eang ;b += incr) { cb = omega * cb; - AddPoint(cb.vec * ar + dr, piece, (sang - b) / (sang - eang)); + AddPoint(cb.vector() * ar + dr, piece, (sang - b) / (sang - eang)); } } else { @@ -1372,10 +1374,10 @@ void Path::DoArc(NR::Point const &iS, NR::Point const &iE, if ( sang > eang ) { sang -= 2*M_PI; } - NR::rotate const omega(incr); + Geom::Rotate const omega(incr); for (double b = sang + incr ; b < eang ; b += incr) { cb = omega * cb; - AddPoint(cb.vec * ar + dr, piece, (b - sang) / (eang - sang)); + AddPoint(cb.vector() * ar + dr, piece, (b - sang) / (eang - sang)); } } } diff --git a/src/livarot/PathStroke.cpp b/src/livarot/PathStroke.cpp index f4ece6892..e9f2ae677 100644 --- a/src/livarot/PathStroke.cpp +++ b/src/livarot/PathStroke.cpp @@ -8,7 +8,7 @@ #include "Path.h" #include "Shape.h" -#include <libnr/nr-rotate-ops.h> +#include <2geom/transforms.h> /* * stroking polylines into a Shape instance @@ -729,7 +729,7 @@ void Path::RecRound(Shape *dest, int sNo, int eNo, // start and end index ang /= lod; int nbS = (int) floor(ang); - NR::rotate omega(((sia > 0) ? -lod : lod)); + Geom::Rotate omega(((sia > 0) ? -lod : lod)); NR::Point cur = iS - origine; // StrokeNormalize(cur); // cur*=width; diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 418f43b3c..4504f4467 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -86,7 +86,8 @@ findShadowedTime(Geom::Path const &patha, cutterPath.appendNew<LineSegment> (B-width*N); cutterPath.appendNew<LineSegment> (B+width*N); cutterPath.appendNew<LineSegment> (A+width*N); - cutterPath.appendNew<LineSegment> (A-width*N); + cutterPath.close(); + //cutterPath.appendNew<LineSegment> (A-width*N); cutter.push_back(cutterPath); std::vector<Geom::Path> patha_as_vect = std::vector<Geom::Path>(1,patha); @@ -135,16 +136,47 @@ split_at_horiz_vert_tgt (std::vector<Geom::Path> const & path_in){ //LPEKnot specific Crossing Data manipulation. //--------------------------------------------------------------------------- -//TODO: evaluate how lpeknot specific that is. Worth being moved to 2geom? +//TODO: Fix this in 2Geom: I think CrossingSets should not contain duplicates. +Geom::CrossingSet crossingSet_remove_double(Geom::CrossingSet const &input){ + Geom::CrossingSet result(input.size()); + //Yeah, I know, there is a "unique" algorithm for that... + Geom::Crossing last; + for( unsigned i=0; i<input.size(); i++){ + for( unsigned j=0; j<input[i].size(); j++){ + if( j==0 || !(input[i][j]==last) ){ + result[i].push_back(input[i][j]); + last = input[i][j]; + }else{ + g_warning("Duplicate found in a Geom::CrossingSet!"); + } + } + } + return result; +} + +//TODO: evaluate how usefull/lpeknot specific that is. Worth being moved to 2geom? (I doubt it) namespace LPEKnotNS { +//Yet another crossing data representation. Not sure at all it is usefull! +// +: >Given a point, you immediately know which strings are meeting there, +// and the index of the crossing along each string. This makes it easy to check +// topology change. In a CrossingSet, you have to do some search to know the index +// of the crossing along "the second" string (i.e. find the symetric crossing)... +// >Each point is stored only once. +// However, we don't have so many crossing points in general, so none of these points might be relevant. +// +// -: one more clumsy data representation, and "parallelism" failures to expect... +// (in particular, duplicates are hateful with this respect...) + CrossingPoints::CrossingPoints(Geom::CrossingSet const &input, std::vector<Geom::Path> const &path) : std::vector<CrossingPoint>() { using namespace Geom; + g_print("JF>\nCrossing set content:\n"); for( unsigned i=0; i<input.size(); i++){ Crossings i_crossings = input[i]; for( unsigned n=0; n<i_crossings.size(); n++ ){ Crossing c = i_crossings[n]; + g_print("JF> (%u,%u) at times (%f,%f) ----->",c.a,c.b,c.ta,c.tb); unsigned j = c.getOther(i); if (i<j || (i==j && c.ta<c.tb) ){ CrossingPoint cp; @@ -163,6 +195,19 @@ CrossingPoints::CrossingPoints(Geom::CrossingSet const &input, std::vector<Geom: cp.nj = std::find(input[j].begin(),input[j].end(),c_bar)-input[j].begin(); cp.sign = 1; push_back(cp); + g_print("i=%u, ni=%u, j=%u, nj=%u\n",cp.i,cp.ni,cp.j,cp.nj); + } + else{ + g_print("\n"); + bool found = false; + for( unsigned ii=0; ii<input.size(); ii++){ + Crossings ii_crossings = input[ii]; + for( unsigned nn=0; nn<ii_crossings.size(); nn++ ){ + Crossing cc = ii_crossings[nn]; + if (cc.b==c.a && cc.a==c.b && cc.ta==c.tb && cc.tb==c.ta) found = true; + } + } + assert( found ); } } } @@ -214,6 +259,7 @@ CrossingPoints::get(unsigned const i, unsigned const ni) ((*this)[k].j==i && (*this)[k].nj==ni) ) return (*this)[k]; } + g_warning("LPEKnotNS::CrossingPoints::get error. %uth crossing along string %u not found.",ni,i); assert(false);//debug purpose... return CrossingPoint(); } @@ -335,6 +381,20 @@ LPEKnot::doEffect_path (std::vector<Geom::Path> const &input_path) std::vector<Geom::Path> path_in = split_at_horiz_vert_tgt(input_path); CrossingSet crossingTable = crossings_among(path_in); + + for(unsigned i=0;i<crossingTable.size();i++){ + for(unsigned j=0;j<crossingTable[i].size();j++){ + g_print("JF>avant: %u,%u,%f,%f\n",crossingTable[i][j].a, crossingTable[i][j].b, crossingTable[i][j].ta, crossingTable[i][j].tb); + } + } + crossingTable = crossingSet_remove_double(crossingTable); + + for(unsigned i=0;i<crossingTable.size();i++){ + for(unsigned j=0;j<crossingTable[i].size();j++){ + g_print("JF>apres: %u,%u,%f,%f\n",crossingTable[i][j].a, crossingTable[i][j].b, crossingTable[i][j].ta, crossingTable[i][j].tb); + } + } + crossing_points = LPEKnotNS::CrossingPoints(crossingTable, path_in); crossing_points.inherit_signs(old_crdata); crossing_points_vector.param_set_and_write_new_value(crossing_points.to_vector()); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index bb2b908de..cd724b70e 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -47,7 +47,7 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem *lpeitem) SPItem *item = SP_ITEM(lpeitem); Geom::Matrix t = sp_item_i2d_affine(item); - Geom::Rect bbox = to_2geom(*item->getBounds(t)); // fixme: what happens if getBounds does not return a valid rect? + Geom::Rect bbox = *item->getBounds(t); // fixme: what happens if getBounds does not return a valid rect? Point A(bbox.left(), bbox.bottom()); Point B(bbox.left(), bbox.top()); diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index 52ccc29e1..1df0e127a 100644 --- a/src/live_effects/lpe-ruler.cpp +++ b/src/live_effects/lpe-ruler.cpp @@ -19,6 +19,7 @@ #include "inkscape.h" #include "desktop.h" + namespace Inkscape { namespace LivePathEffect { @@ -110,34 +111,51 @@ LPERuler::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_i { using namespace Geom; - Piecewise<D2<SBasis> > pwd2_arclength = arc_length_parametrization(pwd2_in); - Point A(pwd2_arclength.firstValue()); - Point B(pwd2_arclength.lastValue()); - double path_length = Geom::length(pwd2_arclength); - - Piecewise<D2<SBasis> > n = -rot90(unitVector(derivative(pwd2_arclength))); - Piecewise<D2<SBasis> >output(pwd2_arclength); - - if (mark_dir == MARKDIR_RIGHT) { - n *= -1.0; - } - - int j = 0; const int mminterval = static_cast<int>(major_mark_steps); - const int j_shift = static_cast<int>(shift) % mminterval; - - /* draw the ruler */ - if ((border_marks == BORDERMARK_START || border_marks == BORDERMARK_BOTH) && (offset != 0.0 || j_shift != 0)) - output.concat (ruler_mark(A, n.firstValue(), MARK_MAJOR)); - for (double t = offset; t < path_length; t += mark_distance, ++j) { - if ((j % mminterval) == j_shift) { - output.concat (ruler_mark(pwd2_arclength(t), n(t), MARK_MAJOR)); + const int i_shift = static_cast<int>(shift) % mminterval; + int sign = (mark_dir == MARKDIR_RIGHT ? 1 : -1 ); + + Piecewise<D2<SBasis> >output(pwd2_in); + Piecewise<D2<SBasis> >speed = derivative(pwd2_in); + Piecewise<SBasis> arclength = arcLengthSb(pwd2_in); + double totlength = arclength.lastValue(); + + //find at which times to draw a mark: + std::vector<double> s_cuts; + for (double s = offset; s<totlength; s+=mark_distance){ + s_cuts.push_back(s); + } + std::vector<std::vector<double> > roots = multi_roots(arclength, s_cuts); + std::vector<double> t_cuts; + g_warning("times:"); + for (unsigned v=0; v<roots.size();v++){ + //FIXME: 2geom multi_roots solver seem to sometimes "repeat" solutions. + //Here, we are supposed to have one and only one solution for each s. + if(roots[v].size()>0) + t_cuts.push_back(roots[v][0]); + } + //draw the marks + for (unsigned i=0; i<t_cuts.size(); i++){ + Point A = pwd2_in(t_cuts[i]); + Point n = rot90(unit_vector(speed(t_cuts[i])))*sign; + if ((i % mminterval) == i_shift) { + output.concat (ruler_mark(A, n, MARK_MAJOR)); } else { - output.concat (ruler_mark(pwd2_arclength(t), n(t), MARK_MINOR)); + output.concat (ruler_mark(A, n, MARK_MINOR)); } } - if (border_marks == BORDERMARK_END || border_marks == BORDERMARK_BOTH) - output.concat (ruler_mark(B, n.lastValue(), MARK_MAJOR)); + //eventually draw a mark at start + if ((border_marks == BORDERMARK_START || border_marks == BORDERMARK_BOTH) && (offset != 0.0 || i_shift != 0)){ + Point A = pwd2_in.firstValue(); + Point n = rot90(unit_vector(speed.firstValue()))*sign; + output.concat (ruler_mark(A, n, MARK_MAJOR)); + } + //eventually draw a mark at end + if (border_marks == BORDERMARK_END || border_marks == BORDERMARK_BOTH){ + Point A = pwd2_in.lastValue(); + Point n = rot90(unit_vector(speed.lastValue()))*sign; + output.concat (ruler_mark(A, n, MARK_MAJOR)); + } return output; } diff --git a/src/live_effects/lpe-sketch.cpp b/src/live_effects/lpe-sketch.cpp index 6aebcd7fa..a95d89398 100644 --- a/src/live_effects/lpe-sketch.cpp +++ b/src/live_effects/lpe-sketch.cpp @@ -185,8 +185,12 @@ LPESketch::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_ parallel_offset.resetRandomizer(); strokelength_rdm.resetRandomizer(); strokeoverlap_rdm.resetRandomizer(); + ends_tolerance.resetRandomizer(); + tremble_size.resetRandomizer(); tgtlength_rdm.resetRandomizer(); + + // some variables for futur use (for construction lines; compute arclength only once...) // notations will be : t = path time, s = distance from start along the path. Piecewise<SBasis> pathlength; diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp index dd6c5a90a..aab62a75c 100644 --- a/src/live_effects/lpe-spiro.cpp +++ b/src/live_effects/lpe-spiro.cpp @@ -13,6 +13,7 @@ #include <2geom/matrix.h> #include <2geom/bezier-curve.h> #include <2geom/hvlinesegment.h> +#include <2geom/isnan.h> #include "helper/geom-nodetype.h" #include "helper/geom-curves.h" @@ -25,6 +26,8 @@ #include "inkscape.h" #include "desktop.h" +#define SPIRO_SHOW_INFINITE_COORDINATE_CALLS + typedef struct { bezctx base; SPCurve *curve; @@ -34,39 +37,55 @@ typedef struct { void bezctx_ink_moveto(bezctx *bc, double x, double y, int /*is_open*/) { bezctx_ink *bi = (bezctx_ink *) bc; - bi->curve->moveto(x, y); + if ( IS_FINITE(x) && IS_FINITE(y) ) { + bi->curve->moveto(x, y); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("lpe moveto not finite"); + } +#endif } void bezctx_ink_lineto(bezctx *bc, double x, double y) { bezctx_ink *bi = (bezctx_ink *) bc; - bi->curve->lineto(x, y); + if ( IS_FINITE(x) && IS_FINITE(y) ) { + bi->curve->lineto(x, y); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("lpe lineto not finite"); + } +#endif } void bezctx_ink_quadto(bezctx *bc, double xm, double ym, double x3, double y3) { bezctx_ink *bi = (bezctx_ink *) bc; - double x0, y0; - double x1, y1; - double x2, y2; - - Geom::Point last = *(bi->curve->last_point()); - x0 = last[Geom::X]; - y0 = last[Geom::Y]; - x1 = xm + (1./3) * (x0 - xm); - y1 = ym + (1./3) * (y0 - ym); - x2 = xm + (1./3) * (x3 - xm); - y2 = ym + (1./3) * (y3 - ym); - - bi->curve->curveto(x1, y1, x2, y2, x3, y3); + if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { + bi->curve->quadto(xm, ym, x3, y3); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("lpe quadto not finite"); + } +#endif } void bezctx_ink_curveto(bezctx *bc, double x1, double y1, double x2, double y2, double x3, double y3) { bezctx_ink *bi = (bezctx_ink *) bc; - bi->curve->curveto(x1, y1, x2, y2, x3, y3); + if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { + bi->curve->curveto(x1, y1, x2, y2, x3, y3); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("lpe curveto not finite"); + } +#endif } bezctx * @@ -213,20 +232,6 @@ LPESpiro::doEffect(SPCurve * curve) } g_free (path); - - // FIXME: refactor the spiro code such that it cannot generate non-continous paths! - // sometimes, the code above generates a path that is not continuous: caused by chaotic algorithm? - // The continuity error always happens after a lot of curveto calls (a big path probably that spins to infinity?) - // if so, undo the effect by resetting the original path. - try { - curve->get_pathvector() * Geom::identity(); // tests for continuity, this makes LPE Spiro slower of course :-( - } - catch (Geom::ContinuityError & e) { - g_warning("Exception during LPE Spiro execution. \n %s", e.what()); - SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, - _("An exception occurred during execution of the Spiro Path Effect.") ); - curve->set_pathvector(original_pathv); - } } }; //namespace LivePathEffect diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index ef9d38ee4..72d96f5a2 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -7,58 +7,64 @@ */ #include <cstdio> - #include "live_effects/lpe-vonkoch.h" -#include "svg/svg.h" -#include "ui/widget/scalar.h" #include "nodepath.h" +#include <2geom/transforms.h> -#include <2geom/sbasis.h> -#include <2geom/sbasis-geometric.h> -#include <2geom/bezier-to-sbasis.h> -#include <2geom/sbasis-to-bezier.h> -#include <2geom/d2.h> -#include <2geom/piecewise.h> - -#include <algorithm> -using std::vector; - - +//using std::vector; namespace Inkscape { namespace LivePathEffect { -VonKochPathParam::~VonKochPathParam() -{ -} - void VonKochPathParam::param_setup_nodepath(Inkscape::NodePath::Path *np) -{ +{ PathParam::param_setup_nodepath(np); sp_nodepath_make_straight_path(np); } -static const Util::EnumData<VonKochRefType> VonKochRefTypeData[VKREF_END] = { - {VKREF_BBOX, N_("Bounding box"), "bbox"}, - {VKREF_SEG, N_("Last gen. segment"), "lastseg"}, -}; -static const Util::EnumDataConverter<VonKochRefType> VonKochRefTypeConverter(VonKochRefTypeData, VKREF_END); +//FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug. +void +VonKochRefPathParam::param_setup_nodepath(Inkscape::NodePath::Path *np) +{ + PathParam::param_setup_nodepath(np); + sp_nodepath_make_straight_path(np); +} +bool +VonKochRefPathParam::param_readSVGValue(const gchar * strvalue) +{ + std::vector<Geom::Path> old = _pathvector; + bool res = PathParam::param_readSVGValue(strvalue); + if (res && _pathvector.size()==1 && _pathvector.front().size()==1){ + return true; + }else{ + _pathvector = old; + return false; + } +} LPEVonKoch::LPEVonKoch(LivePathEffectObject *lpeobject) : Effect(lpeobject), + ref_path(_("Reference segment"), _("The reference segment. Defaults to bbox diameter."), "ref_path", &wr, this, "M0,0 L10,0"), + //refA(_("Ref Start"), _("Left side middle of the reference box"), "refA", &wr, this), + //refB(_("Ref End"), _("Right side middle of the reference box"), "refB", &wr, this), + generator(_("Generating path"), _("Path whose segments define the iterated transforms"), "generator", &wr, this, "M0,0 L30,0 M0,10 L10,10 M 20,10 L30,10"), + similar_only(_("Use uniform transforms only"), _("2 consecutive segments are used to reverse/preserve orientation only (otherwise, they define a general transform)."), "similar_only", &wr, this, false), nbgenerations(_("Nb of generations"), _("Depth of the recursion --- keep low!!"), "nbgenerations", &wr, this, 1), - generator(_("Generating path"), _("Path whos segments define the fractal"), "generator", &wr, this, "M0,0 L3,0 M0,1 L1,1 M 2,1 L3,1"), - similar_only(_("Use uniform scale/rotation only"), _("If off, 2segments component of generating path can be used to define a general rtansform. If on, they only affect the orientation preserving/reversing of the transform."), "similar_only", &wr, this, false), drawall(_("Draw all generations"), _("If unchecked, draw only the last generation"), "drawall", &wr, this, true), - reftype(_("Reference"), _("Generating path segments define transforms in reference to bbox or last segment"), "reftype", VonKochRefTypeConverter, &wr, this, VKREF_BBOX), + //FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug. maxComplexity(_("Max complexity"), _("Disable effect if the output is too complex"), "maxComplexity", &wr, this, 1000) + //,draw_boxes(_("Display boxes"), _("Display boxes instead of paths only"), "draw_boxes", &wr, this, true) { + //FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug. + registerParameter( dynamic_cast<Parameter *>(&ref_path) ); + //registerParameter( dynamic_cast<Parameter *>(&refA) ); + //registerParameter( dynamic_cast<Parameter *>(&refB) ); registerParameter( dynamic_cast<Parameter *>(&generator) ); + registerParameter( dynamic_cast<Parameter *>(&similar_only) ); registerParameter( dynamic_cast<Parameter *>(&nbgenerations) ); registerParameter( dynamic_cast<Parameter *>(&drawall) ); - registerParameter( dynamic_cast<Parameter *>(&reftype) ); - registerParameter( dynamic_cast<Parameter *>(&similar_only) ); registerParameter( dynamic_cast<Parameter *>(&maxComplexity) ); + //registerParameter( dynamic_cast<Parameter *>(&draw_boxes) ); nbgenerations.param_make_integer(); nbgenerations.param_set_range(0, NR_HUGE); @@ -75,28 +81,27 @@ std::vector<Geom::Path> LPEVonKoch::doEffect_path (std::vector<Geom::Path> const & path_in) { using namespace Geom; - std::vector<Geom::Path> generating_path = path_from_piecewise(generator.get_pwd2(),.01);//TODO what should that tolerance be? + + std::vector<Geom::Path> generating_path = generator.get_pathvector(); + + if (generating_path.size()==0) { + return path_in; + } //Collect transform matrices. - //FIXME: fusing/cutting nodes mix up component order in the path. This is why the last segment is used. Matrix m0; - VonKochRefType type = reftype.get_value(); - if (type==VKREF_BBOX){ - Rect bbox = Rect(boundingbox_X,boundingbox_Y); - m0 = Matrix(boundingbox_X.extent(),0,0,boundingbox_X.extent(), boundingbox_X.min(), boundingbox_Y.middle()); - - }else{ - if (generating_path.size()==0) return path_in; - Point p = generating_path.back().back().pointAt(0); - Point u = generating_path.back().back().pointAt(1)-p; - m0 = Matrix(u[X], u[Y],-u[Y], u[X], p[X], p[Y]); - } + Geom::Path refpath = ref_path.get_pathvector().front(); + Point A = refpath.pointAt(0); + Point B = refpath.pointAt(refpath.size()); + Point u = B-A; + m0 = Matrix(u[X], u[Y],-u[Y], u[X], A[X], A[Y]); + + //FIXME: a path is used as ref instead of 2 points to work around path/point param incompatibility bug. + //Point u = refB-refA; + //m0 = Matrix(u[X], u[Y],-u[Y], u[X], refA[X], refA[Y]); m0 = m0.inverse(); - std::vector<Matrix> transforms; - unsigned end = generating_path.size(); - if (type==VKREF_SEG) end-=1; for (unsigned i=0; i<generating_path.size(); i++){ Matrix m; if(generating_path[i].size()==1){ @@ -109,7 +114,7 @@ LPEVonKoch::doEffect_path (std::vector<Geom::Path> const & path_in) Point p = generating_path[i].pointAt(1); Point u = generating_path[i].pointAt(2)-p; Point v = p-generating_path[i].pointAt(0); - if (similar_only){ + if (similar_only.get_value()){ int sign = (u[X]*v[Y]-u[Y]*v[X]>=0?1:-1); v[X] = -u[Y]*sign; v[Y] = u[X]*sign; @@ -120,13 +125,15 @@ LPEVonKoch::doEffect_path (std::vector<Geom::Path> const & path_in) } } - if (transforms.size()==0) return path_in; + if (transforms.size()==0){ + return path_in; + } - //Do nothing if the output is too complex... + //Do nothing if the output is too complex... int path_in_complexity = 0; for (unsigned k = 0; k < path_in.size(); k++){ path_in_complexity+=path_in[k].size(); - } + } double complexity = pow(transforms.size(),nbgenerations)*path_in_complexity; if (drawall.get_value()){ int k = transforms.size(); @@ -139,13 +146,14 @@ LPEVonKoch::doEffect_path (std::vector<Geom::Path> const & path_in) complexity = pow(transforms.size(),nbgenerations)*path_in_complexity; } if (complexity > double(maxComplexity)){ + g_warning("VonKoch lpe's output too complex. Effect bypassed."); return path_in; } //Generate path: std::vector<Geom::Path> pathi = path_in; std::vector<Geom::Path> path_out = path_in; - + for (unsigned i = 0; i<nbgenerations; i++){ if (drawall.get_value()){ path_out = path_in; @@ -156,7 +164,7 @@ LPEVonKoch::doEffect_path (std::vector<Geom::Path> const & path_in) } for (unsigned j = 0; j<transforms.size(); j++){ for (unsigned k = 0; k<pathi.size() && complexity < maxComplexity; k++){ - path_out.push_back(pathi[k]*transforms[j]); + path_out.push_back(pathi[k]*transforms[j]); complexity+=pathi[k].size(); } } @@ -165,10 +173,98 @@ LPEVonKoch::doEffect_path (std::vector<Geom::Path> const & path_in) return path_out; } + +//Usefull?? +//void +//LPEVonKoch::addCanvasIndicators(SPLPEItem */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) +/*{ + using namespace Geom; + if (draw_boxes.get_value()){ + double ratio = .5; + if (similar_only.get_value()) ratio = boundingbox_Y.extent()/boundingbox_X.extent()/2; + + Point BB1,BB2,BB3,BB4,v; + + //Draw the reference box (ref_path is supposed to consist in one line segment) + //FIXME: a path is used as ref instead of 2 points to work around path/point param incompatibility bug. + Geom::Path refpath = ref_path.get_pathvector().front(); + if (refpath.size()==1){ + BB1 = BB4 = refpath.front().pointAt(0); + BB2 = BB3 = refpath.front().pointAt(1); + v = rot90(BB2 - BB1)*ratio; + BB1 -= v; + BB2 -= v; + BB3 += v; + BB4 += v; + Geom::Path refbox(BB1); + refbox.appendNew<LineSegment>(BB2); + refbox.appendNew<LineSegment>(BB3); + refbox.appendNew<LineSegment>(BB4); + refbox.close(); + PathVector refbox_as_vect; + refbox_as_vect.push_back(refbox); + hp_vec.push_back(refbox_as_vect); + } + //Draw the transformed boxes + std::vector<Geom::Path> generating_path = generator.get_pathvector(); + for (unsigned i=0;i<generating_path.size(); i++){ + if (generating_path[i].size()==0){ + //Ooops! this should not happen. + }else if (generating_path[i].size()==1){ + BB1 = BB4 = generating_path[i].pointAt(0); + BB2 = BB3 = generating_path[i].pointAt(1); + v = rot90(BB2 - BB1)*ratio; + }else{//Only tak the first 2 segments into account. + BB1 = BB4 = generating_path[i].pointAt(1); + BB2 = BB3 = generating_path[i].pointAt(2); + if(similar_only.get_value()){ + v = rot90(BB2 - BB1)*ratio; + }else{ + v = (generating_path[i].pointAt(0) - BB1)*ratio; + } + } + BB1 -= v; + BB2 -= v; + BB3 += v; + BB4 += v; + Geom::Path path(BB1); + path.appendNew<LineSegment>(BB2); + path.appendNew<LineSegment>(BB3); + path.appendNew<LineSegment>(BB4); + path.close(); + PathVector pathv; + pathv.push_back(path); + hp_vec.push_back(pathv); + } + } +} +*/ + void LPEVonKoch::doBeforeEffect (SPLPEItem *lpeitem) { + using namespace Geom; original_bbox(lpeitem); + + std::vector<Geom::Path> paths = ref_path.get_pathvector(); + Geom::Point A,B; + if (paths.size()==0||paths.front().size()==0){ + //FIXME: a path is used as ref instead of 2 points to work around path/point param incompatibility bug. + //refA.param_setValue( Geom::Point(boundingbox_X.min(), boundingbox_Y.middle()) ); + //refB.param_setValue( Geom::Point(boundingbox_X.max(), boundingbox_Y.middle()) ); + A = Point(boundingbox_X.min(), boundingbox_Y.middle()); + B = Point(boundingbox_X.max(), boundingbox_Y.middle()); + }else{ + A = paths.front().pointAt(0); + B = paths.front().pointAt(paths.front().size()); + } + if (paths.size()!=1||paths.front().size()!=1){ + Geom::Path tmp_path(A); + tmp_path.appendNew<LineSegment>(B); + std::vector<Geom::Path> tmp_pathv; + tmp_pathv.push_back(tmp_path); + ref_path.set_new_value(tmp_pathv,true); + } } @@ -177,17 +273,36 @@ LPEVonKoch::resetDefaults(SPItem * item) { using namespace Geom; original_bbox(SP_LPE_ITEM(item)); - Point start(boundingbox_X.min(), boundingbox_Y.middle()); - Point end(boundingbox_X.max(), boundingbox_Y.middle()); - std::vector<Geom::Path> paths; - Geom::Path path = Geom::Path(start); - path.appendNew<Geom::LineSegment>( end ); - paths.push_back(path * Matrix(1./3,0,0,1./3,start[X]*2./3,start[Y]*2./3 + boundingbox_Y.extent()/2)); - paths.push_back(path * Matrix(1./3,0,0,1./3, end[X]*2./3, end[Y]*2./3 + boundingbox_Y.extent()/2)); - paths.push_back(path); + Point A,B; + A[Geom::X] = boundingbox_X.min(); + A[Geom::Y] = boundingbox_Y.middle(); + B[Geom::X] = boundingbox_X.max(); + B[Geom::Y] = boundingbox_Y.middle(); + + std::vector<Geom::Path> paths,refpaths; + Geom::Path path = Geom::Path(A); + path.appendNew<Geom::LineSegment>(B); + refpaths.push_back(path); + ref_path.set_new_value(refpaths, true); + + paths.push_back(path * Matrix(1./3,0,0,1./3, A[X]*2./3, A[Y]*2./3 + boundingbox_Y.extent()/2)); + paths.push_back(path * Matrix(1./3,0,0,1./3, B[X]*2./3, B[Y]*2./3 + boundingbox_Y.extent()/2)); generator.set_new_value(paths, true); + + //FIXME: a path is used as ref instead of 2 points to work around path/point param incompatibility bug. + //refA[Geom::X] = boundingbox_X.min(); + //refA[Geom::Y] = boundingbox_Y.middle(); + //refB[Geom::X] = boundingbox_X.max(); + //refB[Geom::Y] = boundingbox_Y.middle(); + //std::vector<Geom::Path> paths; + //Geom::Path path = Geom::Path( (Point) refA); + //path.appendNew<Geom::LineSegment>( (Point) refB ); + //paths.push_back(path * Matrix(1./3,0,0,1./3, refA[X]*2./3, refA[Y]*2./3 + boundingbox_Y.extent()/2)); + //paths.push_back(path * Matrix(1./3,0,0,1./3, refB[X]*2./3, refB[Y]*2./3 + boundingbox_Y.extent()/2)); + //paths.push_back(path); + //generator.set_new_value(paths, true); } void diff --git a/src/live_effects/lpe-vonkoch.h b/src/live_effects/lpe-vonkoch.h index 011602eaf..16964f527 100644 --- a/src/live_effects/lpe-vonkoch.h +++ b/src/live_effects/lpe-vonkoch.h @@ -12,30 +12,38 @@ #include "live_effects/effect.h" #include "live_effects/lpegroupbbox.h" #include "live_effects/parameter/path.h" -#include "live_effects/parameter/enum.h" +#include "live_effects/parameter/point.h" #include "live_effects/parameter/bool.h" namespace Inkscape { namespace LivePathEffect { -enum VonKochRefType { - VKREF_BBOX = 0, - VKREF_SEG, - VKREF_END // This must be last -}; - class VonKochPathParam : public PathParam{ public: VonKochPathParam ( const Glib::ustring& label, - const Glib::ustring& tip, - const Glib::ustring& key, - Inkscape::UI::Widget::Registry* wr, - Effect* effect, - const gchar * default_value = "M0,0 L1,1"):PathParam(label,tip,key,wr,effect,default_value){}; - virtual ~VonKochPathParam(); - virtual void param_setup_nodepath(Inkscape::NodePath::Path *np); + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + const gchar * default_value = "M0,0 L1,1"):PathParam(label,tip,key,wr,effect,default_value){} + virtual ~VonKochPathParam(){} + virtual void param_setup_nodepath(Inkscape::NodePath::Path *np); }; + //FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug. +class VonKochRefPathParam : public PathParam{ +public: + VonKochRefPathParam ( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + const gchar * default_value = "M0,0 L1,1"):PathParam(label,tip,key,wr,effect,default_value){} + virtual ~VonKochRefPathParam(){} + virtual void param_setup_nodepath(Inkscape::NodePath::Path *np); + virtual bool param_readSVGValue(const gchar * strvalue); + }; + class LPEVonKoch : public Effect, GroupBBoxEffect { public: LPEVonKoch(LivePathEffectObject *lpeobject); @@ -49,16 +57,22 @@ public: virtual void transform_multiply(Geom::Matrix const& postmul, bool set); + //Usefull?? + // protected: + //virtual void addCanvasIndicators(SPLPEItem *lpeitem, std::vector<Geom::PathVector> &hp_vec); + private: ScalarParam nbgenerations; VonKochPathParam generator; BoolParam similar_only; BoolParam drawall; - EnumParam<VonKochRefType> reftype; + //BoolParam draw_boxes; + //FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug. + VonKochRefPathParam ref_path; + // PointParam refA; + // PointParam refB; ScalarParam maxComplexity; - //void on_pattern_pasted(); - LPEVonKoch(const LPEVonKoch&); LPEVonKoch& operator=(const LPEVonKoch&); }; diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index c11e99ecd..79e6857f0 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -27,7 +27,7 @@ GroupBBoxEffect::original_bbox(SPLPEItem *lpeitem, bool absolute) transform = Geom::identity(); } - Geom::Rect itemBBox = to_2geom(*item->getBounds(transform, SPItem::GEOMETRIC_BBOX)); // fixme: fix for when getBounds returns invalid Rect + Geom::Rect itemBBox = *item->getBounds(transform, SPItem::GEOMETRIC_BBOX); // fixme: fix for when getBounds returns invalid Rect boundingbox_X = itemBBox[Geom::X]; boundingbox_Y = itemBBox[Geom::Y]; } diff --git a/src/live_effects/lpeobject.cpp b/src/live_effects/lpeobject.cpp index ab49de14f..ec0dee0be 100644 --- a/src/live_effects/lpeobject.cpp +++ b/src/live_effects/lpeobject.cpp @@ -21,15 +21,6 @@ //#define LIVEPATHEFFECT_VERBOSE -static void livepatheffect_class_init(LivePathEffectObjectClass *klass); -static void livepatheffect_init(LivePathEffectObject *stop); - -static void livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void livepatheffect_release(SPObject *object); - -static void livepatheffect_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *livepatheffect_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); - static void livepatheffect_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data); static SPObjectClass *livepatheffect_parent_class; @@ -37,7 +28,7 @@ static SPObjectClass *livepatheffect_parent_class; * Registers the LivePathEffect class with Gdk and returns its type number. */ GType -livepatheffect_get_type () +LivePathEffectObject::livepatheffect_get_type () { static GType livepatheffect_type = 0; @@ -45,11 +36,11 @@ livepatheffect_get_type () GTypeInfo livepatheffect_info = { sizeof (LivePathEffectObjectClass), NULL, NULL, - (GClassInitFunc) livepatheffect_class_init, + (GClassInitFunc) LivePathEffectObject::livepatheffect_class_init, NULL, NULL, sizeof (LivePathEffectObject), 16, - (GInstanceInitFunc) livepatheffect_init, + (GInstanceInitFunc) LivePathEffectObject::livepatheffect_init, NULL, }; livepatheffect_type = g_type_register_static (SP_TYPE_OBJECT, "LivePathEffectObject", &livepatheffect_info, (GTypeFlags)0); @@ -69,8 +60,8 @@ static Inkscape::XML::NodeEventVector const livepatheffect_repr_events = { /** * Callback to initialize livepatheffect vtable. */ -static void -livepatheffect_class_init(LivePathEffectObjectClass *klass) +void +LivePathEffectObject::livepatheffect_class_init(LivePathEffectObjectClass *klass) { SPObjectClass *sp_object_class = (SPObjectClass *) klass; @@ -86,8 +77,8 @@ livepatheffect_class_init(LivePathEffectObjectClass *klass) /** * Callback to initialize livepatheffect object. */ -static void -livepatheffect_init(LivePathEffectObject *lpeobj) +void +LivePathEffectObject::livepatheffect_init(LivePathEffectObject *lpeobj) { #ifdef LIVEPATHEFFECT_VERBOSE g_message("Init livepatheffectobject"); @@ -101,8 +92,8 @@ livepatheffect_init(LivePathEffectObject *lpeobj) /** * Virtual build: set livepatheffect attributes from its associated XML node. */ -static void -livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +void +LivePathEffectObject::livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { #ifdef LIVEPATHEFFECT_VERBOSE g_message("Build livepatheffect"); @@ -126,8 +117,8 @@ livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node /** * Virtual release of livepatheffect members before destruction. */ -static void -livepatheffect_release(SPObject *object) +void +LivePathEffectObject::livepatheffect_release(SPObject *object) { #ifdef LIVEPATHEFFECT_VERBOSE g_print("Releasing livepatheffect"); @@ -168,8 +159,8 @@ livepatheffect_release(SPObject *object) /** * Virtual set: set attribute to value. */ -static void -livepatheffect_set(SPObject *object, unsigned key, gchar const *value) +void +LivePathEffectObject::livepatheffect_set(SPObject *object, unsigned key, gchar const *value) { LivePathEffectObject *lpeobj = LIVEPATHEFFECT(object); #ifdef LIVEPATHEFFECT_VERBOSE @@ -202,8 +193,8 @@ livepatheffect_set(SPObject *object, unsigned key, gchar const *value) /** * Virtual write: write object attributes to repr. */ -static Inkscape::XML::Node * -livepatheffect_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +Inkscape::XML::Node * +LivePathEffectObject::livepatheffect_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { #ifdef LIVEPATHEFFECT_VERBOSE g_print("Write livepatheffect"); @@ -243,10 +234,10 @@ livepatheffect_on_repr_attr_changed ( Inkscape::XML::Node * /*repr*/, return; LivePathEffectObject *lpeobj = (LivePathEffectObject*) data; - if (!lpeobj->lpe) + if (!lpeobj->get_lpe()) return; - lpeobj->lpe->setParameter(key, newval); + lpeobj->get_lpe()->setParameter(key, newval); lpeobj->requestModified(SP_OBJECT_MODIFIED_FLAG); } diff --git a/src/live_effects/lpeobject.h b/src/live_effects/lpeobject.h index f141f07ca..dc631a5c1 100644 --- a/src/live_effects/lpeobject.h +++ b/src/live_effects/lpeobject.h @@ -12,26 +12,49 @@ #include "sp-object.h" #include "effect.h" -#define TYPE_LIVEPATHEFFECT (livepatheffect_get_type()) +namespace Inkscape { +namespace XML { +class Node; +class Document; +} +} + +#define TYPE_LIVEPATHEFFECT (LivePathEffectObject::livepatheffect_get_type()) #define LIVEPATHEFFECT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), TYPE_LIVEPATHEFFECT, LivePathEffectObject)) #define IS_LIVEPATHEFFECT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), TYPE_LIVEPATHEFFECT)) +/// The LivePathEffect vtable. +struct LivePathEffectObjectClass { + SPObjectClass parent_class; +}; + class LivePathEffectObject : public SPObject { public: Inkscape::LivePathEffect::EffectType effecttype; - Inkscape::LivePathEffect::Effect *lpe; bool effecttype_set; LivePathEffectObject * fork_private_if_necessary(unsigned int nr_of_allowed_users = 1); -}; -/// The LivePathEffect vtable. -struct LivePathEffectObjectClass { - SPObjectClass parent_class; + /* Note that the returned pointer can be NULL in a valid LivePathEffectObject contained in a valid list of lpeobjects in an lpeitem! + * So one should always check whether the returned value is NULL or not */ + Inkscape::LivePathEffect::Effect * get_lpe() { return lpe; }; + +private: + Inkscape::LivePathEffect::Effect *lpe; // this can be NULL in a valid LivePathEffectObject + + /* C-style class functions: */ +public: + static GType livepatheffect_get_type(); +private: + static void livepatheffect_class_init(LivePathEffectObjectClass *klass); + static void livepatheffect_init(LivePathEffectObject *stop); + static void livepatheffect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); + static void livepatheffect_release(SPObject *object); + static void livepatheffect_set(SPObject *object, unsigned key, gchar const *value); + static Inkscape::XML::Node *livepatheffect_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); }; -GType livepatheffect_get_type(); #endif diff --git a/src/live_effects/parameter/pointparam-knotholder.cpp b/src/live_effects/parameter/pointparam-knotholder.cpp index 34c149b4b..b814f597d 100644 --- a/src/live_effects/parameter/pointparam-knotholder.cpp +++ b/src/live_effects/parameter/pointparam-knotholder.cpp @@ -117,7 +117,8 @@ static void pointparam_knot_moved_handler(SPKnot */*knot*/, Geom::Point const *p Inkscape::SVGOStringStream os; os << pos; - kh->lpeobject->lpe->setParameter(kh->repr_key, os.str().c_str()); + // note: get_lpe() will always return a valid pointer? + kh->lpeobject->get_lpe()->setParameter(kh->repr_key, os.str().c_str()); } static void pointparam_knot_ungrabbed_handler(SPKnot *knot, unsigned int /*state*/, PointParamKnotHolder *kh) diff --git a/src/main.cpp b/src/main.cpp index ebc7ddcdc..7dcf9bf95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1053,11 +1053,11 @@ do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gch SPItem *item = ((SPItem *) o); // "true" SVG bbox for scripting - boost::optional<NR::Rect> area = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> area = item->getBounds(sp_item_i2doc_affine(item)); if (area) { Inkscape::SVGOStringStream os; if (extent) { - os << area->extent(axis); + os << area->dimensions()[axis]; } else { os << area->min()[axis]; } @@ -1086,14 +1086,14 @@ do_query_all_recurse (SPObject *o) { SPItem *item = ((SPItem *) o); if (o->id && SP_IS_ITEM(item)) { - boost::optional<NR::Rect> area = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> area = item->getBounds(sp_item_i2doc_affine(item)); if (area) { Inkscape::SVGOStringStream os; os << o->id; - os << "," << area->min()[NR::X]; - os << "," << area->min()[NR::Y]; - os << "," << area->extent(NR::X); - os << "," << area->extent(NR::Y); + os << "," << area->min()[Geom::X]; + os << "," << area->min()[Geom::Y]; + os << "," << area->dimensions()[Geom::X]; + os << "," << area->dimensions()[Geom::Y]; g_print ("%s\n", os.str().c_str()); } } @@ -1178,7 +1178,7 @@ sp_do_export_png(SPDocument *doc) // write object bbox to area sp_document_ensure_up_to_date (doc); - boost::optional<NR::Rect> areaMaybe; + boost::optional<Geom::Rect> areaMaybe; sp_item_invoke_bbox((SPItem *) o_area, areaMaybe, sp_item_i2r_affine((SPItem *) o_area), TRUE); if (areaMaybe) { area = NRRect(areaMaybe); diff --git a/src/marker.cpp b/src/marker.cpp index 49486476d..fded90c4a 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -481,7 +481,7 @@ sp_marker_update (SPObject *object, SPCtx *ctx, guint flags) for (v = marker->views; v != NULL; v = v->next) { for (unsigned i = 0 ; i < v->size ; i++) { if (v->items[i]) { - NR::Matrix tmp = from_2geom(marker->c2p); + Geom::Matrix tmp = marker->c2p; nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->items[i]), &tmp); } } @@ -649,7 +649,7 @@ sp_marker_show_instance ( SPMarker *marker, NRArenaItem *parent, /* fixme: Position (Lauris) */ nr_arena_item_add_child (parent, v->items[pos], NULL); /* nr_arena_item_unref (v->items[pos]); */ - NR::Matrix tmp = from_2geom(marker->c2p); + Geom::Matrix tmp = marker->c2p; nr_arena_group_set_child_transform((NRArenaGroup *) v->items[pos], &tmp); } } diff --git a/src/nodepath.cpp b/src/nodepath.cpp index c3242ccc1..adcfd8d76 100644 --- a/src/nodepath.cpp +++ b/src/nodepath.cpp @@ -191,11 +191,13 @@ sp_nodepath_create_helperpaths(Inkscape::NodePath::Path *np) { PathEffectList lpelist = sp_lpe_item_get_effect_list(lpeitem); for (PathEffectList::iterator i = lpelist.begin(); i != lpelist.end(); ++i) { Inkscape::LivePathEffect::LPEObjectReference *lperef = (*i); - Inkscape::LivePathEffect::Effect *lpe = lperef->lpeobject->lpe; - // create new canvas items from the effect's helper paths - std::vector<Geom::PathVector> hpaths = lpe->getHelperPaths(lpeitem); - for (std::vector<Geom::PathVector>::iterator j = hpaths.begin(); j != hpaths.end(); ++j) { - (*np->helper_path_vec)[lpe].push_back(canvasitem_from_pathvec(np, *j, true)); + Inkscape::LivePathEffect::Effect *lpe = lperef->lpeobject->get_lpe(); + if (lpe) { + // create new canvas items from the effect's helper paths + std::vector<Geom::PathVector> hpaths = lpe->getHelperPaths(lpeitem); + for (std::vector<Geom::PathVector>::iterator j = hpaths.begin(); j != hpaths.end(); ++j) { + (*np->helper_path_vec)[lpe].push_back(canvasitem_from_pathvec(np, *j, true)); + } } } } @@ -211,17 +213,19 @@ sp_nodepath_update_helperpaths(Inkscape::NodePath::Path *np) { SPLPEItem *lpeitem = SP_LPE_ITEM(np->item); PathEffectList lpelist = sp_lpe_item_get_effect_list(lpeitem); for (PathEffectList::iterator i = lpelist.begin(); i != lpelist.end(); ++i) { - Inkscape::LivePathEffect::Effect *lpe = (*i)->lpeobject->lpe; - /* update canvas items from the effect's helper paths; note that this code relies on the - * fact that getHelperPaths() will always return the same number of helperpaths in the same - * order as during their creation in sp_nodepath_create_helperpaths - */ - std::vector<Geom::PathVector> hpaths = lpe->getHelperPaths(lpeitem); - for (unsigned int j = 0; j < hpaths.size(); ++j) { - SPCurve *curve = new SPCurve(hpaths[j]); - curve->transform(np->i2d); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(((*np->helper_path_vec)[lpe])[j]), curve); - curve = curve->unref(); + Inkscape::LivePathEffect::Effect *lpe = (*i)->lpeobject->get_lpe(); + if (lpe) { + /* update canvas items from the effect's helper paths; note that this code relies on the + * fact that getHelperPaths() will always return the same number of helperpaths in the same + * order as during their creation in sp_nodepath_create_helperpaths + */ + std::vector<Geom::PathVector> hpaths = lpe->getHelperPaths(lpeitem); + for (unsigned int j = 0; j < hpaths.size(); ++j) { + SPCurve *curve = new SPCurve(hpaths[j]); + curve->transform(np->i2d); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(((*np->helper_path_vec)[lpe])[j]), curve); + curve = curve->unref(); + } } } } @@ -316,10 +320,15 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object, np->d2i = np->i2d.inverse(); np->repr = repr; - if (repr_key_in) { // apparantly the object is an LPEObject + if (repr_key_in) { // apparently the object is an LPEObject (this is a dirty check, hopefully nobody tries feeding non-lpeobjects into this method with non-null repr_key_in) np->repr_key = g_strdup(repr_key_in); np->repr_nodetypes_key = g_strconcat(np->repr_key, "-nodetypes", NULL); - Inkscape::LivePathEffect::Parameter *lpeparam = LIVEPATHEFFECT(object)->lpe->getParameter(repr_key_in); + Inkscape::LivePathEffect::Effect * lpe = LIVEPATHEFFECT(object)->get_lpe(); + if (!lpe) { + g_error("sp_nodepath_new: lpeobject without real lpe passed as argument!"); + sp_nodepath_destroy(np); + } + Inkscape::LivePathEffect::Parameter *lpeparam = lpe->getParameter(repr_key_in); if (lpeparam) { lpeparam->param_setup_nodepath(np); } @@ -4874,10 +4883,13 @@ void sp_nodepath_set_curve (Inkscape::NodePath::Path *np, SPCurve *curve) { sp_shape_set_curve(SP_SHAPE(np->object), curve, true); } } else if ( IS_LIVEPATHEFFECT(np->object) ) { - Inkscape::LivePathEffect::PathParam *pathparam = dynamic_cast<Inkscape::LivePathEffect::PathParam *>( LIVEPATHEFFECT(np->object)->lpe->getParameter(np->repr_key) ); - if (pathparam) { - pathparam->set_new_value(np->curve->get_pathvector(), false); // do not write to SVG - np->object->requestModified(SP_OBJECT_MODIFIED_FLAG); + Inkscape::LivePathEffect::Effect * lpe = LIVEPATHEFFECT(np->object)->get_lpe(); + if (lpe) { + Inkscape::LivePathEffect::PathParam *pathparam = dynamic_cast<Inkscape::LivePathEffect::PathParam *>( lpe->getParameter(np->repr_key) ); + if (pathparam) { + pathparam->set_new_value(np->curve->get_pathvector(), false); // do not write to SVG + np->object->requestModified(SP_OBJECT_MODIFIED_FLAG); + } } } } diff --git a/src/object-edit.cpp b/src/object-edit.cpp index 400354d4a..63e404e4b 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -749,7 +749,7 @@ ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*or ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE; Geom::Point delta = p - Geom::Point(ge->cx.computed, ge->cy.computed); - NR::scale sc(ge->rx.computed, ge->ry.computed); + Geom::Scale sc(ge->rx.computed, ge->ry.computed); ge->start = atan2(delta * sc.inverse()); if ( ( state & GDK_CONTROL_MASK ) && snaps ) @@ -780,7 +780,7 @@ ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*orig ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE; Geom::Point delta = p - Geom::Point(ge->cx.computed, ge->cy.computed); - NR::scale sc(ge->rx.computed, ge->ry.computed); + Geom::Scale sc(ge->rx.computed, ge->ry.computed); ge->end = atan2(delta * sc.inverse()); if ( ( state & GDK_CONTROL_MASK ) && snaps ) diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 13fba8060..cbf31c271 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -138,20 +138,20 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, if (SP_IS_GROUP(o)) { _findCandidates(o, it, false, bbox_to_snap, snap_dim, false, Geom::identity()); } else { - boost::optional<NR::Rect> bbox_of_item = NR::Rect(); + boost::optional<Geom::Rect> bbox_of_item = Geom::Rect(); if (clip_or_mask) { // Oh oh, this will get ugly. We cannot use sp_item_i2d_affine directly because we need to // insert an additional transformation in document coordinates (code copied from sp_item_i2d_affine) sp_item_invoke_bbox(item, bbox_of_item, - from_2geom(to_2geom(sp_item_i2doc_affine(item)) * matrix_to_desktop(additional_affine, item)), + sp_item_i2doc_affine(item) * matrix_to_desktop(additional_affine, item), true); } else { sp_item_invoke_bbox(item, bbox_of_item, sp_item_i2d_affine(item), true); } if (bbox_of_item) { // See if the item is within range - if (bbox_to_snap_incl.intersects(to_2geom(*bbox_of_item))) { + if (bbox_to_snap_incl.intersects(*bbox_of_item)) { // This item is within snapping range, so record it as a candidate _candidates->push_back(SnapCandidate(item, clip_or_mask, additional_affine)); } @@ -204,9 +204,7 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::Snapper::PointType const & //Collect all nodes so we can snap to them if (_snap_to_itemnode) { if (!(_strict_snapping && !p_is_a_node) || p_is_a_guide) { - std::vector<NR::Point> dummy_vctr; - sp_item_snappoints(root_item, _include_item_center, SnapPointsIter(dummy_vctr)); - to_2geom(dummy_vctr, *_points_to_snap_to); + sp_item_snappoints(root_item, _include_item_center, SnapPointsIter(*_points_to_snap_to)); } } @@ -216,10 +214,10 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::Snapper::PointType const & // Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox // of the item AND the bbox of the clipping path at the same time if (!(*i).clip_or_mask) { - boost::optional<NR::Rect> b = sp_item_bbox_desktop(root_item, bbox_type); + boost::optional<Geom::Rect> b = sp_item_bbox_desktop(root_item, bbox_type); if (b) { for ( unsigned k = 0 ; k < 4 ; k++ ) { - _points_to_snap_to->push_back(to_2geom(b->corner(k))); + _points_to_snap_to->push_back(b->corner(k)); } } } diff --git a/src/preferences.cpp b/src/preferences.cpp index 7ebc4b30f..54ab79448 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -2,7 +2,7 @@ * @brief Singleton class to access the preferences file - implementation */ /* Authors: - * Krzysztof KosiÅ„ski <tweenk.pl@gmail.com> + * Krzysztof Kosinski <tweenk.pl@gmail.com> * * Copyright (C) 2008 Authors * @@ -35,11 +35,11 @@ Preferences::Preferences() : gchar *path = profile_path(NULL); _prefs_dir = path; g_free(path); - + path = profile_path(_prefs_basename.data()); _prefs_filename = path; g_free(path); - + _load(); } @@ -70,12 +70,12 @@ void Preferences::_loadDefaults() void Preferences::_load() { _loadDefaults(); - + Glib::ustring const not_saved = _("Inkscape will run with default settings, " "and new settings will not be saved. "); - + // NOTE: After we upgrade to Glib 2.16, use Glib::ustring::compose - + // 1. Does the file exist? if (!g_file_test(_prefs_filename.data(), G_FILE_TEST_EXISTS)) { // No - we need to create one. @@ -99,7 +99,7 @@ void Preferences::_load() g_mkdir(dir, 0755); g_free(dir); } - + } else if (!g_file_test(_prefs_dir.data(), G_FILE_TEST_IS_DIR)) { // The profile dir is not actually a directory //_errorDialog(Glib::ustring::compose(_("%1 is not a valid directory."), @@ -121,13 +121,13 @@ void Preferences::_load() g_free(msg); return; } - + // The prefs file was just created. // We can return now and skip the rest of the load process. _writable = true; return; } - + // Yes, the pref file exists. // 2. Is it a regular file? if (!g_file_test(_prefs_filename.data(), G_FILE_TEST_IS_REGULAR)) { @@ -139,7 +139,7 @@ void Preferences::_load() g_free(msg); return; } - + // 3. Is the file readable? gchar *prefs_xml = NULL; gsize len = 0; if (!g_file_get_contents(_prefs_filename.data(), &prefs_xml, &len, NULL)) { @@ -174,7 +174,7 @@ void Preferences::_load() Inkscape::GC::release(prefs_read); return; } - + // Merge the loaded prefs with defaults. _prefs_doc->root()->mergeFrom(prefs_read->root(), "id"); Inkscape::GC::release(prefs_read); @@ -187,7 +187,7 @@ void Preferences::_load() void Preferences::save() { if (!_writable) return; // no-op if the prefs file is not writable - + // sp_repr_save_file uses utf-8 instead of the glib filename encoding. // I don't know why filenames are kept in utf-8 in Inkscape and then // converted to filename encoding when necessary through sepcial functions @@ -285,7 +285,7 @@ bool Preferences::getBool(Glib::ustring const &pref_key, Glib::ustring const &at gchar const *rawstr = node->attribute(attr.data()); if(!rawstr || !rawstr[0]) return def; Glib::ustring str = rawstr; - + // This is to handle legacy preferences using ints as booleans if (str == "true" || str == "1") return true; return false; @@ -431,11 +431,11 @@ Inkscape::XML::Node *Preferences::_getNode(Glib::ustring const &pref_key, bool c Inkscape::XML::Node *node = _prefs_doc->root(), *child = NULL; gchar **splits = g_strsplit(pref_key.data(), ".", 0); int part_i = 0; - + while(splits[part_i]) { for (child = node->firstChild(); child; child = child->next()) if (!strcmp(splits[part_i], child->attribute("id"))) break; - + // If the previous loop found a matching key, child now contains the node // matching the processed key part. If no node was found then it is NULL. if (!child) { @@ -445,7 +445,7 @@ Inkscape::XML::Node *Preferences::_getNode(Glib::ustring const &pref_key, bool c child = node->document()->createElement("group"); child->setAttribute("id", splits[part_i]); node->appendChild(child); - + ++part_i; node = child; } @@ -455,7 +455,7 @@ Inkscape::XML::Node *Preferences::_getNode(Glib::ustring const &pref_key, bool c return NULL; } } - + ++part_i; node = child; } @@ -482,7 +482,7 @@ Preferences *Preferences::_instance = NULL; } // namespace Inkscape - + /* Local Variables: mode:c++ diff --git a/src/removeoverlap/removeoverlap.cpp b/src/removeoverlap/removeoverlap.cpp index c2cd6d213..60bb0e4f9 100644 --- a/src/removeoverlap/removeoverlap.cpp +++ b/src/removeoverlap/removeoverlap.cpp @@ -21,11 +21,11 @@ using vpsc::Rectangle; namespace { struct Record { SPItem *item; - NR::Point midpoint; + Geom::Point midpoint; Rectangle *vspc_rect; Record() {} - Record(SPItem *i, NR::Point m, Rectangle *r) + Record(SPItem *i, Geom::Point m, Rectangle *r) : item(i), midpoint(m), vspc_rect(r) {} }; } @@ -42,16 +42,16 @@ void removeoverlap(GSList const *const items, double const xGap, double const yG std::vector<Record> records; std::vector<Rectangle *> rs; - NR::Point const gap(xGap, yGap); + Geom::Point const gap(xGap, yGap); for (std::list<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it) { - using NR::X; using NR::Y; - boost::optional<NR::Rect> item_box(sp_item_bbox_desktop(*it)); + using Geom::X; using Geom::Y; + boost::optional<Geom::Rect> item_box(sp_item_bbox_desktop(*it)); if (item_box) { - NR::Point min(item_box->min() - .5*gap); - NR::Point max(item_box->max() + .5*gap); + Geom::Point min(item_box->min() - .5*gap); + Geom::Point max(item_box->max() + .5*gap); Rectangle *vspc_rect = new Rectangle(min[X], max[X], min[Y], max[Y]); records.push_back(Record(*it, item_box->midpoint(), vspc_rect)); rs.push_back(vspc_rect); @@ -64,8 +64,8 @@ void removeoverlap(GSList const *const items, double const xGap, double const yG it != records.end(); ++it ) { - NR::Point const curr = it->midpoint; - NR::Point const dest(it->vspc_rect->getCentreX(), + Geom::Point const curr = it->midpoint; + Geom::Point const dest(it->vspc_rect->getCentreX(), it->vspc_rect->getCentreY()); sp_item_move_rel(it->item, Geom::Translate(dest - curr)); delete it->vspc_rect; diff --git a/src/satisfied-guide-cns.cpp b/src/satisfied-guide-cns.cpp index 640ffa79f..3ffebeb06 100644 --- a/src/satisfied-guide-cns.cpp +++ b/src/satisfied-guide-cns.cpp @@ -6,7 +6,7 @@ #include <approx-equal.h> void satisfied_guide_cns(SPDesktop const &desktop, - std::vector<NR::Point> const &snappoints, + std::vector<Geom::Point> const &snappoints, std::vector<SPGuideConstraint> &cns) { SPNamedView const &nv = *sp_desktop_namedview(&desktop); diff --git a/src/satisfied-guide-cns.h b/src/satisfied-guide-cns.h index eeadf48cd..1952bef44 100644 --- a/src/satisfied-guide-cns.h +++ b/src/satisfied-guide-cns.h @@ -2,12 +2,12 @@ #define __SATISFIED_GUIDE_CNS_H__ #include <forward.h> -#include <libnr/nr-forward.h> +#include <2geom/forward.h> #include <vector> class SPGuideConstraint; void satisfied_guide_cns(SPDesktop const &desktop, - std::vector<NR::Point> const &snappoints, + std::vector<Geom::Point> const &snappoints, std::vector<SPGuideConstraint> &cns); diff --git a/src/selcue.cpp b/src/selcue.cpp index 418db8e74..661f0a2e4 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -84,7 +84,7 @@ void Inkscape::SelCue::_updateItemBboxes() for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) { SPItem *item = (SPItem *) l->data; - boost::optional<Geom::Rect> const b = to_2geom(sp_item_bbox_desktop(item, bbox_type)); + boost::optional<Geom::Rect> const b = sp_item_bbox_desktop(item, bbox_type); SPCanvasItem* box = NULL; diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 591cc795d..d58f7ff25 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -50,10 +50,7 @@ #include "libnr/nr-matrix-translate-ops.h" #include "libnr/nr-scale-ops.h" #include <libnr/nr-matrix-ops.h> -#include <libnr/nr-rotate-ops.h> -#include "libnr/nr-scale-translate-ops.h" -#include "libnr/nr-translate-matrix-ops.h" -#include "libnr/nr-translate-scale-ops.h" +#include <2geom/transforms.h> #include "xml/repr.h" #include "style.h" #include "document-private.h" @@ -617,14 +614,14 @@ sp_item_list_common_parent_group(GSList const *items) } /** Finds out the minimum common bbox of the selected items. */ -static boost::optional<NR::Rect> +static boost::optional<Geom::Rect> enclose_items(GSList const *items) { g_assert(items != NULL); - boost::optional<NR::Rect> r; + boost::optional<Geom::Rect> r; for (GSList const *i = items; i; i = i->next) { - r = NR::union_bounds(r, sp_item_bbox_desktop((SPItem *) i->data)); + r = Geom::unify(r, sp_item_bbox_desktop((SPItem *) i->data)); } return r; } @@ -670,7 +667,7 @@ sp_selection_raise(SPDesktop *desktop) rev = g_slist_sort(rev, (GCompareFunc) sp_item_repr_compare_position); // Determine the common bbox of the selected items. - boost::optional<NR::Rect> selected = enclose_items(items); + boost::optional<Geom::Rect> selected = enclose_items(items); // Iterate over all objects in the selection (starting from top). if (selected) { @@ -680,7 +677,7 @@ sp_selection_raise(SPDesktop *desktop) for (SPObject *newref = child->next; newref; newref = newref->next) { // if the sibling is an item AND overlaps our selection, if (SP_IS_ITEM(newref)) { - boost::optional<NR::Rect> newref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); + boost::optional<Geom::Rect> newref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); if ( newref_bbox && selected->intersects(*newref_bbox) ) { // AND if it's not one of our selected objects, if (!g_slist_find((GSList *) items, newref)) { @@ -760,7 +757,7 @@ sp_selection_lower(SPDesktop *desktop) Inkscape::XML::Node *grepr = SP_OBJECT_REPR(group); // Determine the common bbox of the selected items. - boost::optional<NR::Rect> selected = enclose_items(items); + boost::optional<Geom::Rect> selected = enclose_items(items); /* Construct direct-ordered list of selected children. */ GSList *rev = g_slist_copy((GSList *) items); @@ -775,7 +772,7 @@ sp_selection_lower(SPDesktop *desktop) for (SPObject *newref = prev_sibling(child); newref; newref = prev_sibling(newref)) { // if the sibling is an item AND overlaps our selection, if (SP_IS_ITEM(newref)) { - boost::optional<NR::Rect> ref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); + boost::optional<Geom::Rect> ref_bbox = sp_item_bbox_desktop(SP_ITEM(newref)); if ( ref_bbox && selected->intersects(*ref_bbox) ) { // AND if it's not one of our selected objects, if (!g_slist_find((GSList *) items, newref)) { @@ -1221,7 +1218,6 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons // calculate the matrix we need to apply to the clone to cancel its induced transform from its original Geom::Matrix parent_transform = sp_item_i2root_affine(SP_ITEM(SP_OBJECT_PARENT (item))); Geom::Matrix t = parent_transform * matrix_to_desktop (matrix_from_desktop (affine, item), item) * parent_transform.inverse(); - NR::Matrix t_nr = from_2geom(t); Geom::Matrix t_inv =parent_transform * matrix_to_desktop (matrix_from_desktop (affine.inverse(), item), item) * parent_transform.inverse(); Geom::Matrix result = t_inv * item->transform * t; @@ -1234,19 +1230,18 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons if (prefs_parallel) { Geom::Matrix move = result * clone_move * t_inv; - NR::Matrix move_nr = from_2geom(move); - sp_item_write_transform(item, SP_OBJECT_REPR(item), from_2geom(move), &move_nr); + sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move); } else if (prefs_unmoved) { //if (SP_IS_USE(sp_use_get_original(SP_USE(item)))) // clone_move = NR::identity(); Geom::Matrix move = result * clone_move; - sp_item_write_transform(item, SP_OBJECT_REPR(item), from_2geom(move), &t_nr); + sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &t); } } else { // just apply the result - sp_item_write_transform(item, SP_OBJECT_REPR(item), result, &t_nr); + sp_item_write_transform(item, SP_OBJECT_REPR(item), result, &t); } } else { @@ -1290,17 +1285,17 @@ sp_selection_scale_absolute(Inkscape::Selection *selection, if (selection->isEmpty()) return; - boost::optional<NR::Rect> const bbox(selection->bounds()); + boost::optional<Geom::Rect> const bbox(selection->bounds()); if ( !bbox || bbox->isEmpty() ) { return; } - NR::translate const p2o(-bbox->min()); + Geom::Translate const p2o(-bbox->min()); - NR::scale const newSize(x1 - x0, + Geom::Scale const newSize(x1 - x0, y1 - y0); - NR::scale const scale( newSize / NR::scale(bbox->dimensions()) ); - NR::translate const o2n(x0, y0); + Geom::Scale const scale( newSize * Geom::Scale(bbox->dimensions()).inverse() ); + Geom::Translate const o2n(x0, y0); NR::Matrix const final( p2o * scale * o2n ); sp_selection_apply_affine(selection, final); @@ -1312,15 +1307,15 @@ void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point con if (selection->isEmpty()) return; - boost::optional<NR::Rect> const bbox(selection->bounds()); + boost::optional<Geom::Rect> const bbox(selection->bounds()); if ( !bbox || bbox->isEmpty() ) { return; } // FIXME: ARBITRARY LIMIT: don't try to scale above 1 Mpx, it won't display properly and will crash sooner or later anyway - if ( bbox->extent(NR::X) * scale[Geom::X] > 1e6 || - bbox->extent(NR::Y) * scale[Geom::Y] > 1e6 ) + if ( bbox->dimensions()[NR::X] * scale[Geom::X] > 1e6 || + bbox->dimensions()[NR::Y] * scale[Geom::Y] > 1e6 ) { return; } @@ -1355,12 +1350,12 @@ sp_selection_skew_relative(Inkscape::Selection *selection, Geom::Point const &al void sp_selection_move_relative(Inkscape::Selection *selection, Geom::Point const &move) { - sp_selection_apply_affine(selection, NR::Matrix(NR::translate(move))); + sp_selection_apply_affine(selection, NR::Matrix(Geom::Translate(move))); } void sp_selection_move_relative(Inkscape::Selection *selection, double dx, double dy) { - sp_selection_apply_affine(selection, NR::Matrix(NR::translate(dx, dy))); + sp_selection_apply_affine(selection, NR::Matrix(Geom::Translate(dx, dy))); } /** @@ -1406,6 +1401,21 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) _("Rotate")); } +// helper function: +static +Geom::Point +cornerFarthestFrom(Geom::Rect const &r, Geom::Point const &p){ + Geom::Point m = r.midpoint(); + unsigned i = 0; + if (p[X] < m[X]) { + i = 1; + } + if (p[Y] < m[Y]) { + i = 3 - i; + } + return r.corner(i); +} + /** \param angle the angle in "angular pixels", i.e. how many visible pixels must move the outermost point of the rotated object */ @@ -1415,7 +1425,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) if (selection->isEmpty()) return; - boost::optional<NR::Rect> const bbox(selection->bounds()); + boost::optional<Geom::Rect> const bbox(selection->bounds()); boost::optional<Geom::Point> center = selection->center(); if ( !bbox || !center ) { @@ -1424,7 +1434,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) gdouble const zoom = selection->desktop()->current_zoom(); gdouble const zmove = angle / zoom; - gdouble const r = NR::L2(bbox->cornerFarthestFrom(*center) - *center); + gdouble const r = Geom::L2(cornerFarthestFrom(*bbox, *center) - *center); gdouble const zangle = 180 * atan2(zmove, r) / M_PI; @@ -1444,12 +1454,12 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) if (selection->isEmpty()) return; - boost::optional<NR::Rect> const bbox(selection->bounds()); + boost::optional<Geom::Rect> const bbox(selection->bounds()); if (!bbox) { return; } - NR::Point const center(bbox->midpoint()); + Geom::Point const center(bbox->midpoint()); // you can't scale "do nizhe pola" (below zero) double const max_len = bbox->maxExtent(); @@ -1481,13 +1491,13 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) if (selection->isEmpty()) return; - boost::optional<NR::Rect> sel_bbox = selection->bounds(); + boost::optional<Geom::Rect> sel_bbox = selection->bounds(); if (!sel_bbox) { return; } - NR::Point const center(sel_bbox->midpoint()); + Geom::Point const center(sel_bbox->midpoint()); sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_CONTEXT_SELECT, _("Scale by whole factor")); @@ -1805,7 +1815,7 @@ SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, void scroll_to_show_item(SPDesktop *desktop, SPItem *item) { Geom::Rect dbox = desktop->get_display_area(); - boost::optional<Geom::Rect> sbox = to_2geom(sp_item_bbox_desktop(item)); + boost::optional<Geom::Rect> sbox = sp_item_bbox_desktop(item); if ( sbox && dbox.contains(*sbox) == false ) { Geom::Point const s_dt = sbox->midpoint(); @@ -2036,8 +2046,8 @@ sp_select_clone_original(SPDesktop *desktop) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool highlight = prefs->getBool("options.highlightoriginal", "value"); if (highlight) { - boost::optional<NR::Rect> a = item->getBounds(sp_item_i2d_affine(item)); - boost::optional<NR::Rect> b = original->getBounds(sp_item_i2d_affine(original)); + boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2d_affine(item)); + boost::optional<Geom::Rect> b = original->getBounds(sp_item_i2d_affine(original)); if ( a && b ) { // draw a flashing line between the objects SPCurve *curve = new SPCurve(); @@ -2078,7 +2088,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) } sp_document_ensure_up_to_date(doc); - boost::optional<NR::Rect> r = selection->bounds(); + boost::optional<Geom::Rect> r = selection->bounds(); boost::optional<Geom::Point> c = selection->center(); if ( !r || !c || r->isEmpty() ) { return; @@ -2202,15 +2212,15 @@ sp_selection_tile(SPDesktop *desktop, bool apply) } sp_document_ensure_up_to_date(doc); - boost::optional<NR::Rect> r = selection->bounds(); + boost::optional<Geom::Rect> r = selection->bounds(); if ( !r || r->isEmpty() ) { return; } // calculate the transform to be applied to objects to move them to 0,0 - NR::Point move_p = NR::Point(0, sp_document_height(doc)) - (r->min() + NR::Point (0, r->extent(NR::Y))); - move_p[NR::Y] = -move_p[NR::Y]; - NR::Matrix move = NR::Matrix (NR::translate (move_p)); + Geom::Point move_p = Geom::Point(0, sp_document_height(doc)) - (r->min() + Geom::Point (0, r->dimensions()[NR::Y])); + move_p[Geom::Y] = -move_p[Geom::Y]; + NR::Matrix move = NR::Matrix (Geom::Translate (move_p)); GSList *items = g_slist_copy((GSList *) selection->itemList()); @@ -2251,7 +2261,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) prefs->setInt("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); gchar const *pat_id = pattern_tile(repr_copies, bounds, doc, - ( NR::Matrix(NR::translate(desktop->dt2doc(NR::Point(r->min()[NR::X], + ( NR::Matrix(Geom::Translate(desktop->dt2doc(NR::Point(r->min()[NR::X], r->max()[NR::Y])))) * parent_transform.inverse() ), parent_transform * move); @@ -2545,8 +2555,8 @@ sp_selection_create_bitmap_copy (SPDesktop *desktop) } // Calculate the matrix that will be applied to the image so that it exactly overlaps the source objects - NR::Matrix eek (sp_item_i2d_affine (SP_ITEM(parent_object))); - NR::Matrix t; + Geom::Matrix eek (sp_item_i2d_affine (SP_ITEM(parent_object))); + Geom::Matrix t; double shift_x = bbox.x0; double shift_y = bbox.y1; @@ -2554,7 +2564,7 @@ sp_selection_create_bitmap_copy (SPDesktop *desktop) shift_x = round (shift_x); shift_y = -round (-shift_y); // this gets correct rounding despite coordinate inversion, remove the negations when the inversion is gone } - t = NR::scale(1, -1) * NR::translate (shift_x, shift_y) * eek.inverse(); + t = Geom::Scale(1, -1) * Geom::Translate (shift_x, shift_y) * eek.inverse(); // Do the export sp_export_png_file(document, filepath, @@ -2861,7 +2871,7 @@ fit_canvas_to_selection(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to fit canvas to.")); return false; } - boost::optional<Geom::Rect> const bbox(to_2geom(desktop->selection->bounds())); + boost::optional<Geom::Rect> const bbox(desktop->selection->bounds()); if (bbox && !bbox->isEmpty()) { doc->fitToRect(*bbox); return true; @@ -2889,7 +2899,7 @@ fit_canvas_to_drawing(SPDocument *doc) sp_document_ensure_up_to_date(doc); SPItem const *const root = SP_ITEM(doc->root); - boost::optional<Geom::Rect> const bbox(to_2geom(root->getBounds(sp_item_i2r_affine(root)))); + boost::optional<Geom::Rect> const bbox(root->getBounds(sp_item_i2r_affine(root))); if (bbox && !bbox->isEmpty()) { doc->fitToRect(*bbox); return true; diff --git a/src/selection.cpp b/src/selection.cpp index 9b9b48485..bd695ff8b 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -24,6 +24,7 @@ #include "desktop-handles.h" #include "document.h" #include "selection.h" +#include "helper/recthull.h" #include "xml/repr.h" #include "sp-shape.h" @@ -378,46 +379,21 @@ Inkscape::XML::Node *Selection::singleRepr() { NRRect *Selection::bounds(NRRect *bbox, SPItem::BBoxType type) const { g_return_val_if_fail (bbox != NULL, NULL); - *bbox = NRRect(bounds(type)); + bounds(bbox, type); return bbox; } -boost::optional<NR::Rect> Selection::bounds(SPItem::BBoxType type) const +boost::optional<Geom::Rect> Selection::bounds(SPItem::BBoxType type) const { GSList const *items = const_cast<Selection *>(this)->itemList(); - boost::optional<NR::Rect> bbox; + boost::optional<Geom::Rect> bbox; for ( GSList const *i = items ; i != NULL ; i = i->next ) { - bbox = NR::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data), type)); + bbox = unify(bbox, sp_item_bbox_desktop(SP_ITEM(i->data), type)); } return bbox; } -// TODO: This should be replaces by a proper 2geom function -inline Geom::Rect union_bounds_2geom(boost::optional<Geom::Rect> const & a, Geom::Rect const &b) { - if (a) { - return union_bounds_2geom(*a, b); - } else { - return b; - } -} - -boost::optional<Geom::Rect> Selection::bounds_2geom(SPItem::BBoxType type) const -{ - GSList const *items = const_cast<Selection *>(this)->itemList(); - - boost::optional<NR::Rect> bbox; - for ( GSList const *i = items ; i != NULL ; i = i->next ) { - bbox = union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data), type)); - } - // TODO: eliminate this conversion after the switch to 2geom - boost::optional<Geom::Rect> bbox_ret; - if (bbox) { - bbox_ret = to_2geom(*bbox); - } - return bbox_ret; -} - NRRect *Selection::boundsInDocument(NRRect *bbox, SPItem::BBoxType type) const { g_return_val_if_fail (bbox != NULL, NULL); @@ -439,9 +415,9 @@ NRRect *Selection::boundsInDocument(NRRect *bbox, SPItem::BBoxType type) const { return bbox; } -boost::optional<NR::Rect> Selection::boundsInDocument(SPItem::BBoxType type) const { +boost::optional<Geom::Rect> Selection::boundsInDocument(SPItem::BBoxType type) const { NRRect r; - return boundsInDocument(&r, type)->upgrade(); + return to_2geom(boundsInDocument(&r, type)->upgrade()); } /** Extract the position of the center from the first selected object */ @@ -454,9 +430,9 @@ boost::optional<Geom::Point> Selection::center() const { return first->getCenter(); } } - boost::optional<NR::Rect> bbox = bounds(); + boost::optional<Geom::Rect> bbox = bounds(); if (bbox) { - return to_2geom(bounds()->midpoint()); + return bounds()->midpoint(); } else { return boost::optional<Geom::Point>(); } @@ -465,9 +441,9 @@ boost::optional<Geom::Point> Selection::center() const { /** * Compute the list of points in the selection that are to be considered for snapping. */ -std::vector<NR::Point> Selection::getSnapPoints(bool includeItemCenter) const { +std::vector<Geom::Point> Selection::getSnapPoints(bool includeItemCenter) const { GSList const *items = const_cast<Selection *>(this)->itemList(); - std::vector<NR::Point> p; + std::vector<Geom::Point> p; for (GSList const *iter = items; iter != NULL; iter = iter->next) { SPItem *this_item = SP_ITEM(iter->data); sp_item_snappoints(this_item, false, SnapPointsIter(p)); @@ -481,24 +457,24 @@ std::vector<NR::Point> Selection::getSnapPoints(bool includeItemCenter) const { return p; } -std::vector<NR::Point> Selection::getSnapPointsConvexHull() const { +std::vector<Geom::Point> Selection::getSnapPointsConvexHull() const { GSList const *items = const_cast<Selection *>(this)->itemList(); - std::vector<NR::Point> p; + std::vector<Geom::Point> p; for (GSList const *iter = items; iter != NULL; iter = iter->next) { sp_item_snappoints(SP_ITEM(iter->data), false, SnapPointsIter(p)); } - std::vector<NR::Point> pHull; + std::vector<Geom::Point> pHull; if (!p.empty()) { - std::vector<NR::Point>::iterator i; - NR::ConvexHull cvh(p.front()); + std::vector<Geom::Point>::iterator i; + Geom::RectHull cvh(p.front()); for (i = p.begin(); i != p.end(); i++) { // these are the points we get back cvh.add(*i); } - boost::optional<NR::Rect> rHull = cvh.bounds(); + boost::optional<Geom::Rect> rHull = cvh.bounds(); if (rHull) { for ( unsigned i = 0 ; i < 4 ; ++i ) { pHull.push_back(rHull->corner(i)); diff --git a/src/selection.h b/src/selection.h index 2e7bddf81..6ae462fc3 100644 --- a/src/selection.h +++ b/src/selection.h @@ -243,8 +243,7 @@ public: /** @brief Returns the bounding rectangle of the selection */ NRRect *bounds(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; /** @brief Returns the bounding rectangle of the selection */ - boost::optional<NR::Rect> bounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; - boost::optional<Geom::Rect> bounds_2geom(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; + boost::optional<Geom::Rect> bounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; /** * @brief Returns the bounding rectangle of the selection @@ -258,7 +257,7 @@ public: * * \todo how is this different from bounds()? */ - boost::optional<NR::Rect> boundsInDocument(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; + boost::optional<Geom::Rect> boundsInDocument(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const; /** * @brief Returns the rotation/skew center of the selection @@ -269,13 +268,13 @@ public: * @brief Gets the selection's snap points. * @return Selection's snap points */ - std::vector<NR::Point> getSnapPoints(bool includeItemCenter) const; + std::vector<Geom::Point> getSnapPoints(bool includeItemCenter) const; /** * @brief Gets the snap points of a selection that form a convex hull. * @return Selection's convex hull points */ - std::vector<NR::Point> getSnapPointsConvexHull() const; + std::vector<Geom::Point> getSnapPointsConvexHull() const; /** * @brief Connects a slot to be notified of selection changes diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h index 0afa552ea..4a0dd0bf7 100644 --- a/src/seltrans-handles.h +++ b/src/seltrans-handles.h @@ -13,6 +13,7 @@ */ #include "display/sodipodi-ctrl.h" +#include <2geom/forward.h> namespace Inkscape { @@ -23,29 +24,29 @@ class SPSelTransHandle; // request handlers gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, NR::Point &p, guint state); + SPSelTransHandle const &handle, Geom::Point &p, guint state); gboolean sp_sel_trans_stretch_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, NR::Point &p, guint state); + SPSelTransHandle const &handle, Geom::Point &p, guint state); gboolean sp_sel_trans_skew_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, NR::Point &p, guint state); + SPSelTransHandle const &handle, Geom::Point &p, guint state); gboolean sp_sel_trans_rotate_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, NR::Point &p, guint state); + SPSelTransHandle const &handle, Geom::Point &p, guint state); gboolean sp_sel_trans_center_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, NR::Point &p, guint state); + SPSelTransHandle const &handle, Geom::Point &p, guint state); // action handlers -void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); -void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); -void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); -void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); -void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); +void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); +void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); +void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); +void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); +void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); struct SPSelTransHandle { GtkAnchorType anchor; GdkCursorType cursor; guint control; - void (* action) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); - gboolean (* request) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); + void (* action) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); + gboolean (* request) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &p, guint state); gdouble x, y; }; diff --git a/src/seltrans.cpp b/src/seltrans.cpp index f5572796d..6ae7948f1 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -21,12 +21,7 @@ #include <cstring> #include <string> -#include <libnr/nr-matrix-ops.h> -#include <libnr/nr-matrix-translate-ops.h> -#include <libnr/nr-rotate-ops.h> -#include <libnr/nr-scale-ops.h> -#include <libnr/nr-translate-matrix-ops.h> -#include <libnr/nr-translate-ops.h> +#include <2geom/transforms.h> #include <gdk/gdkkeysyms.h> #include "document.h" #include "sp-namedview.h" @@ -49,7 +44,7 @@ #include "prefs-utils.h" #include "xml/repr.h" #include "mod360.h" -#include "2geom/angle.h" +#include <2geom/angle.h> #include "display/snap-indicator.h" @@ -58,8 +53,8 @@ static void sp_remove_handles(SPKnot *knot[], gint num); static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, gpointer data); static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint state, gpointer data); static void sp_sel_trans_handle_click(SPKnot *knot, guint state, gpointer data); -static void sp_sel_trans_handle_new_event(SPKnot *knot, NR::Point *position, guint32 state, gpointer data); -static gboolean sp_sel_trans_handle_request(SPKnot *knot, NR::Point *p, guint state, gboolean *data); +static void sp_sel_trans_handle_new_event(SPKnot *knot, Geom::Point *position, guint32 state, gpointer data); +static gboolean sp_sel_trans_handle_request(SPKnot *knot, Geom::Point *p, guint state, gboolean *data); extern GdkPixbuf *handles[]; @@ -96,12 +91,12 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : _show_handles(true), _bbox(), _approximate_bbox(), - _absolute_affine(NR::scale(1,1)), - _opposite(NR::Point(0,0)), - _opposite_for_specpoints(NR::Point(0,0)), - _opposite_for_bboxpoints(NR::Point(0,0)), - _origin_for_specpoints(NR::Point(0,0)), - _origin_for_bboxpoints(NR::Point(0,0)), + _absolute_affine(Geom::Scale(1,1)), + _opposite(Geom::Point(0,0)), + _opposite_for_specpoints(Geom::Point(0,0)), + _opposite_for_bboxpoints(Geom::Point(0,0)), + _origin_for_specpoints(Geom::Point(0,0)), + _origin_for_bboxpoints(Geom::Point(0,0)), _chandle(NULL), _stamp_cache(NULL), _message_context(desktop->messageStack()) @@ -118,7 +113,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : } _updateVolatileState(); - _current_relative_affine.set_identity(); + _current_relative_affine.setIdentity(); _center_is_set = false; // reread _center from items, or set to bbox midpoint @@ -232,7 +227,7 @@ void Inkscape::SelTrans::increaseState() _updateHandles(); } -void Inkscape::SelTrans::setCenter(NR::Point const &p) +void Inkscape::SelTrans::setCenter(Geom::Point const &p) { _center = p; _center_is_set = true; @@ -247,7 +242,7 @@ void Inkscape::SelTrans::setCenter(NR::Point const &p) _updateHandles(); } -void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool show_handles) +void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool show_handles) { Inkscape::Selection *selection = sp_desktop_selection(_desktop); @@ -256,7 +251,7 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho _grabbed = true; _show_handles = show_handles; _updateVolatileState(); - _current_relative_affine.set_identity(); + _current_relative_affine.setIdentity(); _changed = false; @@ -284,7 +279,7 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho _geometric_bbox = selection->bounds(SPItem::GEOMETRIC_BBOX); _point = p; if (_geometric_bbox) { - _point_geom = _geometric_bbox->min() + _geometric_bbox->dimensions() * NR::scale(x, y); + _point_geom = _geometric_bbox->min() + _geometric_bbox->dimensions() * Geom::Scale(x, y); } else { _point_geom = p; } @@ -292,9 +287,8 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho // Next, get all points to consider for snapping SnapManager const &m = _desktop->namedview->snap_manager; _snap_points.clear(); - to_2geom(selection->getSnapPoints(m.getIncludeItemCenter()), _snap_points); - std::vector<Geom::Point> snap_points_hull; - to_2geom(selection->getSnapPointsConvexHull(), snap_points_hull); + _snap_points = selection->getSnapPoints(m.getIncludeItemCenter()); + std::vector<Geom::Point> snap_points_hull = selection->getSnapPointsConvexHull(); if (_snap_points.size() > 100) { /* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes An average user would rarely ever try to snap such a large number of nodes anyway, because @@ -306,10 +300,10 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho // Find bbox hulling all special points, which excludes stroke width. Here we need to include the // path nodes, for example because a rectangle which has been converted to a path doesn't have // any other special points - NR::Rect snap_points_bbox; + Geom::Rect snap_points_bbox; if ( snap_points_hull.empty() == false ) { std::vector<Geom::Point>::iterator i = snap_points_hull.begin(); - snap_points_bbox = NR::Rect(*i, *i); + snap_points_bbox = Geom::Rect(*i, *i); i++; while (i != snap_points_hull.end()) { snap_points_bbox.expandTo(*i); @@ -321,7 +315,7 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho if (_bbox) { // ... and add the bbox corners to _bbox_points for ( unsigned i = 0 ; i < 4 ; i++ ) { - _bbox_points.push_back(to_2geom(_bbox->corner(i))); + _bbox_points.push_back(_bbox->corner(i)); } // There are two separate "opposites" (i.e. opposite w.r.t. the handle being dragged): // - one for snapping the boundingbox, which can be either visual or geometric @@ -329,21 +323,21 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho // The "opposite" in case of a geometric boundingbox always coincides with the "opposite" for the special points // These distinct "opposites" are needed in the snapmanager to avoid bugs such as #sf1540195 (in which // a box is caught between two guides) - _opposite_for_bboxpoints = _bbox->min() + _bbox->dimensions() * NR::scale(1-x, 1-y); - _opposite_for_specpoints = snap_points_bbox.min() + snap_points_bbox.dimensions() * NR::scale(1-x, 1-y); + _opposite_for_bboxpoints = _bbox->min() + _bbox->dimensions() * Geom::Scale(1-x, 1-y); + _opposite_for_specpoints = snap_points_bbox.min() + snap_points_bbox.dimensions() * Geom::Scale(1-x, 1-y); _opposite = _opposite_for_bboxpoints; } // The lines below are usefull for debugging any snapping issues, as they'll spit out all points that are considered for snapping /*std::cout << "Number of snap points: " << _snap_points.size() << std::endl; - for (std::vector<NR::Point>::const_iterator i = _snap_points.begin(); i != _snap_points.end(); i++) + for (std::vector<Geom::Point>::const_iterator i = _snap_points.begin(); i != _snap_points.end(); i++) { std::cout << " " << *i << std::endl; } std::cout << "Number of bbox points: " << _bbox_points.size() << std::endl; - for (std::vector<NR::Point>::const_iterator i = _bbox_points.begin(); i != _bbox_points.end(); i++) + for (std::vector<Geom::Point>::const_iterator i = _bbox_points.begin(); i != _bbox_points.end(); i++) { std::cout << " " << *i << std::endl; }*/ @@ -362,23 +356,23 @@ void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool sho g_return_if_fail(_stamp_cache == NULL); } -void Inkscape::SelTrans::transform(NR::Matrix const &rel_affine, NR::Point const &norm) +void Inkscape::SelTrans::transform(Geom::Matrix const &rel_affine, Geom::Point const &norm) { g_return_if_fail(_grabbed); g_return_if_fail(!_empty); - NR::Matrix const affine( NR::translate(-norm) * rel_affine * NR::translate(norm) ); + Geom::Matrix const affine( Geom::Translate(-norm) * rel_affine * Geom::Translate(norm) ); if (_show == SHOW_CONTENT) { // update the content for (unsigned i = 0; i < _items.size(); i++) { SPItem &item = *_items[i]; - NR::Matrix const &prev_transform = _items_affines[i]; + Geom::Matrix const &prev_transform = _items_affines[i]; sp_item_set_i2d_affine(&item, prev_transform * affine); } } else { if (_bbox) { - NR::Point p[4]; + Geom::Point p[4]; /* update the outline */ for (unsigned i = 0 ; i < 4 ; i++) { p[i] = _bbox->corner(i) * affine; @@ -432,7 +426,7 @@ void Inkscape::SelTrans::ungrab() // If dragging showed content live, sp_selection_apply_affine cannot change the centers // appropriately - it does not know the original positions of the centers (all objects already have // the new bboxes). So we need to reset the centers from our saved array. - if (_show != SHOW_OUTLINE && !_current_relative_affine.is_translation()) { + if (_show != SHOW_OUTLINE && !_current_relative_affine.isTranslation()) { for (unsigned i = 0; i < _items_centers.size(); i++) { SPItem *currentItem = _items[i]; if (currentItem->isCenterSet()) { // only if it's already set @@ -447,13 +441,13 @@ void Inkscape::SelTrans::ungrab() _items_affines.clear(); _items_centers.clear(); - if (_current_relative_affine.is_translation()) { + if (_current_relative_affine.isTranslation()) { sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, _("Move")); - } else if (_current_relative_affine.is_scale()) { + } else if (_current_relative_affine.isScale()) { sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, _("Scale")); - } else if (_current_relative_affine.is_rotation()) { + } else if (_current_relative_affine.isRotation()) { sp_document_done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, _("Rotate")); } else { @@ -527,8 +521,8 @@ void Inkscape::SelTrans::stamp() Geom::Matrix const *new_affine; if (_show == SHOW_OUTLINE) { - NR::Matrix const i2d(sp_item_i2d_affine(original_item)); - NR::Matrix const i2dnew( i2d * _current_relative_affine ); + Geom::Matrix const i2d(sp_item_i2d_affine(original_item)); + Geom::Matrix const i2dnew( i2d * _current_relative_affine ); sp_item_set_i2d_affine(copy_item, i2dnew); new_affine = ©_item->transform; } else { @@ -676,12 +670,12 @@ void Inkscape::SelTrans::_showHandles(SPKnot *knot[], SPSelTransHandle const han } sp_knot_show(knot[i]); - NR::Point const handle_pt(handle[i].x, handle[i].y); + Geom::Point const handle_pt(handle[i].x, handle[i].y); // shouldn't have nullary bbox, but knots g_assert(_bbox); - NR::Point p( _bbox->min() + Geom::Point p( _bbox->min() + ( _bbox->dimensions() - * NR::scale(handle_pt) ) ); + * Geom::Scale(handle_pt) ) ); sp_knot_moveto(knot[i], p); } @@ -699,14 +693,14 @@ static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint /*state*/, gpointer / SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->ungrab(); } -static void sp_sel_trans_handle_new_event(SPKnot *knot, NR::Point *position, guint state, gpointer data) +static void sp_sel_trans_handle_new_event(SPKnot *knot, Geom::Point *position, guint state, gpointer data) { SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleNewEvent( knot, position, state, *(SPSelTransHandle const *) data ); } -static gboolean sp_sel_trans_handle_request(SPKnot *knot, NR::Point *position, guint state, gboolean *data) +static gboolean sp_sel_trans_handle_request(SPKnot *knot, Geom::Point *position, guint state, gboolean *data) { return SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleRequest( knot, position, state, *(SPSelTransHandle const *) data @@ -767,7 +761,7 @@ void Inkscape::SelTrans::handleGrab(SPKnot *knot, guint /*state*/, SPSelTransHan } -void Inkscape::SelTrans::handleNewEvent(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle) +void Inkscape::SelTrans::handleNewEvent(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle) { if (!SP_KNOT_IS_GRABBED(knot)) { return; @@ -785,7 +779,7 @@ void Inkscape::SelTrans::handleNewEvent(SPKnot *knot, NR::Point *position, guint } -gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle) +gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle) { if (!SP_KNOT_IS_GRABBED(knot)) { return TRUE; @@ -828,7 +822,7 @@ void Inkscape::SelTrans::_selChanged(Inkscape::Selection */*selection*/) //SPItem::APPROXIMATE_BBOX will be replaced by SPItem::VISUAL_BBOX, as soon as the latter is implemented properly _updateVolatileState(); - _current_relative_affine.set_identity(); + _current_relative_affine.setIdentity(); _center_is_set = false; // center(s) may have changed _updateHandles(); } @@ -838,7 +832,7 @@ void Inkscape::SelTrans::_selModified(Inkscape::Selection */*selection*/, guint { if (!_grabbed) { _updateVolatileState(); - _current_relative_affine.set_identity(); + _current_relative_affine.setIdentity(); // reset internal flag _changed = false; @@ -862,45 +856,45 @@ static double sign(double const x) } gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &, NR::Point &pt, guint state) + SPSelTransHandle const &, Geom::Point &pt, guint state) { return seltrans->scaleRequest(pt, state); } gboolean sp_sel_trans_stretch_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, NR::Point &pt, guint state) + SPSelTransHandle const &handle, Geom::Point &pt, guint state) { return seltrans->stretchRequest(handle, pt, state); } gboolean sp_sel_trans_skew_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &handle, NR::Point &pt, guint state) + SPSelTransHandle const &handle, Geom::Point &pt, guint state) { return seltrans->skewRequest(handle, pt, state); } gboolean sp_sel_trans_rotate_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &, NR::Point &pt, guint state) + SPSelTransHandle const &, Geom::Point &pt, guint state) { return seltrans->rotateRequest(pt, state); } gboolean sp_sel_trans_center_request(Inkscape::SelTrans *seltrans, - SPSelTransHandle const &, NR::Point &pt, guint state) + SPSelTransHandle const &, Geom::Point &pt, guint state) { return seltrans->centerRequest(pt, state); } -gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) +gboolean Inkscape::SelTrans::scaleRequest(Geom::Point &pt, guint state) { // Calculate the scale factors, which can be either visual or geometric // depending on which type of bbox is currently being used (see preferences -> selector tool) - NR::scale default_scale = calcScaleFactors(_point, pt, _origin); + Geom::Scale default_scale = calcScaleFactors(_point, pt, _origin); // Find the scale factors for the geometric bbox - NR::Point pt_geom = _getGeomHandlePos(pt); - NR::scale geom_scale = calcScaleFactors(_point_geom, pt_geom, _origin_for_specpoints); + Geom::Point pt_geom = _getGeomHandlePos(pt); + Geom::Scale geom_scale = calcScaleFactors(_point_geom, pt_geom, _origin_for_specpoints); _absolute_affine = Geom::identity(); //Initialize the scaler @@ -922,42 +916,38 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) m.setup(_desktop, false, _items_const); Inkscape::SnappedPoint bb, sn; - NR::Coord bd(NR_HUGE); - NR::Coord sd(NR_HUGE); + Geom::Coord bd(NR_HUGE); + Geom::Coord sd(NR_HUGE); if ((state & GDK_CONTROL_MASK) || _desktop->isToolboxButtonActive ("lock")) { // Scale is locked to a 1:1 aspect ratio, so that s[X] must be made to equal s[Y]. // // The aspect-ratio must be locked before snapping - if (fabs(default_scale[NR::X]) > fabs(default_scale[NR::Y])) { - default_scale[NR::X] = fabs(default_scale[NR::Y]) * sign(default_scale[NR::X]); - geom_scale[NR::X] = fabs(geom_scale[NR::Y]) * sign(geom_scale[NR::X]); + if (fabs(default_scale[Geom::X]) > fabs(default_scale[Geom::Y])) { + default_scale[Geom::X] = fabs(default_scale[Geom::Y]) * sign(default_scale[Geom::X]); + geom_scale[Geom::X] = fabs(geom_scale[Geom::Y]) * sign(geom_scale[Geom::X]); } else { - default_scale[NR::Y] = fabs(default_scale[NR::X]) * sign(default_scale[NR::Y]); - geom_scale[NR::Y] = fabs(geom_scale[NR::X]) * sign(geom_scale[NR::Y]); + default_scale[Geom::Y] = fabs(default_scale[Geom::X]) * sign(default_scale[Geom::Y]); + geom_scale[Geom::Y] = fabs(geom_scale[Geom::X]) * sign(geom_scale[Geom::Y]); } // Snap along a suitable constraint vector from the origin. - Geom::Scale default_scale_2geom = to_2geom(default_scale); - Geom::Scale geom_scale_2geom = to_2geom(geom_scale); - bb = m.constrainedSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, default_scale_2geom, to_2geom(_origin_for_bboxpoints)); - sn = m.constrainedSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, geom_scale_2geom, to_2geom(_origin_for_specpoints)); + bb = m.constrainedSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, default_scale, _origin_for_bboxpoints); + sn = m.constrainedSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, geom_scale, _origin_for_specpoints); /* Choose the smaller difference in scale. Since s[X] == s[Y] we can ** just compare difference in s[X]. */ - bd = bb.getSnapped() ? fabs(bb.getTransformation()[NR::X] - default_scale_2geom[Geom::X]) : NR_HUGE; - sd = sn.getSnapped() ? fabs(sn.getTransformation()[NR::X] - geom_scale_2geom[Geom::X]) : NR_HUGE; + bd = bb.getSnapped() ? fabs(bb.getTransformation()[Geom::X] - default_scale[Geom::X]) : NR_HUGE; + sd = sn.getSnapped() ? fabs(sn.getTransformation()[Geom::X] - geom_scale[Geom::X]) : NR_HUGE; } else { /* Scale aspect ratio is unlocked */ - Geom::Scale default_scale_2geom = to_2geom(default_scale); - Geom::Scale geom_scale_2geom = to_2geom(geom_scale); - bb = m.freeSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, default_scale_2geom, to_2geom(_origin_for_bboxpoints)); - sn = m.freeSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, geom_scale_2geom, to_2geom(_origin_for_specpoints)); + bb = m.freeSnapScale(Snapper::SNAPPOINT_BBOX, _bbox_points, default_scale, _origin_for_bboxpoints); + sn = m.freeSnapScale(Snapper::SNAPPOINT_NODE, _snap_points, geom_scale, _origin_for_specpoints); /* Pick the snap that puts us closest to the original scale */ - bd = bb.getSnapped() ? fabs(NR::L2(bb.getTransformation()) - NR::L2(NR::Point(default_scale_2geom[Geom::X], default_scale_2geom[Geom::Y]))) : NR_HUGE; - sd = sn.getSnapped() ? fabs(NR::L2(sn.getTransformation()) - NR::L2(NR::Point(geom_scale_2geom[Geom::X], geom_scale_2geom[Geom::Y]))) : NR_HUGE; + bd = bb.getSnapped() ? fabs(Geom::L2(bb.getTransformation()) - Geom::L2(Geom::Point(default_scale[Geom::X], default_scale[Geom::Y]))) : NR_HUGE; + sd = sn.getSnapped() ? fabs(Geom::L2(sn.getTransformation()) - Geom::L2(Geom::Point(geom_scale[Geom::X], geom_scale[Geom::Y]))) : NR_HUGE; } if (!(bb.getSnapped() || sn.getSnapped())) { @@ -967,7 +957,7 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) } else if (bd < sd) { // We snapped the bbox (which is either visual or geometric) _desktop->snapindicator->set_new_snappoint(bb); - default_scale = NR::scale(bb.getTransformation()); + default_scale = Geom::Scale(bb.getTransformation()); // Calculate the new transformation and update the handle position pt = _calcAbsAffineDefault(default_scale); } else { @@ -975,7 +965,7 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) // We snapped the special points (e.g. nodes), which are not at the visual bbox // The handle location however (pt) might however be at the visual bbox, so we // will have to calculate pt taking the stroke width into account - geom_scale = NR::scale(sn.getTransformation()); + geom_scale = Geom::Scale(sn.getTransformation()); pt = _calcAbsAffineGeom(geom_scale); } } @@ -988,19 +978,19 @@ gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) return TRUE; } -gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state) +gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state) { - NR::Dim2 axis, perp; + Geom::Dim2 axis, perp; switch (handle.cursor) { case GDK_TOP_SIDE: case GDK_BOTTOM_SIDE: - axis = NR::Y; - perp = NR::X; + axis = Geom::Y; + perp = Geom::X; break; case GDK_LEFT_SIDE: case GDK_RIGHT_SIDE: - axis = NR::X; - perp = NR::Y; + axis = Geom::X; + perp = Geom::Y; break; default: g_assert_not_reached(); @@ -1009,12 +999,12 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: // Calculate the scale factors, which can be either visual or geometric // depending on which type of bbox is currently being used (see preferences -> selector tool) - NR::scale default_scale = calcScaleFactors(_point, pt, _origin); + Geom::Scale default_scale = calcScaleFactors(_point, pt, _origin); default_scale[perp] = 1; // Find the scale factors for the geometric bbox - NR::Point pt_geom = _getGeomHandlePos(pt); - NR::scale geom_scale = calcScaleFactors(_point_geom, pt_geom, _origin_for_specpoints); + Geom::Point pt_geom = _getGeomHandlePos(pt); + Geom::Scale geom_scale = calcScaleFactors(_point_geom, pt_geom, _origin_for_specpoints); geom_scale[perp] = 1; _absolute_affine = Geom::identity(); //Initialize the scaler @@ -1036,49 +1026,46 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: Inkscape::SnappedPoint bb, sn; g_assert(bb.getSnapped() == false); // Check initialization to catch any regression - NR::Coord bd(NR_HUGE); - NR::Coord sd(NR_HUGE); + Geom::Coord bd(NR_HUGE); + Geom::Coord sd(NR_HUGE); bool symmetrical = state & GDK_CONTROL_MASK; - Geom::Scale default_scale_2geom = to_2geom(default_scale); - Geom::Scale geom_scale_2geom = to_2geom(geom_scale); - - bb = m.constrainedSnapStretch(Snapper::SNAPPOINT_BBOX, _bbox_points, Geom::Coord(default_scale_2geom[axis]), to_2geom(_origin_for_bboxpoints), Geom::Dim2(axis), symmetrical); - sn = m.constrainedSnapStretch(Snapper::SNAPPOINT_NODE, _snap_points, Geom::Coord(geom_scale_2geom[axis]), to_2geom(_origin_for_specpoints), Geom::Dim2(axis), symmetrical); + bb = m.constrainedSnapStretch(Snapper::SNAPPOINT_BBOX, _bbox_points, Geom::Coord(default_scale[axis]), _origin_for_bboxpoints, Geom::Dim2(axis), symmetrical); + sn = m.constrainedSnapStretch(Snapper::SNAPPOINT_NODE, _snap_points, Geom::Coord(geom_scale[axis]), _origin_for_specpoints, Geom::Dim2(axis), symmetrical); if (bb.getSnapped()) { // We snapped the bbox (which is either visual or geometric) - bd = fabs(bb.getTransformation()[axis] - default_scale_2geom[axis]); - default_scale_2geom[axis] = bb.getTransformation()[axis]; + bd = fabs(bb.getTransformation()[axis] - default_scale[axis]); + default_scale[axis] = bb.getTransformation()[axis]; } if (sn.getSnapped()) { - sd = fabs(sn.getTransformation()[axis] - geom_scale_2geom[axis]); - geom_scale_2geom[axis] = sn.getTransformation()[axis]; + sd = fabs(sn.getTransformation()[axis] - geom_scale[axis]); + geom_scale[axis] = sn.getTransformation()[axis]; } if (symmetrical) { // on ctrl, apply symmetrical scaling instead of stretching // Preserve aspect ratio, but never flip in the dimension not being edited (by using fabs()) - default_scale_2geom[perp] = fabs(default_scale_2geom[axis]); - geom_scale_2geom[perp] = fabs(geom_scale_2geom[axis]); + default_scale[perp] = fabs(default_scale[axis]); + geom_scale[perp] = fabs(geom_scale[axis]); } if (!(bb.getSnapped() || sn.getSnapped())) { // We didn't snap at all! Don't update the handle position, just calculate the new transformation - _calcAbsAffineDefault(from_2geom(default_scale_2geom)); + _calcAbsAffineDefault(default_scale); _desktop->snapindicator->remove_snappoint(); } else if (bd < sd) { _desktop->snapindicator->set_new_snappoint(bb); // Calculate the new transformation and update the handle position - pt = _calcAbsAffineDefault(from_2geom(default_scale_2geom)); + pt = _calcAbsAffineDefault(default_scale); } else { _desktop->snapindicator->set_new_snappoint(sn); // We snapped the special points (e.g. nodes), which are not at the visual bbox // The handle location however (pt) might however be at the visual bbox, so we // will have to calculate pt taking the stroke width into account - pt = _calcAbsAffineGeom(from_2geom(geom_scale_2geom)); + pt = _calcAbsAffineGeom(geom_scale); } } @@ -1090,7 +1077,7 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR:: return TRUE; } -gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state) +gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state) { /* When skewing (or rotating): * 1) the stroke width will not change. This makes life much easier because we don't have to @@ -1100,17 +1087,17 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi * the handle; otherwise it will be relative to the center as set for the selection */ - NR::Dim2 dim_a; - NR::Dim2 dim_b; + Geom::Dim2 dim_a; + Geom::Dim2 dim_b; switch (handle.cursor) { case GDK_SB_H_DOUBLE_ARROW: - dim_a = NR::Y; - dim_b = NR::X; + dim_a = Geom::Y; + dim_b = Geom::X; break; case GDK_SB_V_DOUBLE_ARROW: - dim_a = NR::X; - dim_b = NR::Y; + dim_a = Geom::X; + dim_b = Geom::Y; break; default: g_assert_not_reached(); @@ -1118,7 +1105,7 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi break; } - NR::Point const initial_delta = _point - _origin; + Geom::Point const initial_delta = _point - _origin; if (fabs(initial_delta[dim_a]) < 1e-15) { return false; @@ -1126,8 +1113,8 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi // Calculate the scale factors, which can be either visual or geometric // depending on which type of bbox is currently being used (see preferences -> selector tool) - NR::scale scale = calcScaleFactors(_point, pt, _origin, false); - NR::scale skew = calcScaleFactors(_point, pt, _origin, true); + Geom::Scale scale = calcScaleFactors(_point, pt, _origin, false); + Geom::Scale skew = calcScaleFactors(_point, pt, _origin, true); scale[dim_b] = 1; skew[dim_b] = 1; @@ -1159,21 +1146,15 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi m.setup(_desktop, false, _items_const); Inkscape::Snapper::ConstraintLine const constraint(component_vectors[dim_b]); - NR::Point const s(skew[dim_a], scale[dim_a]); - Inkscape::SnappedPoint bb = m.constrainedSnapSkew(Inkscape::Snapper::SNAPPOINT_BBOX, _bbox_points, constraint, to_2geom(s), to_2geom(_origin), Geom::Dim2(dim_b)); - Inkscape::SnappedPoint sn = m.constrainedSnapSkew(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, constraint, to_2geom(s), to_2geom(_origin), Geom::Dim2(dim_b)); + // When skewing, we cannot snap the corners of the bounding box, see the comment in "constrainedSnapSkew" for details + Geom::Point const s(skew[dim_a], scale[dim_a]); + Inkscape::SnappedPoint sn = m.constrainedSnapSkew(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, constraint, s, _origin, Geom::Dim2(dim_b)); - if (bb.getSnapped() || sn.getSnapped()) { + if (sn.getSnapped()) { // We snapped something, so change the skew to reflect it - NR::Coord const bd = bb.getSnapped() ? bb.getTransformation()[0] : NR_HUGE; - NR::Coord const sd = sn.getSnapped() ? sn.getTransformation()[0] : NR_HUGE; - if (bd < sd) { - _desktop->snapindicator->set_new_snappoint(bb); - skew[dim_a] = bd; - } else { - _desktop->snapindicator->set_new_snappoint(sn); - skew[dim_a] = sd; - } + Geom::Coord const sd = sn.getSnapped() ? sn.getTransformation()[0] : NR_HUGE; + _desktop->snapindicator->set_new_snappoint(sn); + skew[dim_a] = sd; } else { _desktop->snapindicator->remove_snappoint(); } @@ -1207,7 +1188,7 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Poi return TRUE; } -gboolean Inkscape::SelTrans::rotateRequest(NR::Point &pt, guint state) +gboolean Inkscape::SelTrans::rotateRequest(Geom::Point &pt, guint state) { /* When rotating (or skewing): * 1) the stroke width will not change. This makes life much easier because we don't have to @@ -1220,40 +1201,40 @@ gboolean Inkscape::SelTrans::rotateRequest(NR::Point &pt, guint state) int snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); // rotate affine in rotate - NR::Point const d1 = _point - _origin; - NR::Point const d2 = pt - _origin; + Geom::Point const d1 = _point - _origin; + Geom::Point const d2 = pt - _origin; - NR::Coord const h1 = NR::L2(d1); // initial radius + Geom::Coord const h1 = Geom::L2(d1); // initial radius if (h1 < 1e-15) return FALSE; - NR::Point q1 = d1 / h1; // normalized initial vector to handle - NR::Coord const h2 = NR::L2(d2); // new radius + Geom::Point q1 = d1 / h1; // normalized initial vector to handle + Geom::Coord const h2 = Geom::L2(d2); // new radius if (fabs(h2) < 1e-15) return FALSE; - NR::Point q2 = d2 / h2; // normalized new vector to handle + Geom::Point q2 = d2 / h2; // normalized new vector to handle double radians; if (state & GDK_CONTROL_MASK) { // Snap to defined angle increments - double cos_t = NR::dot(q1, q2); - double sin_t = NR::dot(NR::rot90(q1), q2); + double cos_t = Geom::dot(q1, q2); + double sin_t = Geom::dot(Geom::rot90(q1), q2); radians = atan2(sin_t, cos_t); if (snaps) { radians = ( M_PI / snaps ) * floor( radians * snaps / M_PI + .5 ); } - q1 = NR::Point(1, 0); - q2 = NR::Point(cos(radians), sin(radians)); + q1 = Geom::Point(1, 0); + q2 = Geom::Point(cos(radians), sin(radians)); } else { - radians = atan2(NR::dot(NR::rot90(d1), d2), - NR::dot(d1, d2)); + radians = atan2(Geom::dot(Geom::rot90(d1), d2), + Geom::dot(d1, d2)); } - NR::rotate const r1(q1); - NR::rotate const r2(q2); + Geom::Rotate const r1(q1); + Geom::Rotate const r2(q2); // Calculate the relative affine - _relative_affine = NR::Matrix(r2/r1); + _relative_affine = r2 * r1.inverse(); // Update the handle position - pt = _point * NR::translate(-_origin) * _relative_affine * NR::translate(_origin); + pt = _point * Geom::Translate(-_origin) * _relative_affine * Geom::Translate(_origin); // Update the status text double degrees = mod360symm(Geom::rad_to_deg(radians)); @@ -1265,19 +1246,17 @@ gboolean Inkscape::SelTrans::rotateRequest(NR::Point &pt, guint state) return TRUE; } -gboolean Inkscape::SelTrans::centerRequest(NR::Point &pt, guint state) +gboolean Inkscape::SelTrans::centerRequest(Geom::Point &pt, guint state) { SnapManager &m = _desktop->namedview->snap_manager; m.setup(_desktop); - Geom::Point pt2g = to_2geom(pt); - m.freeSnapReturnByRef(Snapper::SNAPPOINT_NODE, pt2g); - pt = from_2geom(pt2g); + m.freeSnapReturnByRef(Snapper::SNAPPOINT_NODE, pt); if (state & GDK_CONTROL_MASK) { - if ( fabs(_point[NR::X] - pt[NR::X]) > fabs(_point[NR::Y] - pt[NR::Y]) ) { - pt[NR::Y] = _point[NR::Y]; + if ( fabs(_point[Geom::X] - pt[Geom::X]) > fabs(_point[Geom::Y] - pt[Geom::Y]) ) { + pt[Geom::Y] = _point[Geom::Y]; } else { - pt[NR::X] = _point[NR::X]; + pt[Geom::X] = _point[Geom::X]; } } @@ -1301,8 +1280,8 @@ gboolean Inkscape::SelTrans::centerRequest(NR::Point &pt, guint state) } // status text - GString *xs = SP_PX_TO_METRIC_STRING(pt[NR::X], _desktop->namedview->getDefaultMetric()); - GString *ys = SP_PX_TO_METRIC_STRING(pt[NR::Y], _desktop->namedview->getDefaultMetric()); + GString *xs = SP_PX_TO_METRIC_STRING(pt[Geom::X], _desktop->namedview->getDefaultMetric()); + GString *ys = SP_PX_TO_METRIC_STRING(pt[Geom::Y], _desktop->namedview->getDefaultMetric()); _message_context.setF(Inkscape::NORMAL_MESSAGE, _("Move <b>center</b> to %s, %s"), xs->str, ys->str); g_string_free(xs, FALSE); g_string_free(ys, FALSE); @@ -1315,59 +1294,59 @@ gboolean Inkscape::SelTrans::centerRequest(NR::Point &pt, guint state) * */ -void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &pt, guint state) +void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &pt, guint state) { seltrans->stretch(handle, pt, state); } -void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, NR::Point &pt, guint state) +void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, Geom::Point &pt, guint state) { seltrans->scale(pt, state); } -void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &pt, guint state) +void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, Geom::Point &pt, guint state) { seltrans->skew(handle, pt, state); } -void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, NR::Point &pt, guint state) +void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, Geom::Point &pt, guint state) { seltrans->rotate(pt, state); } -void Inkscape::SelTrans::stretch(SPSelTransHandle const &/*handle*/, NR::Point &/*pt*/, guint /*state*/) +void Inkscape::SelTrans::stretch(SPSelTransHandle const &/*handle*/, Geom::Point &/*pt*/, guint /*state*/) { - transform(_absolute_affine, NR::Point(0, 0)); // we have already accounted for origin, so pass 0,0 + transform(_absolute_affine, Geom::Point(0, 0)); // we have already accounted for origin, so pass 0,0 } -void Inkscape::SelTrans::scale(NR::Point &/*pt*/, guint /*state*/) +void Inkscape::SelTrans::scale(Geom::Point &/*pt*/, guint /*state*/) { - transform(_absolute_affine, NR::Point(0, 0)); // we have already accounted for origin, so pass 0,0 + transform(_absolute_affine, Geom::Point(0, 0)); // we have already accounted for origin, so pass 0,0 } -void Inkscape::SelTrans::skew(SPSelTransHandle const &/*handle*/, NR::Point &/*pt*/, guint /*state*/) +void Inkscape::SelTrans::skew(SPSelTransHandle const &/*handle*/, Geom::Point &/*pt*/, guint /*state*/) { transform(_relative_affine, _origin); } -void Inkscape::SelTrans::rotate(NR::Point &/*pt*/, guint /*state*/) +void Inkscape::SelTrans::rotate(Geom::Point &/*pt*/, guint /*state*/) { transform(_relative_affine, _origin); } -void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, NR::Point &pt, guint /*state*/) +void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, Geom::Point &pt, guint /*state*/) { seltrans->setCenter(pt); } -void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) +void Inkscape::SelTrans::moveTo(Geom::Point const &xy, guint state) { SnapManager &m = _desktop->namedview->snap_manager; m.setup(_desktop, true, _items_const); /* The amount that we've moved by during this drag */ - Geom::Point dxy = to_2geom(xy - _point); + Geom::Point dxy = xy - _point; bool const alt = (state & GDK_MOD1_MASK); bool const control = (state & GDK_CONTROL_MASK); @@ -1421,7 +1400,7 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) /* Snap to things with no constraint */ s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAPPOINT_BBOX, _bbox_points, dxy)); - s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, dxy)); + s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAPPOINT_NODE, _snap_points, dxy)); /*g_get_current_time(&endtime); double elapsed = ((((double)endtime.tv_sec - starttime.tv_sec) * G_USEC_PER_SEC + (endtime.tv_usec - starttime.tv_usec))) / 1000.0; @@ -1459,7 +1438,7 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) Geom::Matrix const move((Geom::Translate(dxy))); Geom::Point const norm(0, 0); - transform(from_2geom(move), from_2geom(norm)); + transform(move, norm); // status text GString *xs = SP_PX_TO_METRIC_STRING(dxy[Geom::X], _desktop->namedview->getDefaultMetric()); @@ -1471,7 +1450,7 @@ void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) // Given a location of a handle at the visual bounding box, find the corresponding location at the // geometrical bounding box -NR::Point Inkscape::SelTrans::_getGeomHandlePos(NR::Point const &visual_handle_pos) +Geom::Point Inkscape::SelTrans::_getGeomHandlePos(Geom::Point const &visual_handle_pos) { if ( _snap_bbox_type == SPItem::GEOMETRIC_BBOX) { // When the selector tool is using geometric bboxes, then the handle is already @@ -1484,32 +1463,32 @@ NR::Point Inkscape::SelTrans::_getGeomHandlePos(NR::Point const &visual_handle_p return visual_handle_pos; } - // Using the NR::Rect constructor below ensures that "min() < max()", which is important + // Using the Geom::Rect constructor below ensures that "min() < max()", which is important // because this will also hold for _bbox, and which is required for get_scale_transform_with_stroke() - NR::Rect new_bbox = NR::Rect(_origin_for_bboxpoints, visual_handle_pos); // new visual bounding box + Geom::Rect new_bbox = Geom::Rect(_origin_for_bboxpoints, visual_handle_pos); // new visual bounding box // Please note that the new_bbox might in fact be just a single line, for example when stretching (in // which case the handle and origin will be aligned vertically or horizontally) - NR::Point normalized_handle_pos = (visual_handle_pos - new_bbox.min()) * NR::scale(new_bbox.dimensions()).inverse(); + Geom::Point normalized_handle_pos = (visual_handle_pos - new_bbox.min()) * Geom::Scale(new_bbox.dimensions()).inverse(); // Calculate the absolute affine while taking into account the scaling of the stroke width int transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1); - NR::Matrix abs_affine = get_scale_transform_with_stroke (*_bbox, _strokewidth, transform_stroke, - new_bbox.min()[NR::X], new_bbox.min()[NR::Y], new_bbox.max()[NR::X], new_bbox.max()[NR::Y]); + Geom::Matrix abs_affine = get_scale_transform_with_stroke (*_bbox, _strokewidth, transform_stroke, + new_bbox.min()[Geom::X], new_bbox.min()[Geom::Y], new_bbox.max()[Geom::X], new_bbox.max()[Geom::Y]); // Calculate the scaled geometrical bbox - NR::Rect new_geom_bbox = NR::Rect(_geometric_bbox->min() * abs_affine, _geometric_bbox->max() * abs_affine); + Geom::Rect new_geom_bbox = Geom::Rect(_geometric_bbox->min() * abs_affine, _geometric_bbox->max() * abs_affine); // Find the location of the handle on this new geometrical bbox - return normalized_handle_pos * NR::scale(new_geom_bbox.dimensions()) + new_geom_bbox.min(); //new position of the geometric handle + return normalized_handle_pos * Geom::Scale(new_geom_bbox.dimensions()) + new_geom_bbox.min(); //new position of the geometric handle } -NR::scale Inkscape::calcScaleFactors(NR::Point const &initial_point, NR::Point const &new_point, NR::Point const &origin, bool const skew) +Geom::Scale Inkscape::calcScaleFactors(Geom::Point const &initial_point, Geom::Point const &new_point, Geom::Point const &origin, bool const skew) { // Work out the new scale factors for the bbox - NR::Point const initial_delta = initial_point - origin; - NR::Point const new_delta = new_point - origin; - NR::Point const offset = new_point - initial_point; - NR::scale scale(1, 1); + Geom::Point const initial_delta = initial_point - origin; + Geom::Point const new_delta = new_point - origin; + Geom::Point const offset = new_point - initial_point; + Geom::Scale scale(1, 1); for ( unsigned int i = 0 ; i < 2 ; i++ ) { if ( fabs(initial_delta[i]) > 1e-6 ) { @@ -1525,11 +1504,11 @@ NR::scale Inkscape::calcScaleFactors(NR::Point const &initial_point, NR::Point c } // Only for scaling/stretching -NR::Point Inkscape::SelTrans::_calcAbsAffineDefault(NR::scale const default_scale) +Geom::Point Inkscape::SelTrans::_calcAbsAffineDefault(Geom::Scale const default_scale) { - NR::Matrix abs_affine = NR::translate(-_origin) * NR::Matrix(default_scale) * NR::translate(_origin); - NR::Point new_bbox_min = _approximate_bbox->min() * abs_affine; - NR::Point new_bbox_max = _approximate_bbox->max() * abs_affine; + Geom::Matrix abs_affine = Geom::Translate(-_origin) * Geom::Matrix(default_scale) * Geom::Translate(_origin); + Geom::Point new_bbox_min = _approximate_bbox->min() * abs_affine; + Geom::Point new_bbox_max = _approximate_bbox->max() * abs_affine; int transform_stroke = false; gdouble strokewidth = 0; @@ -1540,23 +1519,23 @@ NR::Point Inkscape::SelTrans::_calcAbsAffineDefault(NR::scale const default_scal } _absolute_affine = get_scale_transform_with_stroke (*_approximate_bbox, strokewidth, transform_stroke, - new_bbox_min[NR::X], new_bbox_min[NR::Y], new_bbox_max[NR::X], new_bbox_max[NR::Y]); + new_bbox_min[Geom::X], new_bbox_min[Geom::Y], new_bbox_max[Geom::X], new_bbox_max[Geom::Y]); // return the new handle position return ( _point - _origin ) * default_scale + _origin; } // Only for scaling/stretching -NR::Point Inkscape::SelTrans::_calcAbsAffineGeom(NR::scale const geom_scale) +Geom::Point Inkscape::SelTrans::_calcAbsAffineGeom(Geom::Scale const geom_scale) { - _relative_affine = NR::Matrix(geom_scale); - _absolute_affine = NR::translate(-_origin_for_specpoints) * _relative_affine * NR::translate(_origin_for_specpoints); + _relative_affine = Geom::Matrix(geom_scale); + _absolute_affine = Geom::Translate(-_origin_for_specpoints) * _relative_affine * Geom::Translate(_origin_for_specpoints); bool const transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1); - NR::Rect visual_bbox = get_visual_bbox(_geometric_bbox, _absolute_affine, _strokewidth, transform_stroke); + Geom::Rect visual_bbox = get_visual_bbox(_geometric_bbox, _absolute_affine, _strokewidth, transform_stroke); // return the new handle position - return visual_bbox.min() + visual_bbox.dimensions() * NR::scale(_handle_x, _handle_y); + return visual_bbox.min() + visual_bbox.dimensions() * Geom::Scale(_handle_x, _handle_y); } diff --git a/src/seltrans.h b/src/seltrans.h index 65da0fa56..64ced3dc5 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -16,9 +16,9 @@ */ #include <sigc++/sigc++.h> -#include <libnr/nr-point.h> -#include <libnr/nr-matrix.h> -#include <libnr/nr-rect.h> +#include <2geom/point.h> +#include <2geom/matrix.h> +#include <2geom/rect.h> #include "knot.h" #include "forward.h" #include "selcue.h" @@ -33,7 +33,7 @@ class SPSelTransHandle; namespace Inkscape { -NR::scale calcScaleFactors(NR::Point const &initial_point, NR::Point const &new_point, NR::Point const &origin, bool const skew = false); +Geom::Scale calcScaleFactors(Geom::Point const &initial_point, Geom::Point const &new_point, Geom::Point const &origin, bool const skew = false); namespace XML { @@ -52,26 +52,26 @@ public: void increaseState(); void resetState(); - void setCenter(NR::Point const &p); - void grab(NR::Point const &p, gdouble x, gdouble y, bool show_handles); - void transform(NR::Matrix const &rel_affine, NR::Point const &norm); + void setCenter(Geom::Point const &p); + void grab(Geom::Point const &p, gdouble x, gdouble y, bool show_handles); + void transform(Geom::Matrix const &rel_affine, Geom::Point const &norm); void ungrab(); void stamp(); - void moveTo(NR::Point const &xy, guint state); - void stretch(SPSelTransHandle const &handle, NR::Point &pt, guint state); - void scale(NR::Point &pt, guint state); - void skew(SPSelTransHandle const &handle, NR::Point &pt, guint state); - void rotate(NR::Point &pt, guint state); - gboolean scaleRequest(NR::Point &pt, guint state); - gboolean stretchRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state); - gboolean skewRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state); - gboolean rotateRequest(NR::Point &pt, guint state); - gboolean centerRequest(NR::Point &pt, guint state); - - gboolean handleRequest(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle); + void moveTo(Geom::Point const &xy, guint state); + void stretch(SPSelTransHandle const &handle, Geom::Point &pt, guint state); + void scale(Geom::Point &pt, guint state); + void skew(SPSelTransHandle const &handle, Geom::Point &pt, guint state); + void rotate(Geom::Point &pt, guint state); + gboolean scaleRequest(Geom::Point &pt, guint state); + gboolean stretchRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); + gboolean skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); + gboolean rotateRequest(Geom::Point &pt, guint state); + gboolean centerRequest(Geom::Point &pt, guint state); + + gboolean handleRequest(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle); void handleGrab(SPKnot *knot, guint state, SPSelTransHandle const &handle); void handleClick(SPKnot *knot, guint state, SPSelTransHandle const &handle); - void handleNewEvent(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle); + void handleNewEvent(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle); enum Show { @@ -99,9 +99,9 @@ private: void _selModified(Inkscape::Selection *selection, guint flags); void _showHandles(SPKnot *knot[], SPSelTransHandle const handle[], gint num, gchar const *even_tip, gchar const *odd_tip); - NR::Point _getGeomHandlePos(NR::Point const &visual_handle_pos); - NR::Point _calcAbsAffineDefault(NR::scale const default_scale); - NR::Point _calcAbsAffineGeom(NR::scale const geom_scale); + Geom::Point _getGeomHandlePos(Geom::Point const &visual_handle_pos); + Geom::Point _calcAbsAffineDefault(Geom::Scale const default_scale); + Geom::Point _calcAbsAffineGeom(Geom::Scale const geom_scale); enum State { STATE_SCALE, //scale or stretch @@ -112,8 +112,8 @@ private: std::vector<SPItem *> _items; std::vector<SPItem const *> _items_const; - std::vector<NR::Matrix> _items_affines; - std::vector<NR::Point> _items_centers; + std::vector<Geom::Matrix> _items_affines; + std::vector<Geom::Point> _items_centers; std::vector<Geom::Point> _snap_points; std::vector<Geom::Point> _bbox_points; @@ -131,30 +131,30 @@ private: SPItem::BBoxType _snap_bbox_type; - boost::optional<NR::Rect> _bbox; - boost::optional<NR::Rect> _approximate_bbox; - boost::optional<NR::Rect> _geometric_bbox; + boost::optional<Geom::Rect> _bbox; + boost::optional<Geom::Rect> _approximate_bbox; + boost::optional<Geom::Rect> _geometric_bbox; gdouble _strokewidth; - NR::Matrix _current_relative_affine; - NR::Matrix _absolute_affine; - NR::Matrix _relative_affine; + Geom::Matrix _current_relative_affine; + Geom::Matrix _absolute_affine; + Geom::Matrix _relative_affine; /* According to Merriam - Webster's online dictionary * Affine: a transformation (as a translation, a rotation, or a uniform stretching) that carries straight * lines into straight lines and parallel lines into parallel lines but may alter distance between points * and angles between lines <affine geometry> */ - NR::Point _opposite; ///< opposite point to where a scale is taking place - NR::Point _opposite_for_specpoints; - NR::Point _opposite_for_bboxpoints; - NR::Point _origin_for_specpoints; - NR::Point _origin_for_bboxpoints; + Geom::Point _opposite; ///< opposite point to where a scale is taking place + Geom::Point _opposite_for_specpoints; + Geom::Point _opposite_for_bboxpoints; + Geom::Point _origin_for_specpoints; + Geom::Point _origin_for_bboxpoints; gdouble _handle_x; gdouble _handle_y; - boost::optional<NR::Point> _center; + boost::optional<Geom::Point> _center; bool _center_is_set; ///< we've already set _center, no need to reread it from items SPKnot *_shandle[8]; @@ -167,9 +167,9 @@ private: guint _sel_modified_id; GSList *_stamp_cache; - NR::Point _origin; ///< position of origin for transforms - NR::Point _point; ///< original position of the knot being used for the current transform - NR::Point _point_geom; ///< original position of the knot being used for the current transform + Geom::Point _origin; ///< position of origin for transforms + Geom::Point _point; ///< original position of the knot being used for the current transform + Geom::Point _point_geom; ///< original position of the knot being used for the current transform Inkscape::MessageContext _message_context; sigc::connection _sel_changed_connection; sigc::connection _sel_modified_connection; diff --git a/src/snap.cpp b/src/snap.cpp index 394bc7f91..202dd8e92 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -475,14 +475,15 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( /* Snap it */ Inkscape::SnappedPoint snapped_point; + Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint; + Geom::Point const b = (*i - origin); // vector to original point - if (constrained) { - Inkscape::Snapper::ConstraintLine dedicated_constraint = constraint; + if (constrained) { if ((transformation_type == SCALE || transformation_type == STRETCH) && uniform) { // When uniformly scaling, each point will have its own unique constraint line, // running from the scaling origin to the original untransformed point. We will // calculate that line here - dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, (*i) - origin); + dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, b); } else if (transformation_type == STRETCH) { // when non-uniform stretching { dedicated_constraint = Inkscape::Snapper::ConstraintLine((*i), component_vectors[dim]); } else if (transformation_type == TRANSLATION) { @@ -497,7 +498,17 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( } snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox); } else { - snapped_point = freeSnap(type, *j, i == points.begin(), bbox); + bool const c1 = fabs(b[Geom::X]) < 1e-6; + bool const c2 = fabs(b[Geom::Y]) < 1e-6; + if (transformation_type == SCALE && (c1 || c2) && !(c1 && c2)) { + // When scaling, a point aligned either horizontally or vertically with the origin can only + // move in that specific direction; therefore it should only snap in that direction, otherwise + // we will get snapped points with an invalid transformation + dedicated_constraint = Inkscape::Snapper::ConstraintLine(origin, component_vectors[c1]); + snapped_point = constrainedSnap(type, *j, dedicated_constraint, i == points.begin(), bbox); + } else { + snapped_point = freeSnap(type, *j, i == points.begin(), bbox); + } } Geom::Point result; @@ -508,7 +519,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( ** ended up, and also the metric for this transformation. */ Geom::Point const a = (snapped_point.getPoint() - origin); // vector to snapped point - Geom::Point const b = (*i - origin); // vector to original point + //Geom::Point const b = (*i - origin); // vector to original point switch (transformation_type) { case TRANSLATION: @@ -756,8 +767,15 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::Snapper::Point Geom::Point const &o, Geom::Dim2 d) const { - // "s" contains skew factor in s[0], and scale factor in s[1] - return _snapTransformed(point_type, p, true, constraint, SKEW, s, o, d, false); + // "s" contains skew factor in s[0], and scale factor in s[1] + + // Snapping the nodes of the boundingbox of a selection that is being transformed, will only work if + // the transformation of the bounding box is equal to the transformation of the individual nodes. This is + // NOT the case for example when rotating or skewing. The bounding box itself cannot possibly rotate or skew, + // so it's corners have a different transformation. The snappers cannot handle this, therefore snapping + // of bounding boxes is not allowed here. + g_assert(!(point_type & Inkscape::Snapper::SNAPPOINT_BBOX)); + return _snapTransformed(point_type, p, true, constraint, SKEW, s, o, d, false); } Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedConstraints &sc, bool constrained) const @@ -845,7 +863,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, SnappedCo // std::cout << "Finding the best snap..." << std::endl; for (std::list<Inkscape::SnappedPoint>::const_iterator i = sp_list.begin(); i != sp_list.end(); i++) { // first find out if this snapped point is within snapping range - // std::cout << "sp = " << from_2geom((*i).getPoint()); + // std::cout << "sp = " << from_2geom((*i).getPoint()); if ((*i).getDistance() <= (*i).getTolerance()) { // if it's the first point, or if it is closer than the best snapped point so far if (i == sp_list.begin() || bestSnappedPoint.isOtherOneBetter(*i)) { diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index a412694b3..06d025a14 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -26,6 +26,7 @@ #include "sp-item.h" #include "libnr/nr-matrix-ops.h" +#include <2geom/transforms.h> #include "sp-clippath.h" @@ -204,7 +205,7 @@ sp_clippath_update(SPObject *object, SPCtx *ctx, guint flags) SPClipPath *cp = SP_CLIPPATH(object); for (SPClipPathView *v = cp->display; v != NULL; v = v->next) { if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - NR::Matrix t(NR::scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0)); + Geom::Matrix t(Geom::Scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0)); t[4] = v->bbox.x0; t[5] = v->bbox.y0; nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), &t); @@ -275,7 +276,7 @@ sp_clippath_show(SPClipPath *cp, NRArena *arena, unsigned int key) } if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - NR::Matrix t(NR::scale(cp->display->bbox.x1 - cp->display->bbox.x0, cp->display->bbox.y1 - cp->display->bbox.y0)); + Geom::Matrix t(Geom::Scale(cp->display->bbox.x1 - cp->display->bbox.x0, cp->display->bbox.y1 - cp->display->bbox.y0)); t[4] = cp->display->bbox.x0; t[5] = cp->display->bbox.y0; nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), &t); diff --git a/src/sp-conn-end-pair.cpp b/src/sp-conn-end-pair.cpp index 0753e1441..14305c8a9 100644 --- a/src/sp-conn-end-pair.cpp +++ b/src/sp-conn-end-pair.cpp @@ -80,7 +80,7 @@ sp_conn_end_pair_build(SPObject *object) static void -avoid_conn_move(NR::Matrix const */*mp*/, SPItem *moved_item) +avoid_conn_move(Geom::Matrix const */*mp*/, SPItem *moved_item) { // Reroute connector SPPath *path = SP_PATH(moved_item); @@ -167,7 +167,7 @@ SPConnEndPair::getEndpoints(NR::Point endPts[]) const { for (unsigned h = 0; h < 2; ++h) { if ( h2attItem[h] ) { - boost::optional<NR::Rect> bbox = h2attItem[h]->getBounds(sp_item_i2doc_affine(h2attItem[h])); + boost::optional<Geom::Rect> bbox = h2attItem[h]->getBounds(sp_item_i2doc_affine(h2attItem[h])); if (bbox) { endPts[h] = bbox->midpoint(); } else { diff --git a/src/sp-conn-end.cpp b/src/sp-conn-end.cpp index f529d6d62..c94e75f71 100644 --- a/src/sp-conn-end.cpp +++ b/src/sp-conn-end.cpp @@ -11,8 +11,8 @@ #include "document.h" -static void change_endpts(SPCurve *const curve, NR::Point const h2endPt[2]); -static NR::Point calc_bbox_conn_pt(NR::Rect const &bbox, NR::Point const &p); +static void change_endpts(SPCurve *const curve, Geom::Point const h2endPt[2]); +static Geom::Point calc_bbox_conn_pt(Geom::Rect const &bbox, Geom::Point const &p); static double signed_one(double const x); SPConnEnd::SPConnEnd(SPObject *const owner) : @@ -36,7 +36,7 @@ get_nearest_common_ancestor(SPObject const *const obj, SPItem const *const objs[ } static void -sp_conn_end_move_compensate(NR::Matrix const */*mp*/, SPItem */*moved_item*/, +sp_conn_end_move_compensate(Geom::Matrix const */*mp*/, SPItem */*moved_item*/, SPPath *const path, bool const updatePathRepr = true) { @@ -60,19 +60,19 @@ sp_conn_end_move_compensate(NR::Matrix const */*mp*/, SPItem */*moved_item*/, SPItem const *const path_item = SP_ITEM(path); SPObject const *const ancestor = get_nearest_common_ancestor(path_item, h2attItem); - NR::Matrix const path2anc(i2anc_affine(path_item, ancestor)); + Geom::Matrix const path2anc(i2anc_affine(path_item, ancestor)); if (h2attItem[0] != NULL && h2attItem[1] != NULL) { /* Initial end-points: centre of attached object. */ - NR::Point h2endPt_icoordsys[2]; - NR::Matrix h2i2anc[2]; - NR::Rect h2bbox_icoordsys[2]; - NR::Point last_seg_endPt[2] = { + Geom::Point h2endPt_icoordsys[2]; + Geom::Matrix h2i2anc[2]; + Geom::Rect h2bbox_icoordsys[2]; + Geom::Point last_seg_endPt[2] = { *(path->curve->second_point()), *(path->curve->penultimate_point()) }; for (unsigned h = 0; h < 2; ++h) { - boost::optional<NR::Rect> bbox = h2attItem[h]->getBounds(NR::identity()); + boost::optional<Geom::Rect> bbox = h2attItem[h]->getBounds(Geom::identity()); if (!bbox) { if (updatePathRepr) { path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -87,7 +87,7 @@ sp_conn_end_move_compensate(NR::Matrix const */*mp*/, SPItem */*moved_item*/, // For each attached object, change the corresponding point to be // on the edge of the bbox. - NR::Point h2endPt_pcoordsys[2]; + Geom::Point h2endPt_pcoordsys[2]; for (unsigned h = 0; h < 2; ++h) { h2endPt_icoordsys[h] = calc_bbox_conn_pt(h2bbox_icoordsys[h], ( last_seg_endPt[h] * h2i2anc[h].inverse() )); @@ -98,8 +98,8 @@ sp_conn_end_move_compensate(NR::Matrix const */*mp*/, SPItem */*moved_item*/, // We leave the unattached endpoint where it is, and adjust the // position of the attached endpoint to be on the edge of the bbox. unsigned ind; - NR::Point other_endpt; - NR::Point last_seg_pt; + Geom::Point other_endpt; + Geom::Point last_seg_pt; if (h2attItem[0] != NULL) { other_endpt = *(path->curve->last_point()); last_seg_pt = *(path->curve->second_point()); @@ -110,12 +110,12 @@ sp_conn_end_move_compensate(NR::Matrix const */*mp*/, SPItem */*moved_item*/, last_seg_pt = *(path->curve->penultimate_point()); ind = 1; } - NR::Point h2endPt_icoordsys[2]; - NR::Matrix h2i2anc; + Geom::Point h2endPt_icoordsys[2]; + Geom::Matrix h2i2anc; - NR::Rect otherpt_rect = NR::Rect(other_endpt, other_endpt); - NR::Rect h2bbox_icoordsys[2] = { otherpt_rect, otherpt_rect }; - boost::optional<NR::Rect> bbox = h2attItem[ind]->getBounds(NR::identity()); + Geom::Rect otherpt_rect = Geom::Rect(other_endpt, other_endpt); + Geom::Rect h2bbox_icoordsys[2] = { otherpt_rect, otherpt_rect }; + boost::optional<Geom::Rect> bbox = h2attItem[ind]->getBounds(NR::identity()); if (!bbox) { if (updatePathRepr) { path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -132,7 +132,7 @@ sp_conn_end_move_compensate(NR::Matrix const */*mp*/, SPItem */*moved_item*/, // For the attached object, change the corresponding point to be // on the edge of the bbox. - NR::Point h2endPt_pcoordsys[2]; + Geom::Point h2endPt_pcoordsys[2]; h2endPt_icoordsys[ind] = calc_bbox_conn_pt(h2bbox_icoordsys[ind], ( last_seg_pt * h2i2anc.inverse() )); h2endPt_pcoordsys[ind] = h2endPt_icoordsys[ind] * h2i2anc * path2anc.inverse(); @@ -151,7 +151,7 @@ sp_conn_end_move_compensate(NR::Matrix const */*mp*/, SPItem */*moved_item*/, // TODO: This triggering of makeInvalidPath could be cleaned up to be // another option passed to move_compensate. static void -sp_conn_end_shape_move_compensate(NR::Matrix const *mp, SPItem *moved_item, +sp_conn_end_shape_move_compensate(Geom::Matrix const *mp, SPItem *moved_item, SPPath *const path) { if (path->connEndPair.isAutoRoutingConn()) { @@ -180,25 +180,25 @@ sp_conn_adjust_path(SPPath *const path) sp_conn_end_move_compensate(NULL, NULL, path, updatePathRepr); } -static NR::Point -calc_bbox_conn_pt(NR::Rect const &bbox, NR::Point const &p) +static Geom::Point +calc_bbox_conn_pt(Geom::Rect const &bbox, Geom::Point const &p) { - using NR::X; - using NR::Y; - NR::Point const ctr(bbox.midpoint()); - NR::Point const lengths(bbox.dimensions()); + using Geom::X; + using Geom::Y; + Geom::Point const ctr(bbox.midpoint()); + Geom::Point const lengths(bbox.dimensions()); if ( ctr == p ) { /* Arbitrarily choose centre of right edge. */ - return NR::Point(ctr[X] + .5 * lengths[X], + return Geom::Point(ctr[X] + .5 * lengths[X], ctr[Y]); } - NR::Point const cp( p - ctr ); - NR::Dim2 const edgeDim = ( ( fabs(lengths[Y] * cp[X]) < + Geom::Point const cp( p - ctr ); + Geom::Dim2 const edgeDim = ( ( fabs(lengths[Y] * cp[X]) < fabs(lengths[X] * cp[Y]) ) ? Y : X ); - NR::Dim2 const otherDim = (NR::Dim2) !edgeDim; - NR::Point offset; + Geom::Dim2 const otherDim = (Geom::Dim2) !edgeDim; + Geom::Point offset; offset[edgeDim] = (signed_one(cp[edgeDim]) * lengths[edgeDim]); offset[otherDim] = (lengths[edgeDim] @@ -221,7 +221,7 @@ static double signed_one(double const x) } static void -change_endpts(SPCurve *const curve, NR::Point const h2endPt[2]) +change_endpts(SPCurve *const curve, Geom::Point const h2endPt[2]) { #if 0 curve->reset(); diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index ec60251fc..dcaa59ea0 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -352,11 +352,11 @@ sp_flowtext_print(SPItem *item, SPPrintContext *ctx) NRRect pbox; sp_item_invoke_bbox(item, &pbox, Geom::identity(), TRUE); NRRect bbox; - boost::optional<NR::Rect> bbox_maybe = sp_item_bbox_desktop(item); + boost::optional<Geom::Rect> bbox_maybe = sp_item_bbox_desktop(item); if (!bbox_maybe) { return; } - bbox = NRRect(*bbox_maybe); + bbox = NRRect(from_2geom(*bbox_maybe)); NRRect dbox; dbox.x0 = 0.0; diff --git a/src/sp-gradient-test.h b/src/sp-gradient-test.h index b8645155e..b41ac5b9b 100644 --- a/src/sp-gradient-test.h +++ b/src/sp-gradient-test.h @@ -8,7 +8,7 @@ #include "sp-gradient.h" #include "svg/svg.h" #include "xml/repr.h" - +#include <2geom/transforms.h> class SPGradientTest : public DocumentUsingTest { @@ -56,7 +56,7 @@ public: SP_OBJECT(gr)->document = _doc; sp_object_set(SP_OBJECT(gr), SP_ATTR_GRADIENTTRANSFORM, "translate(5, 8)"); - TS_ASSERT_EQUALS( gr->gradientTransform, NR::Matrix(NR::translate(5, 8)) ); + TS_ASSERT_EQUALS( gr->gradientTransform, NR::Matrix(Geom::Translate(5, 8)) ); sp_object_set(SP_OBJECT(gr), SP_ATTR_GRADIENTTRANSFORM, ""); TS_ASSERT_EQUALS( gr->gradientTransform, NR::identity() ); diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 1fe0d2218..3383de8c8 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -24,8 +24,7 @@ #include <libnr/nr-matrix-fns.h> #include <libnr/nr-matrix-ops.h> #include <libnr/nr-matrix-scale-ops.h> -#include <libnr/nr-matrix-translate-ops.h> -#include "libnr/nr-scale-translate-ops.h" +#include <2geom/transforms.h> #include <sigc++/functors/ptr_fun.h> #include <sigc++/adaptors/bind.h> @@ -1253,9 +1252,9 @@ NR::Matrix sp_gradient_get_g2d_matrix(SPGradient const *gr, NR::Matrix const &ctm, NR::Rect const &bbox) { if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { - return ( NR::scale(bbox.dimensions()) - * NR::translate(bbox.min()) - * ctm ); + return ( Geom::Scale(bbox.dimensions()) + * Geom::Translate(bbox.min()) + * Geom::Matrix(ctm) ); } else { return ctm; } @@ -1266,9 +1265,9 @@ sp_gradient_get_gs2d_matrix(SPGradient const *gr, NR::Matrix const &ctm, NR::Rec { if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { return ( gr->gradientTransform - * NR::scale(bbox.dimensions()) - * NR::translate(bbox.min()) - * ctm ); + * Geom::Scale(bbox.dimensions()) + * Geom::Translate(bbox.min()) + * Geom::Matrix(ctm) ); } else { return gr->gradientTransform * ctm; } @@ -1281,8 +1280,8 @@ sp_gradient_set_gs2d_matrix(SPGradient *gr, NR::Matrix const &ctm, gr->gradientTransform = gs2d * ctm.inverse(); if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX ) { gr->gradientTransform = ( gr->gradientTransform - / NR::translate(bbox.min()) - / NR::scale(bbox.dimensions()) ); + * Geom::Translate(-bbox.min()) + * Geom::Scale(bbox.dimensions()).inverse() ); } gr->gradientTransform_set = TRUE; diff --git a/src/sp-image.cpp b/src/sp-image.cpp index a3112bd03..57f8804d9 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -76,7 +76,7 @@ static void sp_image_print (SPItem * item, SPPrintContext *ctx); static gchar * sp_image_description (SPItem * item); static void sp_image_snappoints(SPItem const *item, SnapPointsIter p); static NRArenaItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); -static NR::Matrix sp_image_set_transform (SPItem *item, NR::Matrix const &xform); +static Geom::Matrix sp_image_set_transform (SPItem *item, Geom::Matrix const &xform); static void sp_image_set_curve(SPImage *image); @@ -1327,41 +1327,41 @@ static void sp_image_snappoints(SPItem const *item, SnapPointsIter p) * Transform x, y, set x, y, clear translation */ -static NR::Matrix -sp_image_set_transform(SPItem *item, NR::Matrix const &xform) +static Geom::Matrix +sp_image_set_transform(SPItem *item, Geom::Matrix const &xform) { SPImage *image = SP_IMAGE(item); /* Calculate position in parent coords. */ - NR::Point pos( NR::Point(image->x.computed, image->y.computed) * xform ); + Geom::Point pos( Geom::Point(image->x.computed, image->y.computed) * xform ); /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ - NR::Matrix ret(NR::transform(xform)); - NR::Point const scale(hypot(ret[0], ret[1]), + Geom::Matrix ret(Geom::Matrix(xform).without_translation()); + Geom::Point const scale(hypot(ret[0], ret[1]), hypot(ret[2], ret[3])); if ( scale[NR::X] > 1e-9 ) { - ret[0] /= scale[NR::X]; - ret[1] /= scale[NR::X]; + ret[0] /= scale[Geom::X]; + ret[1] /= scale[Geom::X]; } else { ret[0] = 1.0; ret[1] = 0.0; } if ( scale[NR::Y] > 1e-9 ) { - ret[2] /= scale[NR::Y]; - ret[3] /= scale[NR::Y]; + ret[2] /= scale[Geom::Y]; + ret[3] /= scale[Geom::Y]; } else { ret[2] = 0.0; ret[3] = 1.0; } - image->width = image->width.computed * scale[NR::X]; - image->height = image->height.computed * scale[NR::Y]; + image->width = image->width.computed * scale[Geom::X]; + image->height = image->height.computed * scale[Geom::Y]; /* Find position in item coords */ pos = pos * ret.inverse(); - image->x = pos[NR::X]; - image->y = pos[NR::Y]; + image->x = pos[Geom::X]; + image->y = pos[Geom::Y]; item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 123fe7330..45410960c 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -66,7 +66,7 @@ static void sp_group_set(SPObject *object, unsigned key, char const *value); static void sp_group_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags); static void sp_group_print (SPItem * item, SPPrintContext *ctx); static gchar * sp_group_description (SPItem * item); -static NR::Matrix sp_group_set_transform(SPItem *item, NR::Matrix const &xform); +static Geom::Matrix sp_group_set_transform(SPItem *item, Geom::Matrix const &xform); static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); static void sp_group_hide (SPItem * item, unsigned int key); static void sp_group_snappoints (SPItem const *item, SnapPointsIter p); @@ -290,15 +290,15 @@ static gchar * sp_group_description (SPItem * item) return SP_GROUP(item)->group->getDescription(); } -static NR::Matrix -sp_group_set_transform(SPItem *item, NR::Matrix const &xform) +static Geom::Matrix +sp_group_set_transform(SPItem *item, Geom::Matrix const &xform) { Inkscape::Selection *selection = sp_desktop_selection(inkscape_active_desktop()); persp3d_split_perspectives_according_to_selection(selection); - NR::Matrix last_trans; + Geom::Matrix last_trans; sp_svg_transform_read(SP_OBJECT_REPR(item)->attribute("transform"), &last_trans); - NR::Matrix inc_trans = last_trans.inverse()*xform; + Geom::Matrix inc_trans = last_trans.inverse()*xform; std::list<Persp3D *> plist = selection->perspList(); for (std::list<Persp3D *>::iterator i = plist.begin(); i != plist.end(); ++i) { @@ -702,7 +702,7 @@ void CGroup::onModified(guint flags) { void CGroup::calculateBBox(NRRect *bbox, Geom::Matrix const &transform, unsigned const flags) { - boost::optional<NR::Rect> dummy_bbox; + boost::optional<Geom::Rect> dummy_bbox; GSList *l = _group->childList(false, SPObject::ActionBBox); while (l) { @@ -837,7 +837,9 @@ sp_group_update_patheffect (SPLPEItem *lpeitem, bool write) for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); it++) { LivePathEffectObject *lpeobj = (*it)->lpeobject; - lpeobj->lpe->doBeforeEffect(lpeitem); + if (lpeobj->get_lpe()) { + lpeobj->get_lpe()->doBeforeEffect(lpeitem); + } } sp_group_perform_patheffect(SP_GROUP(lpeitem), SP_GROUP(lpeitem)); diff --git a/src/sp-item-notify-moveto.cpp b/src/sp-item-notify-moveto.cpp index 391766fb6..a51674c3a 100644 --- a/src/sp-item-notify-moveto.cpp +++ b/src/sp-item-notify-moveto.cpp @@ -3,7 +3,7 @@ */ #include <sp-item.h> -#include <libnr/nr-matrix-translate-ops.h> +#include <2geom/transforms.h> #include <sp-guide.h> #include <sp-item-rm-unsatisfied-cns.h> using std::vector; @@ -20,11 +20,11 @@ void sp_item_notify_moveto(SPItem &item, SPGuide const &mv_g, int const snappoin { g_return_if_fail(SP_IS_ITEM(&item)); g_return_if_fail( unsigned(snappoint_ix) < 8 ); - NR::Point const dir( mv_g.normal_to_line ); + Geom::Point const dir( mv_g.normal_to_line ); double const dir_lensq(dot(dir, dir)); g_return_if_fail( dir_lensq != 0 ); - std::vector<NR::Point> snappoints; + std::vector<Geom::Point> snappoints; sp_item_snappoints(&item, true, SnapPointsIter(snappoints)); g_return_if_fail( snappoint_ix < int(snappoints.size()) ); @@ -39,7 +39,7 @@ void sp_item_notify_moveto(SPItem &item, SPGuide const &mv_g, int const snappoin pos0 + s * dot(dir, dir) = position. s * lensq(dir) = position - pos0. s = (position - pos0) / dot(dir, dir). */ - NR::translate const tr( ( position - pos0 ) + Geom::Translate const tr( ( position - pos0 ) * ( dir / dir_lensq ) ); sp_item_set_i2d_affine(&item, sp_item_i2d_affine(&item) * tr); /// \todo Reget snappoints, check satisfied. diff --git a/src/sp-item-rm-unsatisfied-cns.cpp b/src/sp-item-rm-unsatisfied-cns.cpp index f3e231ddc..d10e1d543 100644 --- a/src/sp-item-rm-unsatisfied-cns.cpp +++ b/src/sp-item-rm-unsatisfied-cns.cpp @@ -14,7 +14,7 @@ void sp_item_rm_unsatisfied_cns(SPItem &item) if (item.constraints.empty()) { return; } - std::vector<NR::Point> snappoints; + std::vector<Geom::Point> snappoints; sp_item_snappoints(&item, true, SnapPointsIter(snappoints)); for (unsigned i = item.constraints.size(); i--;) { g_assert( i < item.constraints.size() ); diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index 0d9118ac9..3b0b1e054 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -7,24 +7,16 @@ * Lauris Kaplinski <lauris@kaplinski.com> * Frank Felfe <innerspace@iname.com> * bulia byak <buliabyak@gmail.com> + * Johan Engelen <goejendaagh@zonnet.nl> * - * Copyright (C) 1999-2005 authors + * Copyright (C) 1999-2008 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <libnr/nr-matrix-ops.h> -#include "libnr/nr-matrix-rotate-ops.h" -#include "libnr/nr-matrix-scale-ops.h" -#include "libnr/nr-matrix-translate-ops.h" +#include <2geom/transforms.h> #include "sp-item.h" -static NR::translate inverse(NR::translate const m) -{ - /* TODO: Move this to nr-matrix-fns.h or the like. */ - return NR::translate(-m[0], -m[1]); -} - void sp_item_rotate_rel(SPItem *item, Geom::Rotate const &rotation) { @@ -46,7 +38,7 @@ sp_item_rotate_rel(SPItem *item, Geom::Rotate const &rotation) void sp_item_scale_rel (SPItem *item, Geom::Scale const &scale) { - boost::optional<NR::Rect> bbox = sp_item_bbox_desktop(item); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(item); if (bbox) { Geom::Translate const s(bbox->midpoint()); // use getCenter? sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * s.inverse() * scale * s); @@ -86,29 +78,29 @@ preference value passed to it. Has to solve a quadratic equation to make sure the goal is met exactly and the stroke scaling is obeyed. */ -NR::Matrix -get_scale_transform_with_stroke (NR::Rect &bbox_param, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) +Geom::Matrix +get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) { - NR::Rect bbox (bbox_param); + Geom::Rect bbox (bbox_param); - NR::Matrix p2o = NR::Matrix (NR::translate (-bbox.min())); - NR::Matrix o2n = NR::Matrix (NR::translate (x0, y0)); + Geom::Matrix p2o = Geom::Translate (-bbox.min()); + Geom::Matrix o2n = Geom::Translate (x0, y0); - NR::Matrix scale = NR::Matrix (NR::scale (1, 1)); // scale component - NR::Matrix unbudge = NR::Matrix (NR::translate (0, 0)); // move component to compensate for the drift caused by stroke width change + Geom::Matrix scale = Geom::Scale (1, 1); // scale component + Geom::Matrix unbudge = Geom::Translate (0, 0); // move component to compensate for the drift caused by stroke width change - gdouble w0 = bbox.extent(NR::X); // will return a value >= 0, as required further down the road - gdouble h0 = bbox.extent(NR::Y); + gdouble w0 = bbox[Geom::X].extent(); // will return a value >= 0, as required further down the road + gdouble h0 = bbox[Geom::Y].extent(); gdouble w1 = x1 - x0; // can have any sign gdouble h1 = y1 - y0; gdouble r0 = strokewidth; if (bbox.isEmpty()) { - NR::Matrix move = NR::Matrix(NR::translate(x0 - bbox.min()[NR::X], y0 - bbox.min()[NR::Y])); + Geom::Matrix move = Geom::Translate(x0 - bbox.min()[Geom::X], y0 - bbox.min()[Geom::Y]); return (move); // cannot scale from empty boxes at all, so only translate } - NR::Matrix direct = NR::Matrix (NR::scale(w1 / w0, h1 / h0)); + Geom::Matrix direct = Geom::Scale(w1 / w0, h1 / h0); if (fabs(w0 - r0) < 1e-6 || fabs(h0 - r0) < 1e-6 || (!transform_stroke && (fabs(w1 - r0) < 1e-6 || fabs(h1 - r0) < 1e-6))) { return (p2o * direct * o2n); // can't solve the equation: one of the dimensions is equal to stroke width, so return the straightforward scaler @@ -127,7 +119,7 @@ get_scale_transform_with_stroke (NR::Rect &bbox_param, gdouble strokewidth, bool gdouble ratio_x = (w1 - r0) / (w0 - r0); gdouble ratio_y = (h1 - r0) / (h0 - r0); - NR::Matrix direct_constant_r = NR::Matrix (NR::scale(flip_x * ratio_x, flip_y * ratio_y)); + Geom::Matrix direct_constant_r = Geom::Scale(flip_x * ratio_x, flip_y * ratio_y); if (transform_stroke && r0 != 0 && r0 != NR_HUGE) { // there's stroke, and we need to scale it // These coefficients are obtained from the assumption that scaling applies to the @@ -148,8 +140,8 @@ get_scale_transform_with_stroke (NR::Rect &bbox_param, gdouble strokewidth, bool // Here we also need the absolute values of w0, w1, h0, h1, and r1 gdouble scale_x = (w1 - r1)/(w0 - r0); gdouble scale_y = (h1 - r1)/(h0 - r0); - scale *= NR::scale(flip_x * scale_x, flip_y * scale_y); - unbudge *= NR::translate (-flip_x * 0.5 * (r0 * scale_x - r1), -flip_y * 0.5 * (r0 * scale_y - r1)); + scale *= Geom::Scale(flip_x * scale_x, flip_y * scale_y); + unbudge *= Geom::Translate (-flip_x * 0.5 * (r0 * scale_x - r1), -flip_y * 0.5 * (r0 * scale_y - r1)); } else { scale *= direct; } @@ -158,15 +150,15 @@ get_scale_transform_with_stroke (NR::Rect &bbox_param, gdouble strokewidth, bool scale *= direct; } else {// nonscaling strokewidth scale *= direct_constant_r; - unbudge *= NR::translate (flip_x * 0.5 * r0 * (1 - ratio_x), flip_y * 0.5 * r0 * (1 - ratio_y)); + unbudge *= Geom::Translate (flip_x * 0.5 * r0 * (1 - ratio_x), flip_y * 0.5 * r0 * (1 - ratio_y)); } } return (p2o * scale * unbudge * o2n); } -NR::Rect -get_visual_bbox (boost::optional<NR::Rect> const &initial_geom_bbox, NR::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke) +Geom::Rect +get_visual_bbox (boost::optional<Geom::Rect> const &initial_geom_bbox, Geom::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke) { g_assert(initial_geom_bbox); @@ -174,23 +166,23 @@ get_visual_bbox (boost::optional<NR::Rect> const &initial_geom_bbox, NR::Matrix // Find the new geometric bounding box; Do this by transforming each corner of // the initial geometric bounding box individually and fitting a new boundingbox // around the transformerd corners - NR::Point const p0 = initial_geom_bbox->corner(0) * abs_affine; - NR::Rect new_geom_bbox = NR::Rect(p0, p0); + Geom::Point const p0 = Geom::Point(initial_geom_bbox->corner(0)) * abs_affine; + Geom::Rect new_geom_bbox(p0, p0); for (unsigned i = 1 ; i < 4 ; i++) { - new_geom_bbox.expandTo(initial_geom_bbox->corner(i) * abs_affine); + new_geom_bbox.expandTo(Geom::Point(initial_geom_bbox->corner(i)) * abs_affine); } - NR::Rect new_visual_bbox = new_geom_bbox; + Geom::Rect new_visual_bbox = new_geom_bbox; if (initial_strokewidth > 0 && initial_strokewidth < NR_HUGE) { if (transform_stroke) { // scale stroke by: sqrt (((w1-r0)/(w0-r0))*((h1-r0)/(h0-r0))) (for visual bboxes, see get_scale_transform_with_stroke) // equals scaling by: sqrt ((w1/w0)*(h1/h0)) for geometrical bboxes // equals scaling by: sqrt (area1/area0) for geometrical bboxes gdouble const new_strokewidth = initial_strokewidth * sqrt (new_geom_bbox.area() / initial_geom_bbox->area()); - new_visual_bbox.growBy(0.5 * new_strokewidth); + new_visual_bbox.expandBy(0.5 * new_strokewidth); } else { // Do not transform the stroke - new_visual_bbox.growBy(0.5 * initial_strokewidth); + new_visual_bbox.expandBy(0.5 * initial_strokewidth); } } diff --git a/src/sp-item-transform.h b/src/sp-item-transform.h index 8ce21fb32..884732abe 100644 --- a/src/sp-item-transform.h +++ b/src/sp-item-transform.h @@ -9,8 +9,8 @@ void sp_item_scale_rel (SPItem *item, Geom::Scale const &scale); void sp_item_skew_rel (SPItem *item, double skewX, double skewY); void sp_item_move_rel(SPItem *item, Geom::Translate const &tr); -NR::Matrix get_scale_transform_with_stroke (NR::Rect &bbox, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); -NR::Rect get_visual_bbox (boost::optional<NR::Rect> const &initial_geom_bbox, NR::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke); +Geom::Matrix get_scale_transform_with_stroke (Geom::Rect const &bbox, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); +Geom::Rect get_visual_bbox (boost::optional<Geom::Rect> const &initial_geom_bbox, Geom::Matrix const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke); #endif /* !SP_ITEM_TRANSFORM_H */ diff --git a/src/sp-item-update-cns.cpp b/src/sp-item-update-cns.cpp index 82ff0c458..55846f4b7 100644 --- a/src/sp-item-update-cns.cpp +++ b/src/sp-item-update-cns.cpp @@ -9,7 +9,7 @@ using std::vector; void sp_item_update_cns(SPItem &item, SPDesktop const &desktop) { - std::vector<NR::Point> snappoints; + std::vector<Geom::Point> snappoints; sp_item_snappoints(&item, true, SnapPointsIter(snappoints)); /* TODO: Implement the ordering. */ vector<SPGuideConstraint> found_cns; diff --git a/src/sp-item-update-cns.h b/src/sp-item-update-cns.h index 74bb1f8cd..4cb6a60b6 100644 --- a/src/sp-item-update-cns.h +++ b/src/sp-item-update-cns.h @@ -1,6 +1,7 @@ #ifndef __SP_ITEM_UPDATE_CNS_H__ #define __SP_ITEM_UPDATE_CNS_H__ #include <forward.h> +#include <2geom/forward.h> void sp_item_update_cns(SPItem &item, SPDesktop const &desktop); diff --git a/src/sp-item.cpp b/src/sp-item.cpp index b412353e1..c993a6163 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -67,10 +67,12 @@ #include "algorithms/find-last-if.h" #include "util/reverse-list.h" #include <2geom/rect.h> +#include <2geom/matrix.h> #include <2geom/transforms.h> #include "xml/repr.h" #include "extract-uri.h" +#include "helper/geom.h" #include "live_effects/lpeobject.h" #include "live_effects/effect.h" @@ -159,7 +161,7 @@ void SPItem::init() { this->_is_evaluated = true; this->_evaluated_status = StatusUnknown; - this->transform = NR::identity(); + this->transform = Geom::identity(); this->display = NULL; @@ -175,7 +177,7 @@ void SPItem::init() { this->avoidRef = new SPAvoidRef(this); - new (&this->_transformed_signal) sigc::signal<void, NR::Matrix const *, SPItem *>(); + new (&this->_transformed_signal) sigc::signal<void, Geom::Matrix const *, SPItem *>(); } bool SPItem::isVisibleAndUnlocked() const { @@ -288,13 +290,13 @@ SPItem::setExplicitlyHidden(bool const val) { * Sets the transform_center_x and transform_center_y properties to retain the rotation centre */ void -SPItem::setCenter(NR::Point object_centre) { - boost::optional<NR::Rect> bbox = getBounds(sp_item_i2d_affine(this)); +SPItem::setCenter(Geom::Point object_centre) { + boost::optional<Geom::Rect> bbox = getBounds(sp_item_i2d_affine(this)); if (bbox) { - transform_center_x = object_centre[NR::X] - bbox->midpoint()[NR::X]; + transform_center_x = object_centre[Geom::X] - bbox->midpoint()[Geom::X]; if (fabs(transform_center_x) < 1e-5) // rounding error transform_center_x = 0; - transform_center_y = object_centre[NR::Y] - bbox->midpoint()[NR::Y]; + transform_center_y = object_centre[Geom::Y] - bbox->midpoint()[Geom::Y]; if (fabs(transform_center_y) < 1e-5) // rounding error transform_center_y = 0; } @@ -311,7 +313,7 @@ bool SPItem::isCenterSet() { } Geom::Point SPItem::getCenter() const { - boost::optional<NR::Rect> bbox = getBounds(sp_item_i2d_affine(this)); + boost::optional<Geom::Rect> bbox = getBounds(sp_item_i2d_affine(this)); if (bbox) { return to_2geom(bbox->midpoint()) + Geom::Point (this->transform_center_x, this->transform_center_y); } else { @@ -455,11 +457,11 @@ sp_item_set(SPObject *object, unsigned key, gchar const *value) switch (key) { case SP_ATTR_TRANSFORM: { - NR::Matrix t; + Geom::Matrix t; if (value && sp_svg_transform_read(value, &t)) { sp_item_set_item_transform(item, t); } else { - sp_item_set_item_transform(item, NR::identity()); + sp_item_set_item_transform(item, Geom::identity()); } break; } @@ -553,7 +555,7 @@ clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item) } if (SP_IS_CLIPPATH(clip)) { NRRect bbox; - sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + sp_item_invoke_bbox(item, &bbox, Geom::identity(), TRUE); for (SPItemView *v = item->display; v != NULL; v = v->next) { if (!v->arenaitem->key) { NR_ARENA_ITEM_SET_KEY(v->arenaitem, sp_item_display_key_new(3)); @@ -581,7 +583,7 @@ mask_ref_changed(SPObject *old_mask, SPObject *mask, SPItem *item) } if (SP_IS_MASK(mask)) { NRRect bbox; - sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + sp_item_invoke_bbox(item, &bbox, Geom::identity(), TRUE); for (SPItemView *v = item->display; v != NULL; v = v->next) { if (!v->arenaitem->key) { NR_ARENA_ITEM_SET_KEY(v->arenaitem, sp_item_display_key_new(3)); @@ -617,7 +619,7 @@ sp_item_update(SPObject *object, SPCtx *ctx, guint flags) if ( clip_path || mask ) { NRRect bbox; - sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + sp_item_invoke_bbox(item, &bbox, Geom::identity(), TRUE); if (clip_path) { for (SPItemView *v = item->display; v != NULL; v = v->next) { sp_clippath_set_bbox(clip_path, NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); @@ -641,8 +643,8 @@ sp_item_update(SPObject *object, SPCtx *ctx, guint flags) /* Update bounding box data used by filters */ if (item->style->filter.set && item->display) { NRRect item_bbox; - sp_item_invoke_bbox(item, &item_bbox, NR::identity(), TRUE, SPItem::GEOMETRIC_BBOX); - boost::optional<NR::Rect> i_bbox = item_bbox; + sp_item_invoke_bbox(item, &item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX); + boost::optional<Geom::Rect> i_bbox = item_bbox; SPItemView *itemview = item->display; do { @@ -719,24 +721,24 @@ sp_item_write(SPObject *const object, Inkscape::XML::Document *xml_doc, Inkscape return repr; } -boost::optional<NR::Rect> SPItem::getBounds(NR::Matrix const &transform, +boost::optional<Geom::Rect> SPItem::getBounds(Geom::Matrix const &transform, SPItem::BBoxType type, unsigned int /*dkey*/) const { - boost::optional<NR::Rect> r; + boost::optional<Geom::Rect> r; sp_item_invoke_bbox_full(this, r, transform, type, TRUE); return r; } void -sp_item_invoke_bbox(SPItem const *item, boost::optional<NR::Rect> &bbox, NR::Matrix const &transform, unsigned const clear, SPItem::BBoxType type) +sp_item_invoke_bbox(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type) { sp_item_invoke_bbox_full(item, bbox, transform, type, clear); } -// DEPRECATED to phase out the use of NRRect in favor of boost::optional<NR::Rect> +// DEPRECATED to phase out the use of NRRect in favor of boost::optional<Geom::Rect> void -sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const clear, SPItem::BBoxType type) +sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type) { sp_item_invoke_bbox_full(item, bbox, transform, type, clear); } @@ -746,16 +748,16 @@ sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transfor * transform and the flags to the actual bbox methods. Note that many of subclasses (e.g. groups, * clones), in turn, call this function in their bbox methods. */ void -sp_item_invoke_bbox_full(SPItem const *item, boost::optional<NR::Rect> &bbox, NR::Matrix const &transform, unsigned const flags, unsigned const clear) +sp_item_invoke_bbox_full(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear) { g_assert(item != NULL); g_assert(SP_IS_ITEM(item)); if (clear) { - bbox = boost::optional<NR::Rect>(); + bbox = boost::optional<Geom::Rect>(); } - // TODO: replace NRRect by NR::Rect, for all SPItemClasses, and for SP_CLIPPATH + // TODO: replace NRRect by Geom::Rect, for all SPItemClasses, and for SP_CLIPPATH NRRect temp_bbox; temp_bbox.x0 = temp_bbox.y0 = NR_HUGE; @@ -809,11 +811,11 @@ sp_item_invoke_bbox_full(SPItem const *item, boost::optional<NR::Rect> &bbox, NR } // transform the expansions by the item's transform: - NR::Matrix i2d(sp_item_i2d_affine (item)); - dx0 *= NR::expansionX(i2d); - dx1 *= NR::expansionX(i2d); - dy0 *= NR::expansionY(i2d); - dy1 *= NR::expansionY(i2d); + Geom::Matrix i2d(sp_item_i2d_affine (item)); + dx0 *= i2d.expansionX(); + dx1 *= i2d.expansionX(); + dy0 *= i2d.expansionY(); + dy1 *= i2d.expansionY(); // expand the bbox temp_bbox.x0 += dx0; @@ -835,26 +837,26 @@ sp_item_invoke_bbox_full(SPItem const *item, boost::optional<NR::Rect> &bbox, NR // or it has explicitely been set to be like this (e.g. in sp_shape_bbox) // When x0 > x1 or y0 > y1, the bbox is considered to be "nothing", although it has not been - // explicitely defined this way for NRRects (as opposed to boost::optional<NR::Rect>) + // explicitely defined this way for NRRects (as opposed to boost::optional<Geom::Rect>) // So union bbox with nothing = do nothing, just return return; } - // Do not use temp_bbox.upgrade() here, because it uses a test that returns an empty boost::optional<NR::Rect>() + // Do not use temp_bbox.upgrade() here, because it uses a test that returns an empty boost::optional<Geom::Rect>() // for any rectangle with zero area. The geometrical bbox of for example a vertical line - // would therefore be translated into empty boost::optional<NR::Rect>() (see bug https://bugs.launchpad.net/inkscape/+bug/168684) - boost::optional<NR::Rect> temp_bbox_new = NR::Rect(NR::Point(temp_bbox.x0, temp_bbox.y0), NR::Point(temp_bbox.x1, temp_bbox.y1)); + // would therefore be translated into empty boost::optional<Geom::Rect>() (see bug https://bugs.launchpad.net/inkscape/+bug/168684) + boost::optional<Geom::Rect> temp_bbox_new = Geom::Rect(Geom::Point(temp_bbox.x0, temp_bbox.y0), Geom::Point(temp_bbox.x1, temp_bbox.y1)); - bbox = NR::union_bounds(bbox, temp_bbox_new); + bbox = Geom::unify(bbox, temp_bbox_new); } -// DEPRECATED to phase out the use of NRRect in favor of boost::optional<NR::Rect> +// DEPRECATED to phase out the use of NRRect in favor of boost::optional<Geom::Rect> /** Calls \a item's subclass' bounding box method; clips it by the bbox of clippath, if any; and * unions the resulting bbox with \a bbox. If \a clear is true, empties \a bbox first. Passes the * transform and the flags to the actual bbox methods. Note that many of subclasses (e.g. groups, * clones), in turn, call this function in their bbox methods. */ void -sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags, unsigned const clear) +sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear) { g_assert(item != NULL); g_assert(SP_IS_ITEM(item)); @@ -922,9 +924,9 @@ sp_item_bbox_desktop(SPItem *item, NRRect *bbox, SPItem::BBoxType type) sp_item_invoke_bbox(item, bbox, sp_item_i2d_affine(item), TRUE, type); } -boost::optional<NR::Rect> sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type) +boost::optional<Geom::Rect> sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type) { - boost::optional<NR::Rect> rect = boost::optional<NR::Rect>(); + boost::optional<Geom::Rect> rect = boost::optional<Geom::Rect>(); sp_item_invoke_bbox(item, rect, sp_item_i2d_affine(item), TRUE, type); return rect; } @@ -936,16 +938,16 @@ static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p) * We don't know what shape we could be dealing with here, so we'll just * return the corners of the bounding box */ - boost::optional<NR::Rect> bbox = item->getBounds(sp_item_i2d_affine(item)); + boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2d_affine(item)); if (bbox) { - NR::Point p1, p2; + Geom::Point p1, p2; p1 = bbox->min(); p2 = bbox->max(); *p = p1; - *p = NR::Point(p1[NR::X], p2[NR::Y]); + *p = Geom::Point(p1[Geom::X], p2[Geom::Y]); *p = p2; - *p = NR::Point(p1[NR::Y], p2[NR::X]); + *p = Geom::Point(p1[Geom::Y], p2[Geom::X]); } } @@ -977,14 +979,14 @@ void sp_item_snappoints(SPItem const *item, bool includeItemCenter, SnapPointsIt // obj is a group object, the children are the actual clippers for (SPObject *child = (*o)->children ; child ; child = child->next) { if (SP_IS_ITEM(child)) { - std::vector<NR::Point> p_clip_or_mask; + std::vector<Geom::Point> p_clip_or_mask; // Please note the recursive call here! sp_item_snappoints(SP_ITEM(child), includeItemCenter, SnapPointsIter(p_clip_or_mask)); // Take into account the transformation of the item being clipped or masked - for (std::vector<NR::Point>::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) { + for (std::vector<Geom::Point>::const_iterator p_orig = p_clip_or_mask.begin(); p_orig != p_clip_or_mask.end(); p_orig++) { // All snappoints are in desktop coordinates, but the item's transformation is // in document coordinates. Hence the awkward construction below - *p = (*p_orig) * from_2geom(matrix_to_desktop (matrix_from_desktop (item->transform, item), item)); + *p = (*p_orig) * matrix_to_desktop (matrix_from_desktop (item->transform, item), item); } } } @@ -1101,7 +1103,7 @@ sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags) // Update bbox, in case the clip uses bbox units NRRect bbox; - sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + sp_item_invoke_bbox(item, &bbox, Geom::identity(), TRUE); sp_clippath_set_bbox(SP_CLIPPATH(cp), clip_key, &bbox); SP_OBJECT(cp)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } @@ -1120,14 +1122,14 @@ sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags) // Update bbox, in case the mask uses bbox units NRRect bbox; - sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + sp_item_invoke_bbox(item, &bbox, Geom::identity(), TRUE); sp_mask_set_bbox(SP_MASK(mask), mask_key, &bbox); SP_OBJECT(mask)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } NR_ARENA_ITEM_SET_DATA(ai, item); NRRect item_bbox; - sp_item_invoke_bbox(item, &item_bbox, NR::identity(), TRUE, SPItem::GEOMETRIC_BBOX); - boost::optional<NR::Rect> i_bbox = item_bbox; + sp_item_invoke_bbox(item, &item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX); + boost::optional<Geom::Rect> i_bbox = item_bbox; nr_arena_item_set_item_bbox(ai, i_bbox); } @@ -1175,7 +1177,7 @@ sp_item_invoke_hide(SPItem *item, unsigned key) // Adjusters void -sp_item_adjust_pattern (SPItem *item, NR::Matrix const &postmul, bool set) +sp_item_adjust_pattern (SPItem *item, Geom::Matrix const &postmul, bool set) { SPStyle *style = SP_OBJECT_STYLE (item); @@ -1198,7 +1200,7 @@ sp_item_adjust_pattern (SPItem *item, NR::Matrix const &postmul, bool set) } void -sp_item_adjust_gradient (SPItem *item, NR::Matrix const &postmul, bool set) +sp_item_adjust_gradient (SPItem *item, Geom::Matrix const &postmul, bool set) { SPStyle *style = SP_OBJECT_STYLE (item); @@ -1255,13 +1257,13 @@ sp_item_adjust_stroke (SPItem *item, gdouble ex) /** * Find out the inverse of previous transform of an item (from its repr) */ -NR::Matrix +Geom::Matrix sp_item_transform_repr (SPItem *item) { - NR::Matrix t_old(NR::identity()); + Geom::Matrix t_old(Geom::identity()); gchar const *t_attr = SP_OBJECT_REPR(item)->attribute("transform"); if (t_attr) { - NR::Matrix t; + Geom::Matrix t; if (sp_svg_transform_read(t_attr, &t)) { t_old = t; } @@ -1293,7 +1295,7 @@ sp_item_adjust_stroke_width_recursive(SPItem *item, double expansion) * Recursively adjust rx and ry of rects. */ void -sp_item_adjust_rects_recursive(SPItem *item, NR::Matrix advertized_transform) +sp_item_adjust_rects_recursive(SPItem *item, Geom::Matrix advertized_transform) { if (SP_IS_RECT (item)) { sp_rect_compensate_rxry (SP_RECT(item), advertized_transform); @@ -1309,13 +1311,13 @@ sp_item_adjust_rects_recursive(SPItem *item, NR::Matrix advertized_transform) * Recursively compensate pattern or gradient transform. */ void -sp_item_adjust_paint_recursive (SPItem *item, NR::Matrix advertized_transform, NR::Matrix t_ancestors, bool is_pattern) +sp_item_adjust_paint_recursive (SPItem *item, Geom::Matrix advertized_transform, Geom::Matrix t_ancestors, bool is_pattern) { // _Before_ full pattern/gradient transform: t_paint * t_item * t_ancestors // _After_ full pattern/gradient transform: t_paint_new * t_item * t_ancestors * advertised_transform // By equating these two expressions we get t_paint_new = t_paint * paint_delta, where: - NR::Matrix t_item = sp_item_transform_repr (item); - NR::Matrix paint_delta = t_item * t_ancestors * advertized_transform * t_ancestors.inverse() * t_item.inverse(); + Geom::Matrix t_item = sp_item_transform_repr (item); + Geom::Matrix paint_delta = t_item * t_ancestors * advertized_transform * t_ancestors.inverse() * t_item.inverse(); // Within text, we do not fork gradients, and so must not recurse to avoid double compensation; // also we do not recurse into clones, because a clone's child is the ghost of its original - @@ -1343,7 +1345,7 @@ sp_item_adjust_paint_recursive (SPItem *item, NR::Matrix advertized_transform, N } void -sp_item_adjust_livepatheffect (SPItem *item, NR::Matrix const &postmul, bool set) +sp_item_adjust_livepatheffect (SPItem *item, Geom::Matrix const &postmul, bool set) { if ( !SP_IS_LPE_ITEM(item) ) return; @@ -1362,8 +1364,8 @@ sp_item_adjust_livepatheffect (SPItem *item, NR::Matrix const &postmul, bool set sp_lpe_item_replace_path_effect(lpeitem, lpeobj, new_lpeobj); } - if (lpeobj->lpe) { - Inkscape::LivePathEffect::Effect * effect = lpeobj->lpe; + if (lpeobj->get_lpe()) { + Inkscape::LivePathEffect::Effect * effect = lpeobj->get_lpe(); effect->transform_multiply(postmul, set); } } @@ -1372,14 +1374,14 @@ sp_item_adjust_livepatheffect (SPItem *item, NR::Matrix const &postmul, bool set } /** - * A temporary wrapper for the next function accepting the NR::Matrix - * instead of NR::Matrix + * A temporary wrapper for the next function accepting the Geom::Matrix + * instead of Geom::Matrix */ void -sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const *transform, NR::Matrix const *adv) +sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, Geom::Matrix const *transform, Geom::Matrix const *adv) { if (transform == NULL) - sp_item_write_transform(item, repr, NR::identity(), adv); + sp_item_write_transform(item, repr, Geom::identity(), adv); else sp_item_write_transform(item, repr, *transform, adv); } @@ -1393,14 +1395,14 @@ sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix cons * the repr is updated with the new transform. */ void -sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const &transform, NR::Matrix const *adv, bool compensate) +sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, Geom::Matrix const &transform, Geom::Matrix const *adv, bool compensate) { g_return_if_fail(item != NULL); g_return_if_fail(SP_IS_ITEM(item)); g_return_if_fail(repr != NULL); // calculate the relative transform, if not given by the adv attribute - NR::Matrix advertized_transform; + Geom::Matrix advertized_transform; if (adv != NULL) { advertized_transform = *adv; } else { @@ -1411,7 +1413,7 @@ sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix cons // recursively compensate for stroke scaling, depending on user preference if (prefs_get_int_attribute("options.transform", "stroke", 1) == 0) { - double const expansion = 1. / NR::expansion(advertized_transform); + double const expansion = 1. / advertized_transform.descrim(); sp_item_adjust_stroke_width_recursive(item, expansion); } @@ -1422,28 +1424,28 @@ sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix cons // recursively compensate pattern fill if it's not to be transformed if (prefs_get_int_attribute("options.transform", "pattern", 1) == 0) { - sp_item_adjust_paint_recursive (item, advertized_transform.inverse(), NR::identity(), true); + sp_item_adjust_paint_recursive (item, advertized_transform.inverse(), Geom::identity(), true); } /// \todo FIXME: add the same else branch as for gradients below, to convert patterns to userSpaceOnUse as well /// recursively compensate gradient fill if it's not to be transformed if (prefs_get_int_attribute("options.transform", "gradient", 1) == 0) { - sp_item_adjust_paint_recursive (item, advertized_transform.inverse(), NR::identity(), false); + sp_item_adjust_paint_recursive (item, advertized_transform.inverse(), Geom::identity(), false); } else { // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do // it here _before_ the new transform is set, so as to use the pre-transform bbox - sp_item_adjust_paint_recursive (item, NR::identity(), NR::identity(), false); + sp_item_adjust_paint_recursive (item, Geom::identity(), Geom::identity(), false); } } // endif(compensate) gint preserve = prefs_get_int_attribute("options.preservetransform", "value", 0); - NR::Matrix transform_attr (transform); + Geom::Matrix transform_attr (transform); if ( // run the object's set_transform (i.e. embed transform) only if: ((SPItemClass *) G_OBJECT_GET_CLASS(item))->set_transform && // it does have a set_transform method !preserve && // user did not chose to preserve all transforms !item->clip_ref->getObject() && // the object does not have a clippath !item->mask_ref->getObject() && // the object does not have a mask - !(!transform.is_translation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->getFilter()) + !(!transform.isTranslation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->getFilter()) // the object does not have a filter, or the transform is translation (which is supposed to not affect filters) ) { transform_attr = ((SPItemClass *) G_OBJECT_GET_CLASS(item))->set_transform(item, transform); @@ -1478,7 +1480,7 @@ sp_item_event(SPItem *item, SPEvent *event) * gradients, patterns as sp_item_write_transform does. */ void -sp_item_set_item_transform(SPItem *item, NR::Matrix const &transform) +sp_item_set_item_transform(SPItem *item, Geom::Matrix const &transform) { g_return_if_fail(item != NULL); g_return_if_fail(SP_IS_ITEM(item)); @@ -1536,7 +1538,7 @@ i2i_affine(SPObject const *src, SPObject const *dest) { return i2anc_affine(src, ancestor) * i2anc_affine(dest, ancestor).inverse(); } -NR::Matrix SPItem::getRelativeTransform(SPObject const *dest) const { +Geom::Matrix SPItem::getRelativeTransform(SPObject const *dest) const { return i2i_affine(this, dest); } @@ -1729,7 +1731,7 @@ sp_item_convert_to_guides(SPItem *item) { SPItem::BBoxType bbox_type = (prefs_bbox ==0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - boost::optional<NR::Rect> bbox = sp_item_bbox_desktop(item, bbox_type); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(item, bbox_type); if (!bbox) { g_warning ("Cannot determine item's bounding box during conversion to guides.\n"); return; @@ -1737,10 +1739,10 @@ sp_item_convert_to_guides(SPItem *item) { std::list<std::pair<Geom::Point, Geom::Point> > pts; - NR::Point A((*bbox).min()); - NR::Point C((*bbox).max()); - NR::Point B(A[NR::X], C[NR::Y]); - NR::Point D(C[NR::X], A[NR::Y]); + Geom::Point A((*bbox).min()); + Geom::Point C((*bbox).max()); + Geom::Point B(A[Geom::X], C[Geom::Y]); + Geom::Point D(C[Geom::X], A[Geom::Y]); pts.push_back(std::make_pair(A, B)); pts.push_back(std::make_pair(B, C)); diff --git a/src/sp-item.h b/src/sp-item.h index 76e07e88e..a900c4b87 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -119,7 +119,7 @@ struct SPItem : public SPObject { std::vector<SPGuideConstraint> constraints; - sigc::signal<void, NR::Matrix const *, SPItem *> _transformed_signal; + sigc::signal<void, Geom::Matrix const *, SPItem *> _transformed_signal; void init(); bool isLocked() const; @@ -138,7 +138,7 @@ struct SPItem : public SPObject { void setExplicitlyHidden(bool val); - void setCenter(NR::Point object_centre); + void setCenter(Geom::Point object_centre); void unsetCenter(); bool isCenterSet(); Geom::Point getCenter() const; @@ -147,19 +147,19 @@ struct SPItem : public SPObject { bool isVisibleAndUnlocked(unsigned display_key) const; - NR::Matrix getRelativeTransform(SPObject const *obj) const; + Geom::Matrix getRelativeTransform(SPObject const *obj) const; void raiseOne(); void lowerOne(); void raiseToTop(); void lowerToBottom(); - boost::optional<NR::Rect> getBounds(NR::Matrix const &transform, BBoxType type=APPROXIMATE_BBOX, unsigned int dkey=0) const; + boost::optional<Geom::Rect> getBounds(Geom::Matrix const &transform, BBoxType type=APPROXIMATE_BBOX, unsigned int dkey=0) const; sigc::connection _clip_ref_connection; sigc::connection _mask_ref_connection; - sigc::connection connectTransformed(sigc::slot<void, NR::Matrix const *, SPItem *> slot) { + sigc::connection connectTransformed(sigc::slot<void, Geom::Matrix const *, SPItem *> slot) { return _transformed_signal.connect(slot); } @@ -173,7 +173,7 @@ private: mutable EvaluatedStatus _evaluated_status; }; -typedef std::back_insert_iterator<std::vector<NR::Point> > SnapPointsIter; +typedef std::back_insert_iterator<std::vector<Geom::Point> > SnapPointsIter; /// The SPItem vtable. struct SPItemClass { @@ -198,7 +198,7 @@ struct SPItemClass { void (* snappoints) (SPItem const *item, SnapPointsIter p); /** Apply the transform optimally, and return any residual transformation */ - NR::Matrix (* set_transform)(SPItem *item, NR::Matrix const &transform); + Geom::Matrix (* set_transform)(SPItem *item, Geom::Matrix const &transform); /** Convert the item to guidelines */ void (* convert_to_guides)(SPItem *item); @@ -213,10 +213,10 @@ struct SPItemClass { /* Methods */ -void sp_item_invoke_bbox(SPItem const *item, boost::optional<NR::Rect> &bbox, NR::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); -void sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated)); -void sp_item_invoke_bbox_full(SPItem const *item, boost::optional<NR::Rect> &bbox, NR::Matrix const &transform, unsigned const flags, unsigned const clear); -void sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags, unsigned const clear) __attribute__ ((deprecated)); +void sp_item_invoke_bbox(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); +void sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated)); +void sp_item_invoke_bbox_full(SPItem const *item, boost::optional<Geom::Rect> &bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear); +void sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags, unsigned const clear) __attribute__ ((deprecated)); unsigned sp_item_pos_in_parent(SPItem *item); @@ -230,17 +230,17 @@ void sp_item_invoke_hide(SPItem *item, unsigned int key); void sp_item_snappoints(SPItem const *item, bool includeItemCenter, SnapPointsIter p); -void sp_item_adjust_pattern(SPItem *item, /* NR::Matrix const &premul, */ NR::Matrix const &postmul, bool set = false); -void sp_item_adjust_gradient(SPItem *item, /* NR::Matrix const &premul, */ NR::Matrix const &postmul, bool set = false); +void sp_item_adjust_pattern(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false); +void sp_item_adjust_gradient(SPItem *item, /* Geom::Matrix const &premul, */ Geom::Matrix const &postmul, bool set = false); void sp_item_adjust_stroke(SPItem *item, gdouble ex); void sp_item_adjust_stroke_width_recursive(SPItem *item, gdouble ex); -void sp_item_adjust_paint_recursive(SPItem *item, NR::Matrix advertized_transform, NR::Matrix t_ancestors, bool is_pattern); -void sp_item_adjust_livepatheffect(SPItem *item, NR::Matrix const &postmul, bool set = false); +void sp_item_adjust_paint_recursive(SPItem *item, Geom::Matrix advertized_transform, Geom::Matrix t_ancestors, bool is_pattern); +void sp_item_adjust_livepatheffect(SPItem *item, Geom::Matrix const &postmul, bool set = false); -void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const *transform, NR::Matrix const *adv = NULL); -void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const &transform, NR::Matrix const *adv = NULL, bool compensate = true); +void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, Geom::Matrix const *transform, Geom::Matrix const *adv = NULL); +void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, Geom::Matrix const &transform, Geom::Matrix const *adv = NULL, bool compensate = true); -void sp_item_set_item_transform(SPItem *item, NR::Matrix const &transform); +void sp_item_set_item_transform(SPItem *item, Geom::Matrix const &transform); void sp_item_convert_item_to_guides(SPItem *item); @@ -251,7 +251,7 @@ gint sp_item_event (SPItem *item, SPEvent *event); NRArenaItem *sp_item_get_arenaitem(SPItem *item, unsigned int key); void sp_item_bbox_desktop(SPItem *item, NRRect *bbox, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated)); -boost::optional<NR::Rect> sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); +boost::optional<Geom::Rect> sp_item_bbox_desktop(SPItem *item, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); Geom::Matrix i2anc_affine(SPObject const *item, SPObject const *ancestor); Geom::Matrix i2i_affine(SPObject const *src, SPObject const *dest); diff --git a/src/sp-line.cpp b/src/sp-line.cpp index 1f5c1b181..a3964b171 100644 --- a/src/sp-line.cpp +++ b/src/sp-line.cpp @@ -31,7 +31,7 @@ static void sp_line_set (SPObject *object, unsigned int key, const gchar *value) static Inkscape::XML::Node *sp_line_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); static gchar *sp_line_description (SPItem * item); -static NR::Matrix sp_line_set_transform(SPItem *item, NR::Matrix const &xform); +static Geom::Matrix sp_line_set_transform(SPItem *item, Geom::Matrix const &xform); static void sp_line_update (SPObject *object, SPCtx *ctx, guint flags); static void sp_line_set_shape (SPShape *shape); @@ -188,28 +188,28 @@ sp_line_description(SPItem */*item*/) return g_strdup(_("<b>Line</b>")); } -static NR::Matrix -sp_line_set_transform (SPItem *item, NR::Matrix const &xform) +static Geom::Matrix +sp_line_set_transform (SPItem *item, Geom::Matrix const &xform) { SPLine *line = SP_LINE (item); - NR::Point points[2]; + Geom::Point points[2]; - points[0] = NR::Point(line->x1.computed, line->y1.computed); - points[1] = NR::Point(line->x2.computed, line->y2.computed); + points[0] = Geom::Point(line->x1.computed, line->y1.computed); + points[1] = Geom::Point(line->x2.computed, line->y2.computed); points[0] *= xform; points[1] *= xform; - line->x1.computed = points[0][NR::X]; - line->y1.computed = points[0][NR::Y]; - line->x2.computed = points[1][NR::X]; - line->y2.computed = points[1][NR::Y]; + line->x1.computed = points[0][Geom::X]; + line->y1.computed = points[0][Geom::Y]; + line->x2.computed = points[1][Geom::X]; + line->y2.computed = points[1][Geom::Y]; - sp_item_adjust_stroke(item, NR::expansion(xform)); + sp_item_adjust_stroke(item, xform.descrim()); SP_OBJECT (item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - return NR::identity(); + return Geom::identity(); } static void diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 2b0379cd4..5ab9e27d6 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -215,7 +215,7 @@ sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value) path_effect_ref = NULL; } - if (path_effect_ref && path_effect_ref->lpeobject && path_effect_ref->lpeobject->lpe) { + if (path_effect_ref && path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe()) { lpeitem->path_effect_list->push_back(path_effect_ref); } else { // something has gone wrong in finding the right patheffect. For example when the specified LPE name does not exist. @@ -312,12 +312,12 @@ void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { g_warning("sp_lpe_item_perform_path_effect - NULL lpeobj in list!"); return; } - if (!lpeobj->lpe) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (!lpe) { g_warning("sp_lpe_item_perform_path_effect - lpeobj without lpe!"); return; } - Inkscape::LivePathEffect::Effect *lpe = lpeobj->lpe; if (lpe->isVisible()) { if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { // if the effect expects mouse input before being applied and the input is not finished @@ -362,7 +362,7 @@ sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) PathEffectList lpelist = sp_lpe_item_get_effect_list(lpeitem); std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i; for (i = lpelist.begin(); i != lpelist.end(); ++i) { - Inkscape::LivePathEffect::Effect *lpe = (*i)->lpeobject->lpe; + Inkscape::LivePathEffect::Effect *lpe = (*i)->lpeobject->get_lpe(); if (dynamic_cast<Inkscape::LivePathEffect::LPEPathLength *>(lpe)) { if (!lpe->isVisible()) { // we manually disable text for LPEPathLength @@ -487,8 +487,8 @@ void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, gchar *value, bool reset) sp_lpe_item_create_original_path_recursive(lpeitem); LivePathEffectObject *lpeobj = lpeitem->path_effect_list->back()->lpeobject; - if (lpeobj && lpeobj->lpe) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->lpe; + if (lpeobj && lpeobj->get_lpe()) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); // Ask the path effect to reset itself if it doesn't have parameters yet if (reset) { // has to be called when all the subitems have their lpes applied @@ -607,8 +607,9 @@ sp_lpe_item_has_path_effect_of_type(SPLPEItem *lpeitem, int type) { std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i; for (i = lpeitem->path_effect_list->begin(); i != lpeitem->path_effect_list->end(); ++i) { - if ((*i)->lpeobject->lpe->effectType() == type) { - return (*i)->lpeobject->lpe; + Inkscape::LivePathEffect::Effect* lpe = (*i)->lpeobject->get_lpe(); + if (lpe && (lpe->effectType() == type)) { + return lpe; } } return NULL; @@ -629,8 +630,8 @@ bool sp_lpe_item_can_accept_freehand_shape(SPLPEItem *lpeitem) void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt) { Inkscape::LivePathEffect::LPEObjectReference *lperef = sp_lpe_item_get_current_lpereference(lpeitem); - if (lperef && lperef->lpeobject && lperef->lpeobject->lpe) { - lperef->lpeobject->lpe->editNextParamOncanvas(SP_ITEM(lpeitem), dt); + if (lperef && lperef->lpeobject && lperef->lpeobject->get_lpe()) { + lperef->lpeobject->get_lpe()->editNextParamOncanvas(SP_ITEM(lpeitem), dt); } } @@ -714,7 +715,7 @@ Inkscape::LivePathEffect::Effect* sp_lpe_item_get_current_lpe(SPLPEItem *lpeitem Inkscape::LivePathEffect::LPEObjectReference* lperef = sp_lpe_item_get_current_lpereference(lpeitem); if (lperef && lperef->lpeobject) - return lperef->lpeobject->lpe; + return lperef->lpeobject->get_lpe(); else return NULL; } diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index 49a40f4ca..e7bae2951 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -219,7 +219,7 @@ sp_mask_update (SPObject *object, SPCtx *ctx, guint flags) SPMask *mask = SP_MASK (object); for (SPMaskView *v = mask->display; v != NULL; v = v->next) { if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - NR::Matrix t(NR::scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0)); + Geom::Matrix t(Geom::Scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0)); t[4] = v->bbox.x0; t[5] = v->bbox.y0; nr_arena_group_set_child_transform (NR_ARENA_GROUP (v->arenaitem), &t); @@ -322,7 +322,7 @@ sp_mask_show (SPMask *mask, NRArena *arena, unsigned int key) } if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { - NR::Matrix t(NR::scale(mask->display->bbox.x1 - mask->display->bbox.x0, mask->display->bbox.y1 - mask->display->bbox.y0)); + Geom::Matrix t(Geom::Scale(mask->display->bbox.x1 - mask->display->bbox.x0, mask->display->bbox.y1 - mask->display->bbox.y0)); t[4] = mask->display->bbox.x0; t[5] = mask->display->bbox.y0; nr_arena_group_set_child_transform (NR_ARENA_GROUP (ai), &t); diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index 37ea2e5f5..877bc6823 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -91,7 +91,7 @@ static void refresh_offset_source(SPOffset* offset); static void sp_offset_start_listening(SPOffset *offset,SPObject* to); static void sp_offset_quit_listening(SPOffset *offset); static void sp_offset_href_changed(SPObject *old_ref, SPObject *ref, SPOffset *offset); -static void sp_offset_move_compensate(NR::Matrix const *mp, SPItem *original, SPOffset *self); +static void sp_offset_move_compensate(Geom::Matrix const *mp, SPItem *original, SPOffset *self); static void sp_offset_delete_self(SPObject *deleted, SPOffset *self); static void sp_offset_source_modified (SPObject *iSource, guint flags, SPItem *item); @@ -510,7 +510,7 @@ sp_offset_set_shape(SPShape *shape) theRes->ConvertToForme (orig, 1, originaux); SPItem *item = shape; - boost::optional<NR::Rect> bbox = sp_item_bbox_desktop (item); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (item); if ( bbox && !bbox->isEmpty() ) { gdouble size = L2(bbox->dimensions()); gdouble const exp = NR::expansion(item->transform); @@ -1021,23 +1021,23 @@ sp_offset_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPOffset *offse } static void -sp_offset_move_compensate(NR::Matrix const *mp, SPItem */*original*/, SPOffset *self) +sp_offset_move_compensate(Geom::Matrix const *mp, SPItem */*original*/, SPOffset *self) { guint mode = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_PARALLEL); if (mode == SP_CLONE_COMPENSATION_NONE) return; - NR::Matrix m(*mp); - if (!(m.is_translation())) return; + Geom::Matrix m(*mp); + if (!(m.isTranslation())) return; // calculate the compensation matrix and the advertized movement matrix SPItem *item = SP_ITEM(self); - NR::Matrix compensate; - NR::Matrix advertized_move; + Geom::Matrix compensate; + Geom::Matrix advertized_move; if (mode == SP_CLONE_COMPENSATION_UNMOVED) { - compensate = NR::identity(); - advertized_move.set_identity(); + compensate = Geom::identity(); + advertized_move.setIdentity(); } else if (mode == SP_CLONE_COMPENSATION_PARALLEL) { compensate = m; advertized_move = m; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 731ecce64..16e3bec40 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -56,7 +56,7 @@ static void sp_path_build(SPObject *object, SPDocument *document, Inkscape::XML: static void sp_path_set(SPObject *object, unsigned key, gchar const *value); static Inkscape::XML::Node *sp_path_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -static NR::Matrix sp_path_set_transform(SPItem *item, NR::Matrix const &xform); +static Geom::Matrix sp_path_set_transform(SPItem *item, Geom::Matrix const &xform); static gchar * sp_path_description(SPItem *item); static void sp_path_convert_to_guides(SPItem *item); @@ -348,14 +348,14 @@ sp_path_update(SPObject *object, SPCtx *ctx, guint flags) /** * Writes the given transform into the repr for the given item. */ -static NR::Matrix -sp_path_set_transform(SPItem *item, NR::Matrix const &xform) +static Geom::Matrix +sp_path_set_transform(SPItem *item, Geom::Matrix const &xform) { SPShape *shape = (SPShape *) item; SPPath *path = (SPPath *) item; if (!shape->curve) { // 0 nodes, nothing to transform - return NR::identity(); + return Geom::identity(); } // Transform the original-d path or the (ordinary) path @@ -366,7 +366,7 @@ sp_path_set_transform(SPItem *item, NR::Matrix const &xform) } // Adjust stroke - sp_item_adjust_stroke(item, NR::expansion(xform)); + sp_item_adjust_stroke(item, xform.descrim()); // Adjust pattern fill sp_item_adjust_pattern(item, xform); @@ -380,35 +380,37 @@ sp_path_set_transform(SPItem *item, NR::Matrix const &xform) item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); // nothing remains - we've written all of the transform, so return identity - return NR::identity(); + return Geom::identity(); } static void sp_path_update_patheffect(SPLPEItem *lpeitem, bool write) { - SPShape *shape = (SPShape *) lpeitem; - SPPath *path = (SPPath *) lpeitem; - if (path->original_curve) { - SPCurve *curve = path->original_curve->copy(); - sp_shape_set_curve_insync(shape, curve, TRUE); - sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve); - SP_OBJECT(shape)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - curve->unref(); - - if (write) { - // could also do SP_OBJECT(shape)->updateRepr(); but only the d attribute needs updating. - Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape); - if ( shape->curve != NULL ) { - gchar *str = sp_svg_write_path(shape->curve->get_pathvector()); - repr->setAttribute("d", str); - g_free(str); - } else { - repr->setAttribute("d", NULL); + SPShape * const shape = (SPShape *) lpeitem; + SPPath * const path = (SPPath *) lpeitem; + + if (sp_lpe_item_has_path_effect(lpeitem) && sp_lpe_item_path_effects_enabled(lpeitem)) { + if (path->original_curve) { + SPCurve *curve = path->original_curve->copy(); + sp_shape_set_curve_insync(shape, curve, TRUE); + sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve); + SP_OBJECT(shape)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + curve->unref(); + + if (write) { + // could also do SP_OBJECT(shape)->updateRepr(); but only the d attribute needs updating. + Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape); + if ( shape->curve != NULL ) { + gchar *str = sp_svg_write_path(shape->curve->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", NULL); + } } } - } else { - } + // else: do nothing. } diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index f7c8a03fc..9d981c5f2 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -20,7 +20,7 @@ #include <string> #include <libnr/nr-matrix-ops.h> #include "libnr/nr-matrix-fns.h" -#include <libnr/nr-translate-matrix-ops.h> +#include <2geom/transforms.h> #include "macros.h" #include "svg/svg.h" #include "display/nr-arena.h" @@ -705,7 +705,7 @@ sp_pattern_painter_new (SPPaintServer *ps, NR::Matrix const &full_transform, NR: pp->pcs2px = pattern_patternTransform(pat) * full_transform; } - pp->pcs2px = NR::translate (pattern_x (pat), pattern_y (pat)) * pp->pcs2px; + pp->pcs2px = Geom::Translate (pattern_x (pat), pattern_y (pat)) * pp->pcs2px; } /* Create arena */ diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp index b573300e0..36e64614e 100644 --- a/src/sp-rect.cpp +++ b/src/sp-rect.cpp @@ -43,7 +43,7 @@ static void sp_rect_update(SPObject *object, SPCtx *ctx, guint flags); static Inkscape::XML::Node *sp_rect_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); static gchar *sp_rect_description(SPItem *item); -static NR::Matrix sp_rect_set_transform(SPItem *item, NR::Matrix const &xform); +static Geom::Matrix sp_rect_set_transform(SPItem *item, Geom::Matrix const &xform); static void sp_rect_convert_to_guides(SPItem *item); static void sp_rect_set_shape(SPShape *shape); @@ -336,17 +336,17 @@ sp_rect_set_ry(SPRect *rect, gboolean set, gdouble value) /* fixme: Use preferred units somehow (Lauris) */ /* fixme: Alternately preserve whatever units there are (lauris) */ -static NR::Matrix -sp_rect_set_transform(SPItem *item, NR::Matrix const &xform) +static Geom::Matrix +sp_rect_set_transform(SPItem *item, Geom::Matrix const &xform) { SPRect *rect = SP_RECT(item); /* Calculate rect start in parent coords. */ - NR::Point pos( NR::Point(rect->x.computed, rect->y.computed) * xform ); + Geom::Point pos( Geom::Point(rect->x.computed, rect->y.computed) * xform ); /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ - NR::Matrix ret(NR::transform(xform)); + Geom::Matrix ret(Geom::Matrix(xform).without_translation()); gdouble const sw = hypot(ret[0], ret[1]); gdouble const sh = hypot(ret[2], ret[3]); if (sw > 1e-9) { @@ -376,8 +376,8 @@ sp_rect_set_transform(SPItem *item, NR::Matrix const &xform) /* Find start in item coords */ pos = pos * ret.inverse(); - rect->x = pos[NR::X]; - rect->y = pos[NR::Y]; + rect->x = pos[Geom::X]; + rect->y = pos[Geom::Y]; sp_rect_set_shape(rect); diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 6aec13bc9..bdffd821c 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -272,7 +272,7 @@ sp_shape_update (SPObject *object, SPCtx *ctx, unsigned int flags) if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { /* This is suboptimal, because changing parent style schedules recalculation */ /* But on the other hand - how can we know that parent does not tie style and transform */ - boost::optional<NR::Rect> paintbox = SP_ITEM(object)->getBounds(NR::identity(), SPItem::GEOMETRIC_BBOX); + boost::optional<Geom::Rect> paintbox = SP_ITEM(object)->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX); for (SPItemView *v = SP_ITEM (shape)->display; v != NULL; v = v->next) { NRArenaShape * const s = NR_ARENA_SHAPE(v->arenaitem); if (flags & SP_OBJECT_MODIFIED_FLAG) { @@ -738,7 +738,7 @@ sp_shape_show (SPItem *item, NRArena *arena, unsigned int /*key*/, unsigned int NRArenaShape * const s = NR_ARENA_SHAPE(arenaitem); nr_arena_shape_set_style(s, object->style); nr_arena_shape_set_path(s, shape->curve, false); - boost::optional<NR::Rect> paintbox = item->getBounds(NR::identity()); + boost::optional<Geom::Rect> paintbox = item->getBounds(Geom::identity()); if (paintbox) { s->setPaintBox(*paintbox); } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 96bc9180a..d86e3de48 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -409,7 +409,7 @@ sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ) guint32 seed = point_unique_int (o); // randomly rotate (by step 3 from the seed) and scale (by step 4) the vector - ret = ret * NR::Matrix (NR::rotate (star->randomized * M_PI * rnd (seed, 3))); + ret = ret * NR::Matrix (Geom::Rotate (star->randomized * M_PI * rnd (seed, 3))); ret *= ( 1 + star->randomized * rnd (seed, 4)); // the randomized corner point diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp index 06f8bfb49..8be53dd50 100644 --- a/src/sp-symbol.cpp +++ b/src/sp-symbol.cpp @@ -20,6 +20,7 @@ #include "libnr/nr-matrix-fns.h" #include "libnr/nr-matrix-ops.h" +#include <2geom/transforms.h> #include "display/nr-arena-group.h" #include "xml/repr.h" #include "attributes.h" @@ -269,7 +270,7 @@ sp_symbol_update (SPObject *object, SPCtx *ctx, guint flags) /* Calculate child to parent transformation */ /* Apply parent <use> translation (set up as vewport) */ - symbol->c2p = NR::Matrix(NR::translate(rctx.vp.x0, rctx.vp.y0)); + symbol->c2p = NR::Matrix(Geom::Translate(rctx.vp.x0, rctx.vp.y0)); if (symbol->viewBox_set) { double x, y, width, height; diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 754cc24f9..dd57428ef 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -25,6 +25,7 @@ # include "config.h" #endif +#include <2geom/matrix.h> #include <libnr/nr-matrix-fns.h> #include <libnrtype/FontFactory.h> #include <libnrtype/font-instance.h> @@ -74,7 +75,7 @@ static NRArenaItem *sp_text_show (SPItem *item, NRArena *arena, unsigned key, un static void sp_text_hide (SPItem *item, unsigned key); static char *sp_text_description (SPItem *item); static void sp_text_snappoints(SPItem const *item, SnapPointsIter p); -static NR::Matrix sp_text_set_transform(SPItem *item, NR::Matrix const &xform); +static Geom::Matrix sp_text_set_transform(SPItem *item, Geom::Matrix const &xform); static void sp_text_print (SPItem *item, SPPrintContext *gpc); static SPItemClass *text_parent_class; @@ -436,8 +437,8 @@ static void sp_text_snappoints(SPItem const *item, SnapPointsIter p) } } -static NR::Matrix -sp_text_set_transform (SPItem *item, NR::Matrix const &xform) +static Geom::Matrix +sp_text_set_transform (SPItem *item, Geom::Matrix const &xform) { SPText *text = SP_TEXT(item); @@ -454,12 +455,12 @@ sp_text_set_transform (SPItem *item, NR::Matrix const &xform) // (e.g. it broke stroke width on copy/pasting of style from horizontally stretched to vertically // stretched shape). Using fontsize_expansion only here broke setting the style via font // dialog. This needs to be investigated further. - double const ex = NR::expansion(xform); + double const ex = xform.descrim(); if (ex == 0) { return xform; } - NR::Matrix ret(NR::transform(xform)); + Geom::Matrix ret(Geom::Matrix(xform).without_translation()); ret[0] /= ex; ret[1] /= ex; ret[2] /= ex; diff --git a/src/sp-use-reference.cpp b/src/sp-use-reference.cpp index e493e6afa..347a82427 100644 --- a/src/sp-use-reference.cpp +++ b/src/sp-use-reference.cpp @@ -41,7 +41,7 @@ bool SPUseReference::_acceptObject(SPObject * const obj) const static void sp_usepath_href_changed(SPObject *old_ref, SPObject *ref, SPUsePath *offset); -static void sp_usepath_move_compensate(NR::Matrix const *mp, SPItem *original, SPUsePath *self); +static void sp_usepath_move_compensate(Geom::Matrix const *mp, SPItem *original, SPUsePath *self); static void sp_usepath_delete_self(SPObject *deleted, SPUsePath *offset); static void sp_usepath_source_modified(SPObject *iSource, guint flags, SPUsePath *offset); @@ -139,7 +139,7 @@ sp_usepath_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPUsePath *off } static void -sp_usepath_move_compensate(NR::Matrix const *mp, SPItem *original, SPUsePath *self) +sp_usepath_move_compensate(Geom::Matrix const *mp, SPItem *original, SPUsePath *self) { guint mode = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_PARALLEL); if (mode == SP_CLONE_COMPENSATION_NONE) { diff --git a/src/sp-use.cpp b/src/sp-use.cpp index 8b6321745..12066f925 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -22,7 +22,7 @@ #include <libnr/nr-matrix-ops.h> #include <libnr/nr-matrix-fns.h> -#include "libnr/nr-matrix-translate-ops.h" +#include <2geom/transforms.h> #include <glibmm/i18n.h> #include "display/nr-arena-group.h" #include "attributes.h" @@ -299,7 +299,7 @@ sp_use_print(SPItem *item, SPPrintContext *ctx) SPUse *use = SP_USE(item); if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { - NR::Matrix tp(NR::translate(use->x.computed, use->y.computed)); + NR::Matrix tp(Geom::Translate(use->x.computed, use->y.computed)); sp_print_bind(ctx, tp, 1.0); translated = true; } @@ -354,7 +354,7 @@ sp_use_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags) if (ac) { nr_arena_item_add_child(ai, ac, NULL); } - NR::translate t(use->x.computed, + Geom::Translate t(use->x.computed, use->y.computed); nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), NR::Matrix(t)); } @@ -424,7 +424,7 @@ sp_use_get_root_transform(SPUse *use) if (SP_IS_USE(i_tem)) { SPUse *i_use = SP_USE(i_tem); if ((i_use->x._set && i_use->x.computed != 0) || (i_use->y._set && i_use->y.computed != 0)) { - t = t * NR::translate(i_use->x._set ? i_use->x.computed : 0, i_use->y._set ? i_use->y.computed : 0); + t = t * Geom::Translate(i_use->x._set ? i_use->x.computed : 0, i_use->y._set ? i_use->y.computed : 0); } } @@ -442,9 +442,9 @@ sp_use_get_root_transform(SPUse *use) NR::Matrix sp_use_get_parent_transform(SPUse *use) { - NR::Matrix t(NR::identity()); + Geom::Matrix t(Geom::identity()); if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) { - t *= NR::translate(use->x._set ? use->x.computed : 0, + t *= Geom::Translate(use->x._set ? use->x.computed : 0, use->y._set ? use->y.computed : 0); } @@ -458,7 +458,7 @@ sp_use_get_parent_transform(SPUse *use) * clone's transform. */ static void -sp_use_move_compensate(NR::Matrix const *mp, SPItem */*original*/, SPUse *self) +sp_use_move_compensate(Geom::Matrix const *mp, SPItem */*original*/, SPUse *self) { // the clone is orphaned; or this is not a real use, but a clone of another use; // we skip it, otherwise duplicate compensation will occur @@ -476,26 +476,26 @@ sp_use_move_compensate(NR::Matrix const *mp, SPItem */*original*/, SPUse *self) if (mode == SP_CLONE_COMPENSATION_NONE) return; - NR::Matrix m(*mp); + Geom::Matrix m(*mp); // this is not a simple move, do not try to compensate - if (!(m.is_translation())) + if (!(m.isTranslation())) return; // restore item->transform field from the repr, in case it was changed by seltrans sp_object_read_attr (SP_OBJECT (self), "transform"); - NR::Matrix t = sp_use_get_parent_transform(self); - NR::Matrix clone_move = t.inverse() * m * t; + Geom::Matrix t = sp_use_get_parent_transform(self); + Geom::Matrix clone_move = t.inverse() * m * t; // calculate the compensation matrix and the advertized movement matrix - NR::Matrix advertized_move; + Geom::Matrix advertized_move; if (mode == SP_CLONE_COMPENSATION_PARALLEL) { clone_move = clone_move.inverse() * m; advertized_move = m; } else if (mode == SP_CLONE_COMPENSATION_UNMOVED) { clone_move = clone_move.inverse(); - advertized_move.set_identity(); + advertized_move.setIdentity(); } else { g_assert_not_reached(); } @@ -623,7 +623,7 @@ sp_use_update(SPObject *object, SPCtx *ctx, unsigned flags) /* As last step set additional transform of arena group */ for (SPItemView *v = item->display; v != NULL; v = v->next) { - NR::Matrix t(NR::translate(use->x.computed, use->y.computed)); + NR::Matrix t(Geom::Translate(use->x.computed, use->y.computed)); nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), t); } } @@ -671,7 +671,7 @@ sp_use_unlink(SPUse *use) g_return_val_if_fail(orig, NULL); // Calculate the accumulated transform, starting from the original. - NR::Matrix t = sp_use_get_root_transform(use); + Geom::Matrix t = sp_use_get_root_transform(use); Inkscape::XML::Node *copy = NULL; if (SP_IS_SYMBOL(orig)) { // make a group, copy children @@ -724,7 +724,7 @@ sp_use_unlink(SPUse *use) SPItem *item = SP_ITEM(unlinked); // Set the accummulated transform. { - NR::Matrix nomove(NR::identity()); + Geom::Matrix nomove(Geom::identity()); // Advertise ourselves as not moving. sp_item_write_transform(item, SP_OBJECT_REPR(item), t, &nomove); } diff --git a/src/splivarot.cpp b/src/splivarot.cpp index f44cba46d..dc19ac761 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -1647,7 +1647,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, bool didSomething = false; - boost::optional<NR::Rect> selectionBbox = selection->bounds(); + boost::optional<Geom::Rect> selectionBbox = selection->bounds(); if (!selectionBbox) { return false; } @@ -1668,7 +1668,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop, continue; if (simplifyIndividualPaths) { - boost::optional<NR::Rect> itemBbox = item->getBounds(sp_item_i2d_affine(item)); + boost::optional<Geom::Rect> itemBbox = item->getBounds(sp_item_i2d_affine(item)); if (itemBbox) { simplifySize = L2(itemBbox->dimensions()); } else { diff --git a/src/svg-view.cpp b/src/svg-view.cpp index c4e35a2c9..c406e70a5 100644 --- a/src/svg-view.cpp +++ b/src/svg-view.cpp @@ -100,7 +100,7 @@ SPSVGView::doRescale (bool event) } if (_drawing) { - sp_canvas_item_affine_absolute (_drawing, NR::Matrix(NR::scale(_hscale, _vscale))); + sp_canvas_item_affine_absolute (_drawing, NR::Matrix(Geom::Scale(_hscale, _vscale))); } if (event) { diff --git a/src/svg/svg-affine.cpp b/src/svg/svg-affine.cpp index a34736176..2445135c3 100644 --- a/src/svg/svg-affine.cpp +++ b/src/svg/svg-affine.cpp @@ -24,12 +24,8 @@ #include <glib/gstrfuncs.h> #include <libnr/nr-matrix-fns.h> #include <libnr/nr-matrix-ops.h> -#include <libnr/nr-matrix-translate-ops.h> -#include <libnr/nr-rotate-fns.h> -#include <libnr/nr-rotate-matrix-ops.h> -#include <libnr/nr-scale-matrix-ops.h> -#include <libnr/nr-translate-matrix-ops.h> -#include <libnr/nr-translate-rotate-ops.h> +#include <2geom/transforms.h> +#include <2geom/angle.h> #include <libnr/nr-convert2geom.h> #include "svg.h" #include "prefs-utils.h" @@ -128,24 +124,24 @@ sp_svg_transform_read(gchar const *str, NR::Matrix *transform) } else if (n_args != 2) { return false; } - a = NR::translate(args[0], args[1]) * a; + a = Geom::Translate(args[0], args[1]) * a; } else if (!strcmp (keyword, "scale")) { if (n_args == 1) { args[1] = args[0]; } else if (n_args != 2) { return false; } - a = NR::scale(args[0], args[1]) * a; + a = Geom::Scale(args[0], args[1]) * a; } else if (!strcmp (keyword, "rotate")) { if (n_args != 1 && n_args != 3) { return false; } - NR::rotate const rot(rotate_degrees(args[0])); + Geom::Rotate const rot(Geom::deg_to_rad(args[0])); if (n_args == 3) { - a = ( NR::translate(-args[1], -args[2]) + a = ( Geom::Translate(-args[1], -args[2]) * rot - * NR::translate(args[1], args[2]) - * a ); + * Geom::Translate(args[1], args[2]) + * Geom::Matrix(a) ); } else { a = rot * a; } diff --git a/src/text-context.cpp b/src/text-context.cpp index 9d7fe3c03..08f0cf0d9 100644 --- a/src/text-context.cpp +++ b/src/text-context.cpp @@ -445,7 +445,7 @@ sp_text_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve item_ungrouped = desktop->item_at_point(NR::Point(event->button.x, event->button.y), TRUE); if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) { sp_canvas_item_show(tc->indicator); - boost::optional<Geom::Rect> ibbox = to_2geom(sp_item_bbox_desktop(item_ungrouped)); + boost::optional<Geom::Rect> ibbox = sp_item_bbox_desktop(item_ungrouped); if (ibbox) { SP_CTRLRECT(tc->indicator)->setRectangle(*ibbox); } @@ -1607,7 +1607,7 @@ sp_text_context_update_cursor(SPTextContext *tc, bool scroll_to_see) SPItem *frame = SP_FLOWTEXT(tc->text)->get_frame (NULL); // first frame only if (frame) { sp_canvas_item_show(tc->frame); - boost::optional<Geom::Rect> frame_bbox = to_2geom(sp_item_bbox_desktop(frame)); + boost::optional<Geom::Rect> frame_bbox = sp_item_bbox_desktop(frame); if (frame_bbox) { SP_CTRLRECT(tc->frame)->setRectangle(*frame_bbox); } diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index 95c144e28..33e4ea3a1 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -28,7 +28,7 @@ #include <sp-shape.h> #include <sp-image.h> #include <libnr/nr-matrix-ops.h> -#include <libnr/nr-scale-translate-ops.h> +#include <2geom/transforms.h> #include <display/nr-arena.h> #include <display/nr-arena-shape.h> @@ -507,8 +507,8 @@ void Tracer::traceThread() double iwscale = width / iwidth; double ihscale = height / iheight; - NR::translate trans(x, y); - NR::scale scal(iwscale, ihscale); + Geom::Translate trans(x, y); + Geom::Scale scal(iwscale, ihscale); //# Convolve scale, translation, and the original transform NR::Matrix tf(scal * trans); diff --git a/src/tweak-context.cpp b/src/tweak-context.cpp index 8467d687f..df10ca7a1 100644 --- a/src/tweak-context.cpp +++ b/src/tweak-context.cpp @@ -68,11 +68,15 @@ #include "display/canvas-arena.h" #include "display/curve.h" #include "livarot/Shape.h" -#include "2geom/isnan.h" +#include <2geom/isnan.h> +#include <2geom/transforms.h> #include "prefs-utils.h" #include "style.h" #include "box3d.h" #include "sp-item-transform.h" +#include "filter-chemistry.h" +#include "sp-gaussian-blur-fns.h" +#include "sp-gaussian-blur.h" #include "tweak-context.h" @@ -184,7 +188,7 @@ bool is_transform_mode (gint mode) bool is_color_mode (gint mode) { - return (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER); + return (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER || mode == TWEAK_MODE_BLUR); } void @@ -255,6 +259,10 @@ sp_tweak_update_cursor (SPTweakContext *tc, bool with_shift) tc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag or click to <b>randomize colors</b>."), sel_message); event_context->cursor_shape = cursor_color_xpm; break; + case TWEAK_MODE_BLUR: + tc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag or click to <b>increase blur</b>; with Shift to <b>decrease</b>."), sel_message); + event_context->cursor_shape = cursor_color_xpm; + break; } sp_event_context_update_cursor(event_context); g_free(sel_message); @@ -393,7 +401,7 @@ get_move_force (SPTweakContext *tc) } bool -sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Point p, NR::Point vector, gint mode, double radius, double force, double fidelity, bool reverse) +sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::Point p, Geom::Point vector, gint mode, double radius, double force, double fidelity, bool reverse) { bool did = false; @@ -403,7 +411,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi selection->add(item); } - if (SP_IS_GROUP(item)) { + if (SP_IS_GROUP(item) && !SP_IS_BOX3D(item)) { for (SPObject *child = sp_object_first_child(SP_OBJECT(item)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { if (SP_IS_ITEM(child)) { if (sp_tweak_dilate_recursive (selection, SP_ITEM(child), p, vector, mode, radius, force, fidelity, reverse)) @@ -414,9 +422,9 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi } else { if (mode == TWEAK_MODE_MOVE) { - boost::optional<NR::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { - double x = NR::L2(a->midpoint() - p)/radius; + double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; if (x < 1) { Geom::Point move = force * 0.5 * (cos(M_PI * x) + 1) * vector; @@ -427,9 +435,9 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi } else if (mode == TWEAK_MODE_MOVE_IN_OUT) { - boost::optional<NR::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { - double x = NR::L2(a->midpoint() - p)/radius; + double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; if (x < 1) { Geom::Point move = force * 0.5 * (cos(M_PI * x) + 1) * @@ -441,14 +449,14 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi } else if (mode == TWEAK_MODE_MOVE_JITTER) { - boost::optional<NR::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { double dp = g_random_double_range(0, M_PI*2); double dr = g_random_double_range(0, radius); - double x = NR::L2(a->midpoint() - p)/radius; + double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; if (x < 1) { - Geom::Point move = force * 0.5 * (cos(M_PI * x) + 1) * NR::Point(cos(dp)*dr, sin(dp)*dr); + Geom::Point move = force * 0.5 * (cos(M_PI * x) + 1) * Geom::Point(cos(dp)*dr, sin(dp)*dr); sp_item_move_rel(item, Geom::Translate(move[Geom::X], -move[Geom::Y])); did = true; } @@ -456,9 +464,9 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi } else if (mode == TWEAK_MODE_SCALE) { - boost::optional<NR::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { - double x = NR::L2(a->midpoint() - p)/radius; + double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; if (x < 1) { double scale = 1 + (reverse? force : -force) * 0.05 * (cos(M_PI * x) + 1); @@ -469,9 +477,9 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi } else if (mode == TWEAK_MODE_ROTATE) { - boost::optional<NR::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { - double x = NR::L2(a->midpoint() - p)/radius; + double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; if (x < 1) { double angle = (reverse? force : -force) * 0.05 * (cos(M_PI * x) + 1) * M_PI; @@ -482,9 +490,9 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi } else if (mode == TWEAK_MODE_MORELESS) { - boost::optional<NR::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { - double x = NR::L2(a->midpoint() - p)/radius; + double x = Geom::L2(a->midpoint() - p)/radius; if (a->contains(p)) x = 0; if (x < 1) { double prob = force * 0.5 * (cos(M_PI * x) + 1); @@ -498,9 +506,14 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi SPDocument *doc = SP_OBJECT_DOCUMENT(item); Inkscape::XML::Document* xml_doc = sp_document_repr_doc(doc); Inkscape::XML::Node *old_repr = SP_OBJECT_REPR(item); + SPObject *old_obj = doc->getObjectByRepr(old_repr); Inkscape::XML::Node *parent = old_repr->parent(); Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc); parent->appendChild(copy); + SPObject *new_obj = doc->getObjectByRepr(copy); + if (selection->includes(old_obj)) { + selection->add(new_obj); + } Inkscape::GC::release(copy); } } @@ -528,9 +541,9 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi // skip those paths whose bboxes are entirely out of reach with our radius - boost::optional<NR::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item)); + boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item)); if (bbox) { - bbox->growBy(radius); + bbox->expandBy(radius); if (!bbox->contains(p)) { return false; } @@ -566,21 +579,21 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi theRes->ConvertToShape(theShape, fill_nonZero); } - if (NR::L2(vector) != 0) - vector = 1/NR::L2(vector) * vector; + if (Geom::L2(vector) != 0) + vector = 1/Geom::L2(vector) * vector; bool did_this = false; if (mode == TWEAK_MODE_SHRINK_GROW) { if (theShape->MakeTweak(tweak_mode_grow, theRes, reverse? force : -force, join_straight, 4.0, - true, p, NR::Point(0,0), radius, &i2doc) == 0) // 0 means the shape was actually changed + true, p, Geom::Point(0,0), radius, &i2doc) == 0) // 0 means the shape was actually changed did_this = true; } else if (mode == TWEAK_MODE_ATTRACT_REPEL) { if (theShape->MakeTweak(tweak_mode_repel, theRes, reverse? force : -force, join_straight, 4.0, - true, p, NR::Point(0,0), radius, &i2doc) == 0) + true, p, Geom::Point(0,0), radius, &i2doc) == 0) did_this = true; } else if (mode == TWEAK_MODE_PUSH) { if (theShape->MakeTweak(tweak_mode_push, theRes, @@ -592,7 +605,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi if (theShape->MakeTweak(tweak_mode_roughen, theRes, force, join_straight, 4.0, - true, p, NR::Point(0,0), radius, &i2doc) == 0) + true, p, Geom::Point(0,0), radius, &i2doc) == 0) did_this = true; } @@ -784,7 +797,7 @@ tweak_colors_in_gradient (SPItem *item, bool fill_or_stroke, // This is the matrix which moves and rotates the gradient line // so it's oriented along the X axis: - NR::Matrix norm = NR::Matrix(NR::translate(-p1)) * NR::Matrix(NR::rotate(-atan2(pdiff[NR::Y], pdiff[NR::X]))); + NR::Matrix norm = NR::Matrix(Geom::Translate(-p1)) * NR::Matrix(Geom::Rotate(-atan2(pdiff[NR::Y], pdiff[NR::X]))); // Transform the mouse point by it to find out its projection onto the gradient line: NR::Point pnorm = p * norm; @@ -878,6 +891,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, guint32 fill_goal, bool do_fill, guint32 stroke_goal, bool do_stroke, float opacity_goal, bool do_opacity, + bool do_blur, bool reverse, NR::Point p, double radius, double force, bool do_h, bool do_s, bool do_l, bool do_o) { @@ -890,6 +904,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, fill_goal, do_fill, stroke_goal, do_stroke, opacity_goal, do_opacity, + do_blur, reverse, p, radius, force, do_h, do_s, do_l, do_o)) did = true; } @@ -900,13 +915,13 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, if (!style) { return false; } - boost::optional<NR::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item), + boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item), SPItem::GEOMETRIC_BBOX); if (!bbox) { return false; } - NR::Rect brush(p - NR::Point(radius, radius), p + NR::Point(radius, radius)); + Geom::Rect brush(p - Geom::Point(radius, radius), p + Geom::Point(radius, radius)); NR::Point center = bbox->midpoint(); double this_force; @@ -929,6 +944,54 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, if (this_force > 0.002) { + if (do_blur) { + boost::optional<Geom::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item), + SPItem::GEOMETRIC_BBOX); + if (!bbox) { + return did; + } + + double blur_now = 0; + Geom::Matrix i2d = sp_item_i2d_affine (item); + if (style->filter.set && style->getFilter()) { + //cycle through filter primitives + SPObject *primitive_obj = style->getFilter()->children; + while (primitive_obj) { + if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) { + SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); + //if primitive is gaussianblur + if(SP_IS_GAUSSIANBLUR(primitive)) { + SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive); + float num = spblur->stdDeviation.getNumber(); + blur_now += num * i2d.descrim(); // sum all blurs in the filter + } + } + primitive_obj = primitive_obj->next; + } + } + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; + blur_now = blur_now / perimeter; + + double blur_new; + if (reverse) + blur_new = blur_now - 0.06 * force; + else + blur_new = blur_now + 0.06 * force; + if (blur_new < 0.0005 && blur_new < blur_now) { + blur_new = 0; + } + + if (blur_new == 0) { + remove_filter(item, false); + } else { + double radius = blur_new * perimeter; + SPFilter *filter = modify_filter_gaussian_blur_from_item(SP_OBJECT_DOCUMENT(item), item, radius); + + sp_style_set_property_url(item, "filter", filter, false); + } + return true; // do not do colors, blur is a separate mode + } + if (do_fill) { if (style->fill.isPaintserver()) { tweak_colors_in_gradient (item, true, fill_goal, p, radius, this_force, mode, do_h, do_s, do_l, do_o); @@ -978,6 +1041,19 @@ sp_tweak_dilate (SPTweakContext *tc, NR::Point event_p, NR::Point p, NR::Point v guint32 fill_goal = sp_desktop_get_color_tool(desktop, "tools.tweak", true, &do_fill); guint32 stroke_goal = sp_desktop_get_color_tool(desktop, "tools.tweak", false, &do_stroke); double opacity_goal = sp_desktop_get_master_opacity_tool(desktop, "tools.tweak", &do_opacity); + if (reverse) { + fill_goal = SP_RGBA32_U_COMPOSE( + (255 - SP_RGBA32_R_U(fill_goal)), + (255 - SP_RGBA32_G_U(fill_goal)), + (255 - SP_RGBA32_B_U(fill_goal)), + (255 - SP_RGBA32_A_U(fill_goal))); + stroke_goal = SP_RGBA32_U_COMPOSE( + (255 - SP_RGBA32_R_U(stroke_goal)), + (255 - SP_RGBA32_G_U(stroke_goal)), + (255 - SP_RGBA32_B_U(stroke_goal)), + (255 - SP_RGBA32_A_U(stroke_goal))); + opacity_goal = 1 - opacity_goal; + } double path_force = get_path_force(tc); if (radius == 0 || path_force == 0) { @@ -998,6 +1074,7 @@ sp_tweak_dilate (SPTweakContext *tc, NR::Point event_p, NR::Point p, NR::Point v fill_goal, do_fill, stroke_goal, do_stroke, opacity_goal, do_opacity, + tc->mode == TWEAK_MODE_BLUR, reverse, p, radius, color_force, tc->do_h, tc->do_s, tc->do_l, tc->do_o)) did = true; } @@ -1017,7 +1094,7 @@ void sp_tweak_update_area (SPTweakContext *tc) { double radius = get_dilate_radius(tc); - NR::Matrix const sm (NR::scale(radius, radius) * NR::translate(SP_EVENT_CONTEXT(tc)->desktop->point())); + NR::Matrix const sm (Geom::Scale(radius, radius) * Geom::Translate(SP_EVENT_CONTEXT(tc)->desktop->point())); sp_canvas_item_affine_absolute(tc->dilate_area, sm); sp_canvas_item_show(tc->dilate_area); } @@ -1092,7 +1169,7 @@ sp_tweak_context_root_handler(SPEventContext *event_context, // draw the dilating cursor double radius = get_dilate_radius(tc); - NR::Matrix const sm (NR::scale(radius, radius) * NR::translate(desktop->w2d(motion_w))); + NR::Matrix const sm (Geom::Scale(radius, radius) * Geom::Translate(desktop->w2d(motion_w))); sp_canvas_item_affine_absolute(tc->dilate_area, sm); sp_canvas_item_show(tc->dilate_area); @@ -1183,6 +1260,10 @@ sp_tweak_context_root_handler(SPEventContext *event_context, sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), SP_VERB_CONTEXT_TWEAK, _("Color jitter tweak")); break; + case TWEAK_MODE_BLUR: + sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), + SP_VERB_CONTEXT_TWEAK, _("Blur tweak")); + break; } } break; @@ -1286,6 +1367,13 @@ sp_tweak_context_root_handler(SPEventContext *event_context, ret = TRUE; } break; + case GDK_b: + case GDK_B: + if (MOD__SHIFT_ONLY) { + sp_tweak_switch_mode(tc, TWEAK_MODE_BLUR, MOD__SHIFT); + ret = TRUE; + } + break; case GDK_Up: case GDK_KP_Up: diff --git a/src/tweak-context.h b/src/tweak-context.h index b5b150de0..b5a9b6b7e 100644 --- a/src/tweak-context.h +++ b/src/tweak-context.h @@ -43,7 +43,8 @@ enum { TWEAK_MODE_ATTRACT_REPEL, TWEAK_MODE_ROUGHEN, TWEAK_MODE_COLORPAINT, - TWEAK_MODE_COLORJITTER + TWEAK_MODE_COLORJITTER, + TWEAK_MODE_BLUR }; struct SPTweakContext diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp index 20d0ea0a4..ce10de477 100644 --- a/src/ui/cache/svg_preview_cache.cpp +++ b/src/ui/cache/svg_preview_cache.cpp @@ -38,7 +38,7 @@ GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rec Geom::Matrix t(Geom::Scale(scale_factor, scale_factor)); nr_arena_item_set_transform(root, t); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update( root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE ); diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 65cf14a95..09521008b 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -407,17 +407,17 @@ bool ClipboardManagerImpl::pasteSize(bool separately, bool apply_x, bool apply_y if (separately) { for (GSList *i = const_cast<GSList*>(selection->itemList()) ; i ; i = i->next) { SPItem *item = SP_ITEM(i->data); - boost::optional<NR::Rect> obj_size = sp_item_bbox_desktop(item); + boost::optional<Geom::Rect> obj_size = sp_item_bbox_desktop(item); if ( !obj_size || obj_size->isEmpty() ) continue; - sp_item_scale_rel(item, _getScale(min, max, to_2geom(*obj_size), apply_x, apply_y)); + sp_item_scale_rel(item, _getScale(min, max, *obj_size, apply_x, apply_y)); } } // resize the selection as a whole else { - boost::optional<NR::Rect> sel_size = selection->bounds(); + boost::optional<Geom::Rect> sel_size = selection->bounds(); if ( sel_size && !sel_size->isEmpty() ) { sp_selection_scale_relative(selection, sel_size->midpoint(), - _getScale(min, max, to_2geom(*sel_size), apply_x, apply_y)); + _getScale(min, max, *sel_size, apply_x, apply_y)); } } pasted = true; @@ -571,7 +571,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) } } - boost::optional<NR::Rect> size = selection->bounds(); + boost::optional<Geom::Rect> size = selection->bounds(); if (size) { sp_repr_set_point(_clipnode, "min", size->min()); sp_repr_set_point(_clipnode, "max", size->max()); @@ -786,7 +786,7 @@ void ClipboardManagerImpl::_pasteDocument(SPDocument *clipdoc, bool in_place) selection->setReprList(pasted_objects); // Change the selection to the freshly pasted objects sp_document_ensure_up_to_date(target_document); // What does this do? - boost::optional<NR::Rect> sel_bbox = selection->bounds(); //In desktop coordinates + boost::optional<Geom::Rect> sel_bbox = selection->bounds(); //In desktop coordinates // PS: We could also have used the min/max corners calculated above, instead of selection->bounds() because // we know that after pasting the upper left corner of the selection will be aligend to the corresponding // page corner. Using the boundingbox of the selection is more foolproof though diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 99d3fdda3..b8b59230a 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -160,7 +160,7 @@ private : selected.erase(master); /*}*/ //Compute the anchor point - boost::optional<NR::Rect> b = sp_item_bbox_desktop (thing); + boost::optional<Geom::Rect> b = sp_item_bbox_desktop (thing); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); @@ -177,7 +177,7 @@ private : case AlignAndDistribute::DRAWING: { - boost::optional<NR::Rect> b = sp_item_bbox_desktop + boost::optional<Geom::Rect> b = sp_item_bbox_desktop ( (SPItem *) sp_document_root (sp_desktop_document (desktop)) ); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], @@ -190,7 +190,7 @@ private : case AlignAndDistribute::SELECTION: { - boost::optional<NR::Rect> b = selection->bounds(); + boost::optional<Geom::Rect> b = selection->bounds(); if (b) { mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X], a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]); @@ -215,7 +215,7 @@ private : prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); bool changed = false; - boost::optional<NR::Rect> b; + boost::optional<Geom::Rect> b; if (sel_as_group) b = selection->bounds(); @@ -330,9 +330,9 @@ private : it != selected.end(); ++it) { - boost::optional<NR::Rect> bbox = sp_item_bbox_desktop(*it); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it); if (bbox) { - sorted.push_back(BBoxSort(*it, to_2geom(*bbox), _orientation, _kBegin, _kEnd)); + sorted.push_back(BBoxSort(*it, *bbox, _orientation, _kBegin, _kEnd)); } } //sort bbox by anchors @@ -602,7 +602,7 @@ private : //Check 2 or more selected objects if (selected.size() < 2) return; - boost::optional<NR::Rect> sel_bbox = selection->bounds(); + boost::optional<Geom::Rect> sel_bbox = selection->bounds(); if (!sel_bbox) { return; } @@ -611,7 +611,7 @@ private : // nor drift on sequential randomizations. Discard cache on global (or better active // desktop's) selection_change signal. if (!_dialog.randomize_bbox) { - _dialog.randomize_bbox = to_2geom(*sel_bbox); + _dialog.randomize_bbox = *sel_bbox; } // see comment in ActionAlign above @@ -623,13 +623,13 @@ private : ++it) { sp_document_ensure_up_to_date(sp_desktop_document (desktop)); - boost::optional<NR::Rect> item_box = sp_item_bbox_desktop (*it); + boost::optional<Geom::Rect> item_box = sp_item_bbox_desktop (*it); if (item_box) { // find new center, staying within bbox - double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box).extent(Geom::X)/2 + - g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::X].extent() - (*item_box).extent(Geom::X)); - double y = _dialog.randomize_bbox->min()[Geom::Y] + (*item_box).extent(Geom::Y)/2 + - g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::Y].extent() - (*item_box).extent(Geom::Y)); + double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box)[Geom::X].extent() /2 + + g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::X].extent() - (*item_box)[Geom::X].extent()); + double y = _dialog.randomize_bbox->min()[Geom::Y] + (*item_box)[Geom::Y].extent()/2 + + g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::Y].extent() - (*item_box)[Geom::Y].extent()); // displacement is the new center minus old: NR::Point t = NR::Point (x, y) - 0.5*(item_box->max() + item_box->min()); sp_item_move_rel(*it, Geom::Translate(t)); @@ -1099,9 +1099,9 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem { gdouble max = -1e18; for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) { - boost::optional<NR::Rect> b = sp_item_bbox_desktop (*it); + boost::optional<Geom::Rect> b = sp_item_bbox_desktop (*it); if (b) { - gdouble dim = (*b).extent(horizontal ? Geom::X : Geom::Y); + gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); if (dim > max) { max = dim; master = it; @@ -1116,9 +1116,9 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem { gdouble max = 1e18; for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) { - boost::optional<NR::Rect> b = sp_item_bbox_desktop (*it); + boost::optional<Geom::Rect> b = sp_item_bbox_desktop (*it); if (b) { - gdouble dim = (*b).extent(horizontal ? Geom::X : Geom::Y); + gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent(); if (dim < max) { max = dim; master = it; diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index e2d044908..e1479d3b4 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -866,7 +866,7 @@ bool FileOpenDialogImplWin32::set_svg_preview() NRRectL bbox = {0, 0, scaledSvgWidth, scaledSvgHeight}; // write object bbox to area - boost::optional<NR::Rect> maybeArea(from_2geom(area)); + boost::optional<Geom::Rect> maybeArea(area); sp_document_ensure_up_to_date (svgDoc); sp_item_invoke_bbox((SPItem *) svgDoc->root, maybeArea, sp_item_i2r_affine((SPItem *)(svgDoc->root)), TRUE); diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index 44f37083b..73d26b67e 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -176,7 +176,7 @@ LivePathEffectEditor::~LivePathEffectEditor() } void -LivePathEffectEditor::showParams(LivePathEffect::Effect* effect) +LivePathEffectEditor::showParams(LivePathEffect::Effect& effect) { if (effectwidget) { effectcontrol_vbox.remove(*effectwidget); @@ -184,8 +184,8 @@ LivePathEffectEditor::showParams(LivePathEffect::Effect* effect) effectwidget = NULL; } - explain_label.set_markup("<b>" + effect->getName() + "</b>"); - effectwidget = effect->newWidget(&tooltips); + explain_label.set_markup("<b>" + effect.getName() + "</b>"); + effectwidget = effect.newWidget(&tooltips); if (effectwidget) { effectcontrol_vbox.pack_start(*effectwidget, true, true); } @@ -200,7 +200,7 @@ LivePathEffectEditor::selectInList(LivePathEffect::Effect* effect) { Gtk::TreeNodeChildren chi = effectlist_view.get_model()->children(); for (Gtk::TreeIter ci = chi.begin() ; ci != chi.end(); ci++) { - if (ci->get_value(columns.lperef)->lpeobject->lpe == effect) + if (ci->get_value(columns.lperef)->lpeobject->get_lpe() == effect) effectlist_view.get_selection()->select(ci); } } @@ -259,7 +259,7 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) if ( sp_lpe_item_has_path_effect(lpeitem) ) { Inkscape::LivePathEffect::Effect *lpe = sp_lpe_item_get_current_lpe(lpeitem); if (lpe) { - showParams(lpe); + showParams(*lpe); lpe_list_locked = true; selectInList(lpe); } else { @@ -295,10 +295,17 @@ LivePathEffectEditor::effect_list_reload(SPLPEItem *lpeitem) PathEffectList::iterator it; for( it = effectlist.begin() ; it!=effectlist.end(); it++ ) { - Gtk::TreeModel::Row row = *(effectlist_store->append()); - row[columns.col_name] = (*it)->lpeobject->lpe->getName(); - row[columns.lperef] = *it; - row[columns.col_visible] = (*it)->lpeobject->lpe->isVisible(); + if ((*it)->lpeobject->get_lpe()) { + Gtk::TreeModel::Row row = *(effectlist_store->append()); + row[columns.col_name] = (*it)->lpeobject->get_lpe()->getName(); + row[columns.lperef] = *it; + row[columns.col_visible] = (*it)->lpeobject->get_lpe()->isVisible(); + } else { + Gtk::TreeModel::Row row = *(effectlist_store->append()); + row[columns.col_name] = "Unknown effect!"; + row[columns.lperef] = *it; + row[columns.col_visible] = false; + } } } @@ -427,9 +434,11 @@ void LivePathEffectEditor::on_effect_selection_changed() LivePathEffect::LPEObjectReference * lperef = (*it)[columns.lperef]; if (lperef && current_lpeitem) { - lpe_list_locked = true; // prevent reload of the list which would lose selection - sp_lpe_item_set_current_path_effect(current_lpeitem, lperef); - showParams(lperef->lpeobject->lpe); + if (lperef->lpeobject->get_lpe()) { + lpe_list_locked = true; // prevent reload of the list which would lose selection + sp_lpe_item_set_current_path_effect(current_lpeitem, lperef); + showParams(*lperef->lpeobject->get_lpe()); + } } } @@ -440,12 +449,12 @@ void LivePathEffectEditor::on_visibility_toggled( Glib::ustring const& str ) LivePathEffect::LPEObjectReference * lpeobjref = row[columns.lperef]; - if ( lpeobjref ) { + if ( lpeobjref && lpeobjref->lpeobject->get_lpe() ) { bool newValue = !row[columns.col_visible]; row[columns.col_visible] = newValue; /* FIXME: this explicit writing to SVG is wrong. The lpe_item should have a method to disable/enable an effect within its stack. * So one can call: lpe_item->setActive(lpeobjref->lpeobject); */ - lpeobjref->lpeobject->lpe->getRepr()->setAttribute("is_visible", newValue ? "true" : "false"); + lpeobjref->lpeobject->get_lpe()->getRepr()->setAttribute("is_visible", newValue ? "true" : "false"); sp_document_done( sp_desktop_document(current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, newValue ? _("Activate path effect") : _("Deactivate path effect")); } diff --git a/src/ui/dialog/livepatheffect-editor.h b/src/ui/dialog/livepatheffect-editor.h index a924ed6e9..49db74fca 100644 --- a/src/ui/dialog/livepatheffect-editor.h +++ b/src/ui/dialog/livepatheffect-editor.h @@ -53,7 +53,7 @@ private: void set_sensitize_all(bool sensitive); - void showParams(LivePathEffect::Effect* effect); + void showParams(LivePathEffect::Effect& effect); void showText(Glib::ustring const &str); void selectInList(LivePathEffect::Effect* effect); diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 0334b8541..5927dc740 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -457,7 +457,7 @@ Transformation::updatePageMove(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { if (!_check_move_relative.get_active()) { - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { double x = bbox->min()[Geom::X]; double y = bbox->min()[Geom::Y]; @@ -478,10 +478,10 @@ void Transformation::updatePageScale(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { - double w = bbox->extent(Geom::X); - double h = bbox->extent(Geom::Y); + double w = bbox->dimensions()[Geom::X]; + double h = bbox->dimensions()[Geom::Y]; _scalar_scale_horizontal.setHundredPercent(w); _scalar_scale_vertical.setHundredPercent(h); onScaleXValueChanged(); // to update x/y proportionality if switch is on @@ -508,10 +508,10 @@ void Transformation::updatePageSkew(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { - double w = bbox->extent(Geom::X); - double h = bbox->extent(Geom::Y); + double w = bbox->dimensions()[Geom::X]; + double h = bbox->dimensions()[Geom::Y]; _scalar_skew_vertical.setHundredPercent(w); _scalar_skew_horizontal.setHundredPercent(h); _page_skew.set_sensitive(true); @@ -604,7 +604,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection) if (_check_move_relative.get_active()) { sp_selection_move_relative(selection, x, y); } else { - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { sp_selection_move_relative(selection, x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); @@ -625,9 +625,9 @@ Transformation::applyPageMove(Inkscape::Selection *selection) it != selected.end(); ++it) { - boost::optional<NR::Rect> bbox = sp_item_bbox_desktop(*it); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it); if (bbox) { - sorted.push_back(BBoxSort(*it, to_2geom(*bbox), Geom::X, x > 0? 1. : 0., x > 0? 0. : 1.)); + sorted.push_back(BBoxSort(*it, *bbox, Geom::X, x > 0? 1. : 0., x > 0? 0. : 1.)); } } //sort bbox by anchors @@ -649,9 +649,9 @@ Transformation::applyPageMove(Inkscape::Selection *selection) it != selected.end(); ++it) { - boost::optional<NR::Rect> bbox = sp_item_bbox_desktop(*it); + boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop(*it); if (bbox) { - sorted.push_back(BBoxSort(*it, to_2geom(*bbox), Geom::Y, y > 0? 1. : 0., y > 0? 0. : 1.)); + sorted.push_back(BBoxSort(*it, *bbox, Geom::Y, y > 0? 1. : 0., y > 0? 0. : 1.)); } } //sort bbox by anchors @@ -668,7 +668,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection) } } } else { - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { sp_selection_move_relative(selection, x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); @@ -692,13 +692,13 @@ Transformation::applyPageScale(Inkscape::Selection *selection) Geom::Scale scale (0,0); // the values are increments! if (_units_scale.isAbsolute()) { - boost::optional<NR::Rect> bbox(sp_item_bbox_desktop(item)); + boost::optional<Geom::Rect> bbox(sp_item_bbox_desktop(item)); if (bbox) { double new_width = scaleX; if (fabs(new_width) < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object double new_height = scaleY; if (fabs(new_height) < 1e-6) new_height = 1e-6; - scale = Geom::Scale(new_width / bbox->extent(Geom::X), new_height / bbox->extent(Geom::Y)); + scale = Geom::Scale(new_width / bbox->dimensions()[Geom::X], new_height / bbox->dimensions()[Geom::Y]); } } else { double new_width = scaleX; @@ -710,7 +710,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection) sp_item_scale_rel (item, scale); } } else { - boost::optional<NR::Rect> bbox(selection->bounds()); + boost::optional<Geom::Rect> bbox(selection->bounds()); if (bbox) { Geom::Point center(bbox->midpoint()); // use rotation center? Geom::Scale scale (0,0); @@ -720,7 +720,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection) if (fabs(new_width) < 1e-6) new_width = 1e-6; double new_height = scaleY; if (fabs(new_height) < 1e-6) new_height = 1e-6; - scale = Geom::Scale(new_width / bbox->extent(Geom::X), new_height / bbox->extent(Geom::Y)); + scale = Geom::Scale(new_width / bbox->dimensions()[Geom::X], new_height / bbox->dimensions()[Geom::Y]); } else { double new_width = scaleX; if (fabs(new_width) < 1e-6) new_width = 1e-6; @@ -777,21 +777,21 @@ Transformation::applyPageSkew(Inkscape::Selection *selection) } else { // absolute displacement double skewX = _scalar_skew_horizontal.getValue("px"); double skewY = _scalar_skew_vertical.getValue("px"); - boost::optional<NR::Rect> bbox(sp_item_bbox_desktop(item)); + boost::optional<Geom::Rect> bbox(sp_item_bbox_desktop(item)); if (bbox) { - double width = bbox->extent(Geom::X); - double height = bbox->extent(Geom::Y); + double width = bbox->dimensions()[Geom::X]; + double height = bbox->dimensions()[Geom::Y]; sp_item_skew_rel (item, skewX/height, skewY/width); } } } } else { // transform whole selection - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); boost::optional<Geom::Point> center = selection->center(); if ( bbox && center ) { - double width = bbox->extent(Geom::X); - double height = bbox->extent(Geom::Y); + double width = bbox->dimensions()[Geom::X]; + double height = bbox->dimensions()[Geom::Y]; if (!_units_skew.isAbsolute()) { // percentage double skewX = _scalar_skew_horizontal.getValue("%"); @@ -869,7 +869,7 @@ Transformation::onMoveRelativeToggled() //g_message("onMoveRelativeToggled: %f, %f px\n", x, y); - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { if (_check_move_relative.get_active()) { @@ -1009,7 +1009,7 @@ Transformation::onClear() _scalar_move_horizontal.setValue(0); _scalar_move_vertical.setValue(0); } else { - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { _scalar_move_horizontal.setValue(bbox->min()[Geom::X], "px"); _scalar_move_vertical.setValue(bbox->min()[Geom::Y], "px"); diff --git a/src/ui/view/edit-widget.cpp b/src/ui/view/edit-widget.cpp index bd6c5032c..67091fc40 100644 --- a/src/ui/view/edit-widget.cpp +++ b/src/ui/view/edit-widget.cpp @@ -1097,7 +1097,7 @@ EditWidget::initStatusbar() _select_status.property_xalign() = 0.0; _select_status.property_yalign() = 0.5; - _select_status.set_markup (_("<b>Welcome to Inkscape!</b> Use shape or freehand tools to create objects; use selector (arrow) to move or transform them.")); + _select_status.set_markup (_("<b>Welcome to Inkscape!</b> Use shape or drawing tools to create objects; use selector (arrow) to move or transform them.")); // include this again with Gtk+-2.6 #if GTK_VERSION_GE(2,6) gtk_label_set_ellipsize (GTK_LABEL(_select_status.gobj()), PANGO_ELLIPSIZE_END); @@ -1400,18 +1400,20 @@ EditWidget::updateScrollbars (double scale) /* The desktop region we always show unconditionally */ SPDocument *doc = _desktop->doc(); - NR::Rect darea ( Geom::Point(-sp_document_width(doc), -sp_document_height(doc)), + Geom::Rect darea ( Geom::Point(-sp_document_width(doc), -sp_document_height(doc)), Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc)) ); - darea = NR::union_bounds(darea, sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)))); + SPObject* root = doc->root; + SPItem* item = SP_ITEM(root); + boost::optional<Geom::Rect> deskarea = Geom::unify(darea, sp_item_bbox_desktop(item)); /* Canvas region we always show unconditionally */ - NR::Rect carea( Geom::Point(darea.min()[Geom::X] * scale - 64, darea.max()[Geom::Y] * -scale - 64), - Geom::Point(darea.max()[Geom::X] * scale + 64, darea.min()[Geom::Y] * -scale + 64) ); + Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64), + Geom::Point(deskarea->max()[Geom::X] * scale + 64, deskarea->min()[Geom::Y] * -scale + 64) ); Geom::Rect const viewbox = _svg_canvas.spobj()->getViewbox(); /* Viewbox is always included into scrollable region */ - carea = NR::union_bounds(carea, from_2geom(viewbox)); + carea = Geom::unify(carea, viewbox); Gtk::Adjustment *adj = _bottom_scrollbar.get_adjustment(); adj->set_value(viewbox.min()[Geom::X]); diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index d4c1bb705..f2fa9bcd3 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -114,10 +114,10 @@ ObjectCompositeSettings::_blendBlurValueChanged() // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); - boost::optional<NR::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); + boost::optional<Geom::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); double radius; if (bbox) { - double perimeter = bbox->extent(Geom::X) + bbox->extent(Geom::Y); + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? radius = _fe_cb.get_blur_value() * perimeter / 400; } else { radius = 0; @@ -260,9 +260,9 @@ ObjectCompositeSettings::_subjectChanged() { case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: - boost::optional<NR::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); + boost::optional<Geom::Rect> bbox = _subject->getBounds(SPItem::GEOMETRIC_BBOX); if (bbox) { - double perimeter = bbox->extent(Geom::X) + bbox->extent(Geom::Y); + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? _fe_cb.set_blur_sensitive(true); //update blur widget value float radius = query->filter_gaussianBlur_deviation.value; diff --git a/src/ui/widget/style-subject.cpp b/src/ui/widget/style-subject.cpp index 39081b005..a2e8a2547 100644 --- a/src/ui/widget/style-subject.cpp +++ b/src/ui/widget/style-subject.cpp @@ -65,12 +65,12 @@ StyleSubject::iterator StyleSubject::Selection::begin() { } } -boost::optional<NR::Rect> StyleSubject::Selection::getBounds(SPItem::BBoxType type) { +boost::optional<Geom::Rect> StyleSubject::Selection::getBounds(SPItem::BBoxType type) { Inkscape::Selection *selection = _getSelection(); if (selection) { return selection->bounds(type); } else { - return boost::optional<NR::Rect>(); + return boost::optional<Geom::Rect>(); } } @@ -143,12 +143,12 @@ StyleSubject::iterator StyleSubject::CurrentLayer::begin() { return iterator(_getLayerSList()); } -boost::optional<NR::Rect> StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) { +boost::optional<Geom::Rect> StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) { SPObject *layer = _getLayer(); if (layer && SP_IS_ITEM(layer)) { return sp_item_bbox_desktop(SP_ITEM(layer), type); } else { - return boost::optional<NR::Rect>(); + return boost::optional<Geom::Rect>(); } } diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h index 9204a8163..231a88728 100644 --- a/src/ui/widget/style-subject.h +++ b/src/ui/widget/style-subject.h @@ -12,6 +12,7 @@ #include "util/glib-list-iterators.h" #include <boost/optional.hpp> #include "libnr/nr-rect.h" +#include <2geom/rect.h> #include "sp-item.h" #include <sigc++/sigc++.h> @@ -43,7 +44,7 @@ public: virtual iterator begin() = 0; virtual iterator end() { return iterator(NULL); } - virtual boost::optional<NR::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) = 0; + virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) = 0; virtual int queryStyle(SPStyle *query, int property) = 0; virtual void setCSS(SPCSSAttr *css) = 0; @@ -66,7 +67,7 @@ public: ~Selection(); virtual iterator begin(); - virtual boost::optional<NR::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); + virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); virtual int queryStyle(SPStyle *query, int property); virtual void setCSS(SPCSSAttr *css); @@ -87,7 +88,7 @@ public: ~CurrentLayer(); virtual iterator begin(); - virtual boost::optional<NR::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); + virtual boost::optional<Geom::Rect> getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX); virtual int queryStyle(SPStyle *query, int property); virtual void setCSS(SPCSSAttr *css); diff --git a/src/verbs.cpp b/src/verbs.cpp index c1e7e5fc9..55a465fbb 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1308,7 +1308,7 @@ ObjectVerb::perform( SPAction *action, void *data, void */*pdata*/ ) if (sel->isEmpty()) return; - boost::optional<NR::Rect> bbox = sel->bounds(); + boost::optional<Geom::Rect> bbox = sel->bounds(); if (!bbox) { return; } diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index f7e2c3f27..e4190b930 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1724,20 +1724,20 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale) /* The desktop region we always show unconditionally */ SPDocument *doc = dtw->desktop->doc(); - NR::Rect darea(Geom::Point(-sp_document_width(doc), -sp_document_height(doc)), - Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc))); - darea = NR::union_bounds(darea, sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)))); + Geom::Rect darea ( Geom::Point(-sp_document_width(doc), -sp_document_height(doc)), + Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc)) ); + SPObject* root = doc->root; + SPItem* item = SP_ITEM(root); + boost::optional<Geom::Rect> deskarea = Geom::unify(darea, sp_item_bbox_desktop(item)); /* Canvas region we always show unconditionally */ - NR::Rect carea(Geom::Point(darea.min()[Geom::X] * scale - 64, - darea.max()[Geom::Y] * -scale - 64), - Geom::Point(darea.max()[Geom::X] * scale + 64, - darea.min()[Geom::Y] * -scale + 64)); + Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64), + Geom::Point(deskarea->max()[Geom::X] * scale + 64, deskarea->min()[Geom::Y] * -scale + 64) ); Geom::Rect viewbox = dtw->canvas->getViewbox(); /* Viewbox is always included into scrollable region */ - carea = NR::union_bounds(carea, from_2geom(viewbox)); + carea = Geom::unify(carea, viewbox); set_adjustment(dtw->hadj, carea.min()[Geom::X], carea.max()[Geom::X], viewbox.dimensions()[Geom::X], diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 183481cf6..401d76474 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -658,11 +658,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, if (object && SP_IS_ITEM(object)) { /* Find bbox in document */ Geom::Matrix const i2doc(sp_item_i2doc_affine(SP_ITEM(object))); - boost::optional<NR::Rect> nrdbox = SP_ITEM(object)->getBounds(i2doc); - boost::optional<Geom::Rect> dbox; - if (nrdbox) { - dbox = to_2geom(*nrdbox); - } + boost::optional<Geom::Rect> dbox = SP_ITEM(object)->getBounds(i2doc); if ( SP_OBJECT_PARENT(object) == NULL ) { @@ -676,7 +672,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, /* Update to renderable state */ double sf = 1.0; nr_arena_item_set_transform(root, (Geom::Matrix)Geom::Scale(sf, sf)); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update( root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE ); @@ -708,7 +704,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, sf = (double)psize / (double)block; nr_arena_item_set_transform(root, (Geom::Matrix)Geom::Scale(sf, sf)); - gc.transform.set_identity(); + gc.transform.setIdentity(); nr_arena_item_invoke_update( root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE ); diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index e413aa39e..5f43f7925 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -68,7 +68,7 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) int prefs_bbox = prefs_get_int_attribute("tools", "bounding_box", 0); SPItem::BBoxType bbox_type = (prefs_bbox ==0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - boost::optional<NR::Rect> const bbox(sel->bounds(bbox_type)); + boost::optional<Geom::Rect> const bbox(sel->bounds(bbox_type)); if ( bbox && !bbox->isEmpty() ) { UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(G_OBJECT(spw), "tracker")); SPUnit const &unit = *tracker->getActiveUnit(); @@ -76,8 +76,8 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) struct { char const *key; double val; } const keyval[] = { { "X", bbox->min()[X] }, { "Y", bbox->min()[Y] }, - { "width", bbox->extent(X) }, - { "height", bbox->extent(Y) } + { "width", bbox->dimensions()[X] }, + { "height", bbox->dimensions()[Y] } }; if (unit.base == SP_UNIT_DIMENSIONLESS) { @@ -158,7 +158,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) int prefs_bbox = prefs_get_int_attribute("tools", "bounding_box", 0); SPItem::BBoxType bbox_type = (prefs_bbox ==0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - boost::optional<NR::Rect> bbox = selection->bounds(bbox_type); + boost::optional<Geom::Rect> bbox = selection->bounds(bbox_type); if ( !bbox || bbox->isEmpty() ) { g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); @@ -182,27 +182,27 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) x0 = sp_units_get_pixels (a_x->value, unit); y0 = sp_units_get_pixels (a_y->value, unit); x1 = x0 + sp_units_get_pixels (a_w->value, unit); - xrel = sp_units_get_pixels (a_w->value, unit) / bbox->extent(Geom::X); + xrel = sp_units_get_pixels (a_w->value, unit) / bbox->dimensions()[Geom::X]; y1 = y0 + sp_units_get_pixels (a_h->value, unit); - yrel = sp_units_get_pixels (a_h->value, unit) / bbox->extent(Geom::Y); + yrel = sp_units_get_pixels (a_h->value, unit) / bbox->dimensions()[Geom::Y]; } else { double const x0_propn = a_x->value * unit.unittobase; x0 = bbox->min()[Geom::X] * x0_propn; double const y0_propn = a_y->value * unit.unittobase; y0 = y0_propn * bbox->min()[Geom::Y]; xrel = a_w->value * unit.unittobase; - x1 = x0 + xrel * bbox->extent(Geom::X); + x1 = x0 + xrel * bbox->dimensions()[Geom::X]; yrel = a_h->value * unit.unittobase; - y1 = y0 + yrel * bbox->extent(Geom::Y); + y1 = y0 + yrel * bbox->dimensions()[Geom::Y]; } // Keep proportions if lock is on GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") ); if ( gtk_toggle_action_get_active(lock) ) { if (adj == a_h) { - x1 = x0 + yrel * bbox->extent(Geom::X); + x1 = x0 + yrel * bbox->dimensions()[Geom::X]; } else if (adj == a_w) { - y1 = y0 + xrel * bbox->extent(Geom::Y); + y1 = y0 + xrel * bbox->dimensions()[Geom::Y]; } } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 0749d4c66..b70684692 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -3774,6 +3774,14 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction 2, "tweak_colorjitter_mode", -1 ); + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Blur mode"), + 1, _("Blur selected objects more; with Shift, blur less"), + 2, "tweak_blur_mode", + -1 ); + + EgeSelectOneAction* act = ege_select_one_action_new( "TweakModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) ); g_object_set( act, "short_label", _("Mode:"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); @@ -5007,7 +5015,7 @@ lpetool_toggle_set_bbox (GtkToggleAction *act, gpointer data) { SPDesktop *desktop = static_cast<SPDesktop *>(data); Inkscape::Selection *selection = desktop->selection; - boost::optional<NR::Rect> bbox = selection->bounds(); + boost::optional<Geom::Rect> bbox = selection->bounds(); if (bbox) { Geom::Point A(bbox->min()); @@ -5230,6 +5238,13 @@ static void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActi //## Eraser ## //######################## +static void sp_erc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "tools.eraser", "width", adj->value * 0.01 ); + update_presets_list(tbl); +} + static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) { SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); @@ -5266,7 +5281,7 @@ static void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-eraser", 1, 100, 1.0, 0.0, labels, values, G_N_ELEMENTS(labels), - sp_ddc_width_value_changed, 0.01, 0, 100 ); + sp_erc_width_value_changed, 0.01, 0, 100 ); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); @@ -6401,8 +6416,7 @@ static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) { SPItem *item = reinterpret_cast<SPItem *>(iter->data); Geom::Matrix m = Geom::identity(); - NR::Matrix m_NR = from_2geom(m); - avoid_item_move(&m_NR, item); + avoid_item_move(&m, item); } if (items) { |
