diff options
| author | Arcadie M. Cracan <acracan@gmail.com> | 2009-12-27 11:31:36 +0000 |
|---|---|---|
| committer | Arcadie M. Cracan <acracan@gmail.com> | 2009-12-27 11:31:36 +0000 |
| commit | 30eaa4a74569f4fc5ee802ee3883201379c18235 (patch) | |
| tree | af9d0af2df52735f67a9f4af1a821f6d2fe2f242 /src | |
| parent | Connector tool: make connectors avoid the convex hull of shapes. (diff) | |
| parent | Warning cleanup (diff) | |
| download | inkscape-30eaa4a74569f4fc5ee802ee3883201379c18235.tar.gz inkscape-30eaa4a74569f4fc5ee802ee3883201379c18235.zip | |
Connector tool: make connectors avoid the convex hull of shapes.
(bzr r8857.1.2)
Diffstat (limited to 'src')
177 files changed, 3346 insertions, 2714 deletions
diff --git a/src/2geom/path-intersection.cpp b/src/2geom/path-intersection.cpp index b2d5ceabb..2e4eba519 100644 --- a/src/2geom/path-intersection.cpp +++ b/src/2geom/path-intersection.cpp @@ -41,16 +41,16 @@ int winding(Path const &path, Point p) { starting = false; Rect bounds = *(iter->boundsFast()); Coord x = p[X], y = p[Y]; - + if(x > bounds.right() || !bounds[Y].contains(y)) continue; //ray doesn't intersect box - + Point final = iter->finalPoint(); Point initial = iter->initialPoint(); Cmp final_to_ray = cmp(final[Y], y); Cmp initial_to_ray = cmp(initial[Y], y); - + // if y is included, these will have opposite values, giving order. - Cmp c = cmp(final_to_ray, initial_to_ray); + Cmp c = cmp(final_to_ray, initial_to_ray); if(x < bounds.left()) { // ray goes through bbox // winding delta determined by position of endpoints @@ -100,7 +100,7 @@ int winding(Path const &path, Point p) { //Looks like it looped, which means everything's flat return 0; } - + cont:(void)0; } return wind; @@ -118,7 +118,7 @@ bool path_direction(Path const &p) { double x = p.initialPoint()[X]; Cmp res = cmp(p[0].finalPoint()[Y], y); goto doh; - for(unsigned i = 1; i <= p.size(); i++) { + for(unsigned i = 1; i < p.size(); i++) { Cmp final_to_ray = cmp(p[i].finalPoint()[Y], y); Cmp initial_to_ray = cmp(p[i].initialPoint()[Y], y); // if y is included, these will have opposite values, giving order. @@ -135,10 +135,10 @@ bool path_direction(Path const &p) { } else if(final_to_ray == EQUAL_TO) goto doh; } return res < 0; - + doh: //Otherwise fallback on area - + Piecewise<D2<SBasis> > pw = p.toPwSb(); double area; Point centre; @@ -214,36 +214,34 @@ intersect_polish_f (const gsl_vector * x, void *params, { const double x0 = gsl_vector_get (x, 0); const double x1 = gsl_vector_get (x, 1); - - Geom::Point dx = ((struct rparams *) params)->A(x0) - + + Geom::Point dx = ((struct rparams *) params)->A(x0) - ((struct rparams *) params)->B(x1); - + gsl_vector_set (f, 0, dx[0]); gsl_vector_set (f, 1, dx[1]); - + return GSL_SUCCESS; } #endif -static void +static void intersect_polish_root (Curve const &A, double &s, Curve const &B, double &t) { - int status; - size_t iter = 0; std::vector<Point> as, bs; as = A.pointAndDerivatives(s, 2); bs = B.pointAndDerivatives(t, 2); Point F = as[0] - bs[0]; double best = dot(F, F); - + for(int i = 0; i < 4; i++) { - + /** we want to solve J*(x1 - x0) = f(x0) - + |dA(s)[0] -dB(t)[0]| (X1 - X0) = A(s) - B(t) - |dA(s)[1] -dB(t)[1]| + |dA(s)[1] -dB(t)[1]| **/ // We're using the standard transformation matricies, which is numerically rather poor. Much better to solve the equation using elimination. @@ -259,7 +257,7 @@ intersect_polish_root (Curve const &A, double &s, else if (ns>1) ns=1; if (nt<0) nt=0; else if (nt>1) nt=1; - + as = A.pointAndDerivatives(ns, 2); bs = B.pointAndDerivatives(nt, 2); F = as[0] - bs[0]; @@ -277,33 +275,35 @@ intersect_polish_root (Curve const &A, double &s, const size_t n = 2; struct rparams p = {A, B}; gsl_multiroot_function f = {&intersect_polish_f, n, &p}; - + double x_init[2] = {s, t}; gsl_vector *x = gsl_vector_alloc (n); - + gsl_vector_set (x, 0, x_init[0]); gsl_vector_set (x, 1, x_init[1]); - + const gsl_multiroot_fsolver_type *T = gsl_multiroot_fsolver_hybrids; gsl_multiroot_fsolver *sol = gsl_multiroot_fsolver_alloc (T, 2); gsl_multiroot_fsolver_set (sol, &f, x); - + + int status = 0; + size_t iter = 0; do { iter++; status = gsl_multiroot_fsolver_iterate (sol); - + if (status) /* check if solver is stuck */ break; - + status = gsl_multiroot_test_residual (sol->f, 1e-12); } while (status == GSL_CONTINUE && iter < 1000); - + s = gsl_vector_get (sol->x, 0); t = gsl_vector_get (sol->x, 1); - + gsl_multiroot_fsolver_free (sol); gsl_vector_free (x); } @@ -315,7 +315,7 @@ intersect_polish_root (Curve const &A, double &s, * It passes in the curves, time intervals, and keeps track of depth, while * returning the results through the Crossings parameter. */ -void pair_intersect(Curve const & A, double Al, double Ah, +void pair_intersect(Curve const & A, double Al, double Ah, Curve const & B, double Bl, double Bh, Crossings &ret, unsigned depth = 0) { // std::cout << depth << "(" << Al << ", " << Ah << ")\n"; @@ -324,15 +324,15 @@ void pair_intersect(Curve const & A, double Al, double Ah, OptRect Br = B.boundsLocal(Interval(Bl, Bh)); if (!Br) return; - + if(! Ar->intersects(*Br)) return; - + //Checks the general linearity of the function - if((depth > 12)) { // || (A.boundsLocal(Interval(Al, Ah), 1).maxExtent() < 0.1 + if((depth > 12)) { // || (A.boundsLocal(Interval(Al, Ah), 1).maxExtent() < 0.1 //&& B.boundsLocal(Interval(Bl, Bh), 1).maxExtent() < 0.1)) { double tA, tB, c; - if(linear_intersect(A.pointAt(Al), A.pointAt(Ah), - B.pointAt(Bl), B.pointAt(Bh), + if(linear_intersect(A.pointAt(Al), A.pointAt(Ah), + B.pointAt(Bl), B.pointAt(Bh), tA, tB, c)) { tA = tA * (Ah - Al) + Al; tB = tB * (Bh - Bl) + Bl; @@ -385,8 +385,8 @@ void mono_intersect(Curve const &A, double Al, double Ah, if(depth > 12 || (Ar.maxExtent() < tol && Ar.maxExtent() < tol)) { double tA, tB, c; - if(linear_intersect(A.pointAt(Al), A.pointAt(Ah), - B.pointAt(Bl), B.pointAt(Bh), + if(linear_intersect(A.pointAt(Al), A.pointAt(Ah), + B.pointAt(Bl), B.pointAt(Bh), tA, tB, c)) { tA = tA * (Ah - Al) + Al; tB = tB * (Bh - Bl) + Bl; @@ -483,9 +483,9 @@ std::vector<double> offset_doubles(std::vector<double> const &x, double offs) { std::vector<double> path_mono_splits(Path const &p) { std::vector<double> ret; if(p.empty()) return ret; - + bool pdx=2, pdy=2; //Previous derivative direction - for(unsigned i = 0; i <= p.size(); i++) { + for(unsigned i = 0; i < p.size(); i++) { std::vector<double> spl = offset_doubles(curve_mono_splits(p[i]), i); bool dx = p[i].initialPoint()[X] > (spl.empty()? p[i].finalPoint()[X] : p.valueAt(spl.front(), X)); @@ -502,7 +502,7 @@ std::vector<double> path_mono_splits(Path const &p) { } /** - * Applies path_mono_splits to multiple paths, and returns the results such that + * Applies path_mono_splits to multiple paths, and returns the results such that * time-set i corresponds to Path i. */ std::vector<std::vector<double> > paths_mono_splits(std::vector<Path> const &ps) { @@ -541,14 +541,14 @@ CrossingSet MonoCrosser::crossings(std::vector<Path> const &a, std::vector<Path> if(b.empty()) return CrossingSet(a.size(), Crossings()); CrossingSet results(a.size() + b.size(), Crossings()); if(a.empty()) return results; - + std::vector<std::vector<double> > splits_a = paths_mono_splits(a), splits_b = paths_mono_splits(b); std::vector<std::vector<Rect> > bounds_a = split_bounds(a, splits_a), bounds_b = split_bounds(b, splits_b); - - std::vector<Rect> bounds_a_union, bounds_b_union; + + std::vector<Rect> bounds_a_union, bounds_b_union; for(unsigned i = 0; i < bounds_a.size(); i++) bounds_a_union.push_back(union_list(bounds_a[i])); for(unsigned i = 0; i < bounds_b.size(); i++) bounds_b_union.push_back(union_list(bounds_b[i])); - + std::vector<std::vector<unsigned> > cull = sweep_bounds(bounds_a_union, bounds_b_union); Crossings n; for(unsigned i = 0; i < cull.size(); i++) { @@ -556,7 +556,7 @@ CrossingSet MonoCrosser::crossings(std::vector<Path> const &a, std::vector<Path> unsigned j = cull[i][jx]; unsigned jc = j + a.size(); Crossings res; - + //Sweep of the monotonic portions std::vector<std::vector<unsigned> > cull2 = sweep_bounds(bounds_a[i], bounds_b[j]); for(unsigned k = 0; k < cull2.size(); k++) { @@ -567,9 +567,9 @@ CrossingSet MonoCrosser::crossings(std::vector<Path> const &a, std::vector<Path> res, .1); } } - + for(unsigned k = 0; k < res.size(); k++) { res[k].a = i; res[k].b = jc; } - + merge_crossings(results[i], res, i); merge_crossings(results[i], res, jc); } @@ -583,22 +583,22 @@ CrossingSet MonoCrosser::crossings(std::vector<Path> const &a, std::vector<Path> CrossingSet crossings_among(std::vector<Path> const &p) { CrossingSet results(p.size(), Crossings()); if(p.empty()) return results; - + std::vector<std::vector<double> > splits = paths_mono_splits(p); std::vector<std::vector<Rect> > prs = split_bounds(p, splits); std::vector<Rect> rs; for(unsigned i = 0; i < prs.size(); i++) rs.push_back(union_list(prs[i])); - + std::vector<std::vector<unsigned> > cull = sweep_bounds(rs); - + //we actually want to do the self-intersections, so add em in: for(unsigned i = 0; i < cull.size(); i++) cull[i].push_back(i); - + for(unsigned i = 0; i < cull.size(); i++) { for(unsigned jx = 0; jx < cull[i].size(); jx++) { unsigned j = cull[i][jx]; Crossings res; - + //Sweep of the monotonic portions std::vector<std::vector<unsigned> > cull2 = sweep_bounds(prs[i], prs[j]); for(unsigned k = 0; k < cull2.size(); k++) { @@ -609,14 +609,14 @@ CrossingSet crossings_among(std::vector<Path> const &p) { res, .1); } } - + for(unsigned k = 0; k < res.size(); k++) { res[k].a = i; res[k].b = j; } - + merge_crossings(results[i], res, i); merge_crossings(results[j], res, j); } } - + return results; } */ @@ -635,7 +635,7 @@ Crossings curve_self_crossings(Curve const &a) { } /* -void mono_curve_intersect(Curve const & A, double Al, double Ah, +void mono_curve_intersect(Curve const & A, double Al, double Ah, Curve const & B, double Bl, double Bh, Crossings &ret, unsigned depth=0) { // std::cout << depth << "(" << Al << ", " << Ah << ")\n"; @@ -643,9 +643,9 @@ void mono_curve_intersect(Curve const & A, double Al, double Ah, B0 = B.pointAt(Bl), B1 = B.pointAt(Bh); //inline code that this implies? (without rect/interval construction) if(!Rect(A0, A1).intersects(Rect(B0, B1)) || A0 == A1 || B0 == B1) return; - + //Checks the general linearity of the function - if((depth > 12) || (A.boundsLocal(Interval(Al, Ah), 1).maxExtent() < 0.1 + if((depth > 12) || (A.boundsLocal(Interval(Al, Ah), 1).maxExtent() < 0.1 && B.boundsLocal(Interval(Bl, Bh), 1).maxExtent() < 0.1)) { double tA, tB, c; if(linear_intersect(A0, A1, B0, B1, tA, tB, c)) { @@ -705,7 +705,7 @@ Crossings path_self_crossings(Path const &p) { for(unsigned jx = 0; jx < cull[i].size(); jx++) { unsigned j = cull[i][jx]; res.clear(); - + std::vector<std::vector<unsigned> > cull2 = sweep_bounds(bnds[i], bnds[j]); for(unsigned k = 0; k < cull2.size(); k++) { for(unsigned lx = 0; lx < cull2[k].size(); lx++) { @@ -713,7 +713,7 @@ Crossings path_self_crossings(Path const &p) { mono_curve_intersect(p[i], spl[i][k-1], spl[i][k], p[j], spl[j][l-1], spl[j][l], res); } } - + //if(fabs(int(i)-j) == 1 || fabs(int(i)-j) == p.size()-1) { Crossings res2; for(unsigned k = 0; k < res.size(); k++) { @@ -742,7 +742,7 @@ Crossings self_crossings(Path const &p) { unsigned j = cull[i][jx]; res.clear(); pair_intersect(p[i], 0, 1, p[j], 0, 1, res); - + //if(fabs(int(i)-j) == 1 || fabs(int(i)-j) == p.size()-1) { Crossings res2; for(unsigned k = 0; k < res.size(); k++) { @@ -767,9 +767,9 @@ void flip_crossings(Crossings &crs) { CrossingSet crossings_among(std::vector<Path> const &p) { CrossingSet results(p.size(), Crossings()); if(p.empty()) return results; - + SimpleCrosser cc; - + std::vector<std::vector<unsigned> > cull = sweep_bounds(bounds(p)); for(unsigned i = 0; i < cull.size(); i++) { Crossings res = self_crossings(p[i]); @@ -779,7 +779,7 @@ CrossingSet crossings_among(std::vector<Path> const &p) { merge_crossings(results[i], res, i); for(unsigned jx = 0; jx < cull[i].size(); jx++) { unsigned j = cull[i][jx]; - + Crossings res = cc.crossings(p[i], p[j]); for(unsigned k = 0; k < res.size(); k++) { res[k].a = i; res[k].b = j; } merge_crossings(results[i], res, i); diff --git a/src/Makefile_insert b/src/Makefile_insert index da49187ba..b32889f65 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -271,6 +271,7 @@ CXXTEST_TESTSUITES += \ $(srcdir)/color-profile-test.h \ $(srcdir)/dir-util-test.h \ $(srcdir)/extract-uri-test.h \ + $(srcdir)/marker-test.h \ $(srcdir)/mod360-test.h \ $(srcdir)/round-test.h \ $(srcdir)/preferences-test.h \ diff --git a/src/bind/javabind.cpp b/src/bind/javabind.cpp index f7022584f..6dc8c9a9b 100644 --- a/src/bind/javabind.cpp +++ b/src/bind/javabind.cpp @@ -1010,6 +1010,7 @@ bool JavaBinderyImpl::callStatic(int type, default: { err("Unknown value type: %d", v.getType()); + delete [] jvals; return false; } } @@ -1057,7 +1058,7 @@ bool JavaBinderyImpl::callStatic(int type, return false; } } - delete jvals; + delete [] jvals; String errStr = getException(); if (errStr.size()>0) { @@ -1131,6 +1132,7 @@ bool JavaBinderyImpl::callInstance( default: { err("Unknown value type: %d", v.getType()); + delete [] jvals; return false; } } @@ -1178,7 +1180,7 @@ bool JavaBinderyImpl::callInstance( return false; } } - delete jvals; + delete [] jvals; String errStr = getException(); if (errStr.size()>0) { diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp index e3476deb3..c8fbfa877 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -123,16 +123,17 @@ static void sp_box3d_context_init(Box3DContext *box3d_context) static void sp_box3d_context_finish(SPEventContext *ec) { - Box3DContext *bc = SP_BOX3D_CONTEXT(ec); - SPDesktop *desktop = ec->desktop; + Box3DContext *bc = SP_BOX3D_CONTEXT(ec); + SPDesktop *desktop = ec->desktop; - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME); - sp_box3d_finish(bc); + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME); + sp_box3d_finish(bc); bc->sel_changed_connection.disconnect(); +// sp_repr_remove_listener_by_data(cc->active_shape_repr, cc); if (((SPEventContextClass *) parent_class)->finish) { - ((SPEventContextClass *) parent_class)->finish(ec); - } + ((SPEventContextClass *) parent_class)->finish(ec); + } } @@ -179,13 +180,14 @@ static void sp_box3d_context_selection_changed(Inkscape::Selection *selection, g if (selection->perspList().size() == 1) { // selecting a single box changes the current perspective - ec->desktop->doc()->current_persp3d = selection->perspList().front(); + ec->desktop->doc()->setCurrentPersp3D(selection->perspList().front()); } } -/* create a default perspective in document defs if none is present - (can happen after 'vacuum defs' or when a pre-0.46 file is opened) */ -static void sp_box3d_context_check_for_persp_in_defs(SPDocument *document) { +/* Create a default perspective in document defs if none is present (which can happen, among other + * circumstances, after 'vacuum defs' or when a pre-0.46 file is opened). + */ +static void sp_box3d_context_ensure_persp_in_defs(SPDocument *document) { SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document); bool has_persp = false; @@ -197,7 +199,7 @@ static void sp_box3d_context_check_for_persp_in_defs(SPDocument *document) { } if (!has_persp) { - document->current_persp3d = persp3d_create_xml_element (document); + document->setCurrentPersp3D(persp3d_create_xml_element (document)); } } @@ -209,8 +211,6 @@ static void sp_box3d_context_setup(SPEventContext *ec) ((SPEventContextClass *) parent_class)->setup(ec); } - sp_box3d_context_check_for_persp_in_defs(sp_desktop_document (ec->desktop)); - ec->shape_editor = new ShapeEditor(ec->desktop); SPItem *item = sp_desktop_selection(ec->desktop)->singleItem(); @@ -267,13 +267,13 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven static bool dragging; SPDesktop *desktop = event_context->desktop; + SPDocument *document = sp_desktop_document (desktop); Inkscape::Selection *selection = sp_desktop_selection (desktop); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); Box3DContext *bc = SP_BOX3D_CONTEXT(event_context); - g_assert (SP_ACTIVE_DOCUMENT->current_persp3d); - Persp3D *cur_persp = SP_ACTIVE_DOCUMENT->current_persp3d; + Persp3D *cur_persp = document->getCurrentPersp3D(); event_context->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -300,8 +300,14 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven bc->drag_ptB = from_2geom(button_dt); bc->drag_ptC = from_2geom(button_dt); + // This can happen after saving when the last remaining perspective was purged and must be recreated. + if (!cur_persp) { + sp_box3d_context_ensure_persp_in_defs(document); + cur_persp = document->getCurrentPersp3D(); + } + /* Projective preimages of clicked point under current perspective */ - bc->drag_origin_proj = cur_persp->tmat.preimage (from_2geom(button_dt), 0, Proj::Z); + bc->drag_origin_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(button_dt), 0, Proj::Z); bc->drag_ptB_proj = bc->drag_origin_proj; bc->drag_ptC_proj = bc->drag_origin_proj; bc->drag_ptC_proj.normalize(); @@ -355,7 +361,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven bc->drag_ptB = from_2geom(motion_dt); bc->drag_ptC = from_2geom(motion_dt); - bc->drag_ptB_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), 0, Proj::Z); + bc->drag_ptB_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(motion_dt), 0, Proj::Z); bc->drag_ptC_proj = bc->drag_ptB_proj; bc->drag_ptC_proj.normalize(); bc->drag_ptC_proj[Proj::Z] = 0.25; @@ -364,16 +370,16 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven // perspective line from drag_ptB to vanishing point Y. if (!bc->ctrl_dragged) { /* snapping */ - Box3D::PerspectiveLine pline (bc->drag_ptB, Proj::Z, SP_ACTIVE_DOCUMENT->current_persp3d); + Box3D::PerspectiveLine pline (bc->drag_ptB, Proj::Z, document->getCurrentPersp3D()); bc->drag_ptC = pline.closest_to (from_2geom(motion_dt)); bc->drag_ptB_proj.normalize(); - bc->drag_ptC_proj = cur_persp->tmat.preimage (bc->drag_ptC, bc->drag_ptB_proj[Proj::X], Proj::X); + bc->drag_ptC_proj = cur_persp->perspective_impl->tmat.preimage (bc->drag_ptC, bc->drag_ptB_proj[Proj::X], Proj::X); } else { bc->drag_ptC = from_2geom(motion_dt); bc->drag_ptB_proj.normalize(); - bc->drag_ptC_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X); + bc->drag_ptC_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X); } Geom::Point pt2g = to_2geom(bc->drag_ptC); m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE); @@ -424,43 +430,43 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven break; case GDK_bracketright: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, -180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::X, -180/snaps, MOD__ALT); + sp_document_done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_bracketleft: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, 180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::X, 180/snaps, MOD__ALT); + sp_document_done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_parenright: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, -180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Y, -180/snaps, MOD__ALT); + sp_document_done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_parenleft: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, 180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Y, 180/snaps, MOD__ALT); + sp_document_done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_braceright: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, -180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Z, -180/snaps, MOD__ALT); + sp_document_done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_braceleft: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, 180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Z, 180/snaps, MOD__ALT); + sp_document_done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; @@ -468,7 +474,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven /* TODO: what is this??? case GDK_O: if (MOD__CTRL && MOD__SHIFT) { - Box3D::create_canvas_point(persp3d_get_VP(inkscape_active_document()->current_persp3d, Proj::W).affine(), + Box3D::create_canvas_point(persp3d_get_VP(document()->getCurrentPersp3D(), Proj::W).affine(), 6, 0xff00ff00); } ret = true; @@ -483,6 +489,16 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven } break; + case GDK_p: + case GDK_P: + if (MOD__SHIFT_ONLY) { + if (document->getCurrentPersp3D()) { + persp3d_print_debugging_info (document->getCurrentPersp3D()); + } + ret = true; + } + break; + case GDK_x: case GDK_X: if (MOD__ALT_ONLY) { @@ -598,7 +614,7 @@ static void sp_box3d_drag(Box3DContext &bc, guint /*state*/) // TODO: It would be nice to show the VPs during dragging, but since there is no selection // at this point (only after finishing the box), we must do this "manually" - /**** bc._vpdrag->updateDraggers(); ****/ + /* bc._vpdrag->updateDraggers(); */ sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5); } @@ -631,7 +647,7 @@ static void sp_box3d_finish(Box3DContext *bc) if ( bc->item != NULL ) { SPDesktop * desktop = SP_EVENT_CONTEXT_DESKTOP(bc); SPDocument *doc = sp_desktop_document(desktop); - if (!doc || !doc->current_persp3d) + if (!doc || !doc->getCurrentPersp3D()) return; SPBox3D *box = SP_BOX3D(bc->item); diff --git a/src/box3d.cpp b/src/box3d.cpp index 93efa5c35..aa2dc55e3 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -127,10 +127,8 @@ box3d_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) // TODO: Create/link to the correct perspective SPDocument *doc = SP_OBJECT_DOCUMENT(box); - if (!doc) { - g_print ("No document for the box!!!!\n"); + if (!doc) return; - } box->persp_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(box3d_ref_changed), box)); @@ -150,13 +148,33 @@ box3d_release(SPObject *object) if (box->persp_href) { g_free(box->persp_href); } + + // We have to store this here because the Persp3DReference gets destroyed below, but we need to + // access it to call persp3d_remove_box(), which cannot be called earlier because the reference + // needs to be destroyed first. + Persp3D *persp = box3d_get_perspective(box); + if (box->persp_ref) { box->persp_ref->detach(); delete box->persp_ref; box->persp_ref = NULL; } - //persp3d_remove_box (box3d_get_perspective(box), box); + if (persp) { + persp3d_remove_box (persp, box); + /* + // TODO: This deletes a perspective when the last box referring to it is gone. Eventually, + // it would be nice to have this but currently it crashes when undoing/redoing box deletion + // Reason: When redoing a box deletion, the associated perspective is deleted twice, first + // by the following code and then again by the redo mechanism! Perhaps we should perform + // deletion of the perspective from another location "outside" the undo/redo mechanism? + if (persp->perspective_impl->boxes.empty()) { + SPDocument *doc = SP_OBJECT_DOCUMENT(box); + persp->deleteObject(); + doc->setCurrentPersp3D(persp3d_document_first_persp(doc)); + } + */ + } if (((SPObjectClass *) parent_class)->release) ((SPObjectClass *) parent_class)->release(object); @@ -226,16 +244,10 @@ box3d_ref_changed(SPObject *old_ref, SPObject *ref, SPBox3D *box) if (old_ref) { sp_signal_disconnect_by_data(old_ref, box); persp3d_remove_box (SP_PERSP3D(old_ref), box); - /* Note: This sometimes leads to attempts to remove boxes twice from the list of selected/transformed - boxes in a perspectives, but this should be uncritical. */ - persp3d_remove_box_transform (SP_PERSP3D(old_ref), box); } if ( SP_IS_PERSP3D(ref) && ref != box ) // FIXME: Comparisons sane? { persp3d_add_box (SP_PERSP3D(ref), box); - /* Note: This sometimes leads to attempts to add boxes twice to the list of selected/transformed - boxes in a perspectives, but this should be uncritical. */ - persp3d_add_box_transform (SP_PERSP3D(ref), box); } } @@ -278,7 +290,7 @@ static Inkscape::XML::Node *box3d_write(SPObject *object, Inkscape::XML::Documen repr->setAttribute("inkscape:perspectiveID", uri_string); g_free(uri_string); } else { - Inkscape::XML::Node *persp_repr = SP_OBJECT_REPR(doc->current_persp3d); + Inkscape::XML::Node *persp_repr = SP_OBJECT_REPR(doc->getCurrentPersp3D()); const gchar *persp_id = persp_repr->attribute("id"); gchar *href = g_strdup_printf("#%s", persp_id); repr->setAttribute("inkscape:perspectiveID", href); @@ -331,37 +343,8 @@ box3d_set_transform(SPItem *item, Geom::Matrix const &xform) { SPBox3D *box = SP_BOX3D(item); - /* check whether we need to unlink any boxes from their perspectives */ - Persp3D *persp = box3d_get_perspective(box); - Persp3D *transf_persp; - - if (sp_desktop_document(inkscape_active_desktop()) == SP_OBJECT_DOCUMENT(item) && - !persp3d_has_all_boxes_in_selection (persp)) { - std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList(); - - /* create a new perspective as a copy of the current one and link the selected boxes to it */ - transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp); - - for (std::list<SPBox3D *>::iterator b = selboxes.begin(); b != selboxes.end(); ++b) { - box3d_switch_perspectives(*b, persp, transf_persp); - } - } else { - transf_persp = persp; - } - - /* only transform the perspective once, even if it has several selected boxes */ - if(!persp3d_was_transformed (transf_persp)) { - /* concatenate the affine transformation with the perspective mapping; this - function also triggers repr updates of boxes and the perspective itself */ - persp3d_apply_affine_transformation(transf_persp, xform); - } - - box3d_mark_transformed(box); - - if (persp3d_all_transformed(transf_persp)) { - /* all boxes were transformed; make perspective sensitive for further transformations */ - persp3d_unset_transforms(transf_persp); - } + // We don't apply the transform to the box directly but instead to its perspective (which is + // done in sp_selection_apply_affine). Here we only adjust strokes, patterns, etc. Geom::Matrix ret(Geom::Matrix(xform).without_translation()); gdouble const sw = hypot(ret[0], ret[1]); @@ -412,9 +395,9 @@ box3d_get_corner_screen (SPBox3D const *box, guint id, bool item_coords) { } Geom::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(box))); if (item_coords) { - return box3d_get_perspective(box)->tmat.image(proj_corner).affine() * i2d.inverse(); + return box3d_get_perspective(box)->perspective_impl->tmat.image(proj_corner).affine() * i2d.inverse(); } else { - return box3d_get_perspective(box)->tmat.image(proj_corner).affine(); + return box3d_get_perspective(box)->perspective_impl->tmat.image(proj_corner).affine(); } } @@ -435,7 +418,7 @@ box3d_get_center_screen (SPBox3D *box) { return Geom::Point (NR_HUGE, NR_HUGE); } Geom::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(box))); - return box3d_get_perspective(box)->tmat.image(proj_center).affine() * i2d.inverse(); + return box3d_get_perspective(box)->perspective_impl->tmat.image(proj_center).affine() * i2d.inverse(); } /* @@ -461,13 +444,13 @@ box3d_snap (SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &sta Proj::Pt3 D_proj (x_coord, y_coord + diff_y, z_coord, 1.0); Proj::Pt3 E_proj (x_coord - diff_x, y_coord + diff_y, z_coord, 1.0); - Persp3D *persp = box3d_get_perspective(box); - Geom::Point A = persp->tmat.image(A_proj).affine(); - Geom::Point B = persp->tmat.image(B_proj).affine(); - Geom::Point C = persp->tmat.image(C_proj).affine(); - Geom::Point D = persp->tmat.image(D_proj).affine(); - Geom::Point E = persp->tmat.image(E_proj).affine(); - Geom::Point pt = persp->tmat.image(pt_proj).affine(); + Persp3DImpl *persp_impl = box3d_get_perspective(box)->perspective_impl; + Geom::Point A = persp_impl->tmat.image(A_proj).affine(); + Geom::Point B = persp_impl->tmat.image(B_proj).affine(); + Geom::Point C = persp_impl->tmat.image(C_proj).affine(); + Geom::Point D = persp_impl->tmat.image(D_proj).affine(); + Geom::Point E = persp_impl->tmat.image(E_proj).affine(); + Geom::Point pt = persp_impl->tmat.image(pt_proj).affine(); // TODO: Replace these lines between corners with lines from a corner to a vanishing point // (this might help to prevent rounding errors if the box is small) @@ -523,7 +506,7 @@ box3d_snap (SPBox3D *box, int id, Proj::Pt3 const &pt_proj, Proj::Pt3 const &sta remember_snap_index = snap_index; result = snap_pts[snap_index]; } - return box3d_get_perspective(box)->tmat.preimage (result, z_coord, Proj::Z); + return box3d_get_perspective(box)->perspective_impl->tmat.preimage (result, z_coord, Proj::Z); } void @@ -535,8 +518,9 @@ box3d_set_corner (SPBox3D *box, const guint id, Geom::Point const &new_pos, cons /* update corners 0 and 7 according to which handle was moved and to the axes of movement */ if (!(movement & Box3D::Z)) { - Proj::Pt3 pt_proj (box3d_get_perspective(box)->tmat.preimage (new_pos, (id < 4) ? box->orig_corner0[Proj::Z] : - box->orig_corner7[Proj::Z], Proj::Z)); + Persp3DImpl *persp_impl = box3d_get_perspective(box)->perspective_impl; + Proj::Pt3 pt_proj (persp_impl->tmat.preimage (new_pos, (id < 4) ? box->orig_corner0[Proj::Z] : + box->orig_corner7[Proj::Z], Proj::Z)); if (constrained) { pt_proj = box3d_snap (box, id, pt_proj, box3d_get_proj_corner (id, box->save_corner0, box->save_corner7)); } @@ -553,13 +537,14 @@ box3d_set_corner (SPBox3D *box, const guint id, Geom::Point const &new_pos, cons 1.0); } else { Persp3D *persp = box3d_get_perspective(box); - Box3D::PerspectiveLine pl(persp->tmat.image( + Persp3DImpl *persp_impl = box3d_get_perspective(box)->perspective_impl; + Box3D::PerspectiveLine pl(persp_impl->tmat.image( box3d_get_proj_corner (id, box->save_corner0, box->save_corner7)).affine(), Proj::Z, persp); Geom::Point new_pos_snapped(pl.closest_to(new_pos)); - Proj::Pt3 pt_proj (persp->tmat.preimage (new_pos_snapped, - box3d_get_proj_corner (box, id)[(movement & Box3D::Y) ? Proj::X : Proj::Y], - (movement & Box3D::Y) ? Proj::X : Proj::Y)); + Proj::Pt3 pt_proj (persp_impl->tmat.preimage (new_pos_snapped, + box3d_get_proj_corner (box, id)[(movement & Box3D::Y) ? Proj::X : Proj::Y], + (movement & Box3D::Y) ? Proj::X : Proj::Y)); bool corner0_move_x = !(id & Box3D::X) && (movement & Box3D::X); bool corner0_move_y = !(id & Box3D::Y) && (movement & Box3D::Y); bool corner7_move_x = (id & Box3D::X) && (movement & Box3D::X); @@ -590,9 +575,9 @@ void box3d_set_center (SPBox3D *box, Geom::Point const &new_pos, Geom::Point con double radx = (box->orig_corner7[Proj::X] - box->orig_corner0[Proj::X]) / 2; double rady = (box->orig_corner7[Proj::Y] - box->orig_corner0[Proj::Y]) / 2; - Proj::Pt3 pt_proj (persp->tmat.preimage (new_pos, coord, Proj::Z)); + Proj::Pt3 pt_proj (persp->perspective_impl->tmat.preimage (new_pos, coord, Proj::Z)); if (constrained) { - Proj::Pt3 old_pos_proj (persp->tmat.preimage (old_pos, coord, Proj::Z)); + Proj::Pt3 old_pos_proj (persp->perspective_impl->tmat.preimage (old_pos, coord, Proj::Z)); old_pos_proj.normalize(); pt_proj = box3d_snap (box, -1, pt_proj, old_pos_proj); } @@ -612,7 +597,7 @@ void box3d_set_center (SPBox3D *box, Geom::Point const &new_pos, Geom::Point con Box3D::PerspectiveLine pl(old_pos, Proj::Z, persp); Geom::Point new_pos_snapped(pl.closest_to(new_pos)); - Proj::Pt3 pt_proj (persp->tmat.preimage (new_pos_snapped, coord, Proj::X)); + Proj::Pt3 pt_proj (persp->perspective_impl->tmat.preimage (new_pos_snapped, coord, Proj::X)); /* normalizing pt_proj is essential because we want to mingle affine coordinates */ pt_proj.normalize(); @@ -636,6 +621,7 @@ void box3d_corners_for_PLs (const SPBox3D * box, Proj::Axis axis, { Persp3D *persp = box3d_get_perspective(box); g_return_if_fail (persp); + Persp3DImpl *persp_impl = persp->perspective_impl; //box->orig_corner0.normalize(); //box->orig_corner7.normalize(); double coord = (box->orig_corner0[axis] > box->orig_corner7[axis]) ? @@ -666,10 +652,10 @@ void box3d_corners_for_PLs (const SPBox3D * box, Proj::Axis axis, default: return; } - corner1 = persp->tmat.image(c1).affine(); - corner2 = persp->tmat.image(c2).affine(); - corner3 = persp->tmat.image(c3).affine(); - corner4 = persp->tmat.image(c4).affine(); + corner1 = persp_impl->tmat.image(c1).affine(); + corner2 = persp_impl->tmat.image(c2).affine(); + corner3 = persp_impl->tmat.image(c3).affine(); + corner4 = persp_impl->tmat.image(c4).affine(); } /* Auxiliary function: Checks whether the half-line from A to B crosses the line segment joining C and D */ @@ -1027,7 +1013,7 @@ box3d_recompute_z_orders (SPBox3D *box) { Geom::Point dirs[3]; for (int i = 0; i < 3; ++i) { dirs[i] = persp3d_get_PL_dir_from_pt(persp, c3, Box3D::toProj(Box3D::axes[i])); - if (persp3d_VP_is_finite(persp, Proj::axes[i])) { + if (persp3d_VP_is_finite(persp->perspective_impl, Proj::axes[i])) { num_finite++; axis_finite = Box3D::axes[i]; } else { @@ -1212,7 +1198,7 @@ box3d_pt_lies_in_PL_sector (SPBox3D const *box, Geom::Point const &pt, int id1, Geom::Point c2(box3d_get_corner_screen(box, id2, false)); int ret = 0; - if (persp3d_VP_is_finite(persp, Box3D::toProj(axis))) { + if (persp3d_VP_is_finite(persp->perspective_impl, Box3D::toProj(axis))) { Geom::Point vp(persp3d_get_VP(persp, Box3D::toProj(axis)).affine()); Geom::Point v1(c1 - vp); Geom::Point v2(c2 - vp); @@ -1239,7 +1225,7 @@ int box3d_VP_lies_in_PL_sector (SPBox3D const *box, Proj::Axis vpdir, int id1, int id2, Box3D::Axis axis) { Persp3D *persp = box3d_get_perspective(box); - if (!persp3d_VP_is_finite(persp, vpdir)) { + if (!persp3d_VP_is_finite(persp->perspective_impl, vpdir)) { return 0; } else { return box3d_pt_lies_in_PL_sector(box, persp3d_get_VP(persp, vpdir).affine(), id1, id2, axis); @@ -1302,31 +1288,6 @@ box3d_check_for_swapped_coords(SPBox3D *box) { box3d_exchange_coords(box); } -void -box3d_add_to_selection(SPBox3D *box) { - Persp3D *persp = box3d_get_perspective(box); - g_return_if_fail(persp); - persp3d_add_box_transform(persp, box); -} - -void -box3d_remove_from_selection(SPBox3D *box) { - Persp3D *persp = box3d_get_perspective(box); - if (!persp) { - /* this can happen if a box is deleted through undo and the persp_ref is already detached; - should we rebuild the boxes of each perspective in this case or is it safe to leave it alone? */ - return; - } - persp3d_remove_box_transform(persp, box); -} - -void -box3d_mark_transformed(SPBox3D *box) { - Persp3D *persp = box3d_get_perspective(box); - g_return_if_fail(persp); - persp3d_set_box_transformed(persp, box, true); -} - static void box3d_extract_boxes_rec(SPObject *obj, std::list<SPBox3D *> &boxes) { if (SP_IS_BOX3D(obj)) { @@ -1360,16 +1321,13 @@ box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp, Geom::Point corner0_screen = box3d_get_corner_screen(box, 0, false); Geom::Point corner7_screen = box3d_get_corner_screen(box, 7, false); - box->orig_corner0 = new_persp->tmat.preimage(corner0_screen, z0, Proj::Z); - box->orig_corner7 = new_persp->tmat.preimage(corner7_screen, z7, Proj::Z); + box->orig_corner0 = new_persp->perspective_impl->tmat.preimage(corner0_screen, z0, Proj::Z); + box->orig_corner7 = new_persp->perspective_impl->tmat.preimage(corner7_screen, z7, Proj::Z); } persp3d_remove_box (old_persp, box); persp3d_add_box (new_persp, box); - persp3d_remove_box_transform (old_persp, box); - persp3d_add_box_transform (new_persp, box); - gchar *href = g_strdup_printf("#%s", SP_OBJECT_REPR(new_persp)->attribute("id")); SP_OBJECT_REPR(box)->setAttribute("inkscape:perspectiveID", href); g_free(href); diff --git a/src/box3d.h b/src/box3d.h index b6d962a3c..9f2e1d78e 100644 --- a/src/box3d.h +++ b/src/box3d.h @@ -70,10 +70,6 @@ int box3d_VP_lies_in_PL_sector (SPBox3D const *box, Proj::Axis vpdir, int id1, i void box3d_relabel_corners(SPBox3D *box); void box3d_check_for_swapped_coords(SPBox3D *box); -void box3d_add_to_selection(SPBox3D *box); -void box3d_remove_from_selection(SPBox3D *box); -void box3d_mark_transformed(SPBox3D *box); - std::list<SPBox3D *> box3d_extract_boxes(SPObject *obj); Persp3D *box3d_get_perspective(SPBox3D const *box); diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 4b1307316..310a37356 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -2,7 +2,7 @@ # include "config.h" #endif -//#define DEBUG_LCMS +#define DEBUG_LCMS #include <glib/gstdio.h> #include <sys/fcntl.h> @@ -23,6 +23,7 @@ #endif #include "xml/repr.h" +#include "color.h" #include "color-profile.h" #include "color-profile-fns.h" #include "attributes.h" @@ -50,7 +51,7 @@ static cmsHPROFILE colorprofile_get_proof_profile_handle(); #ifdef DEBUG_LCMS extern guint update_in_progress; -#define DEBUG_MESSAGE(key, ...) \ +#define DEBUG_MESSAGE_SCISLAC(key, ...) \ {\ Inkscape::Preferences *prefs = Inkscape::Preferences::get();\ bool dump = prefs->getBool(Glib::ustring("/options/scislac/") + #key);\ @@ -76,6 +77,13 @@ extern guint update_in_progress; gtk_widget_show_all( dialog );\ }\ } + + +#define DEBUG_MESSAGE(key, ...)\ +{\ + g_message( __VA_ARGS__ );\ +} + #endif // DEBUG_LCMS static SPObjectClass *cprof_parent_class; @@ -91,6 +99,15 @@ cmsHPROFILE ColorProfile::getSRGBProfile() { return _sRGBProf; } +cmsHPROFILE ColorProfile::_NullProf = 0; + +cmsHPROFILE ColorProfile::getNULLProfile() { + if ( !_NullProf ) { + _NullProf = cmsCreateNULLProfile(); + } + return _NullProf; +} + #endif // ENABLE_LCMS /** @@ -151,6 +168,7 @@ void ColorProfile::init( ColorProfile *cprof ) cprof->_profileSpace = icSigRgbData; cprof->_transf = 0; cprof->_revTransf = 0; + cprof->_gamutTransf = 0; #endif // ENABLE_LCMS } @@ -204,6 +222,10 @@ void ColorProfile::_clearProfile() cmsDeleteTransform( _revTransf ); _revTransf = 0; } + if ( _gamutTransf ) { + cmsDeleteTransform( _gamutTransf ); + _gamutTransf = 0; + } if ( profHandle ) { cmsCloseProfile( profHandle ); profHandle = 0; @@ -508,6 +530,32 @@ cmsHTRANSFORM ColorProfile::getTransfFromSRGB8() return _revTransf; } +cmsHTRANSFORM ColorProfile::getTransfGamutCheck() +{ + if ( !_gamutTransf ) { + _gamutTransf = cmsCreateProofingTransform(getSRGBProfile(), TYPE_RGBA_8, getNULLProfile(), TYPE_GRAY_8, profHandle, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, (cmsFLAGS_GAMUTCHECK|cmsFLAGS_SOFTPROOFING)); + } + return _gamutTransf; +} + +bool ColorProfile::GamutCheck(SPColor color){ + BYTE outofgamut = 0; + + guint32 val = color.toRGBA32(0); + guchar check_color[4] = { + SP_RGBA32_R_U(val), + SP_RGBA32_G_U(val), + SP_RGBA32_B_U(val), + 255}; + + int alarm_r, alarm_g, alarm_b; + cmsGetAlarmCodes(&alarm_r, &alarm_g, &alarm_b); + cmsSetAlarmCodes(255, 255, 255); + cmsDoTransform(ColorProfile::getTransfGamutCheck(), &check_color, &outofgamut, 1); + cmsSetAlarmCodes(alarm_r, alarm_g, alarm_b); + return (outofgamut == 255); +} + #include <io/sys.h> diff --git a/src/color-profile.h b/src/color-profile.h index 2e57e7ef0..40d0d7698 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -36,11 +36,15 @@ struct ColorProfile : public SPObject { static std::list<Glib::ustring> getProfileDirs(); #if ENABLE_LCMS static cmsHPROFILE getSRGBProfile(); + static cmsHPROFILE getNULLProfile(); icColorSpaceSignature getColorSpace() const {return _profileSpace;} icProfileClassSignature getProfileClass() const {return _profileClass;} cmsHTRANSFORM getTransfToSRGB8(); cmsHTRANSFORM getTransfFromSRGB8(); + cmsHTRANSFORM getTransfGamutCheck(); + bool GamutCheck(SPColor color); + #endif // ENABLE_LCMS gchar* href; @@ -64,11 +68,13 @@ private: void _clearProfile(); static cmsHPROFILE _sRGBProf; + static cmsHPROFILE _NullProf; icProfileClassSignature _profileClass; icColorSpaceSignature _profileSpace; cmsHTRANSFORM _transf; cmsHTRANSFORM _revTransf; + cmsHTRANSFORM _gamutTransf; #endif // ENABLE_LCMS }; diff --git a/src/color.cpp b/src/color.cpp index b16d9950f..07c15ff15 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -17,6 +17,7 @@ #include <math.h> #include "color.h" #include "svg/svg-icc-color.h" +#include "svg/svg-device-color.h" #include "svg/svg-color.h" #include "svg/css-ostringstream.h" @@ -29,7 +30,8 @@ static bool profileMatches( SVGICCColor const* first, SVGICCColor const* second #define PROFILE_EPSILON 0.00000001 SPColor::SPColor() : - icc(0) + icc(0), + device(0) { v.c[0] = 0; v.c[1] = 0; @@ -37,19 +39,22 @@ SPColor::SPColor() : } SPColor::SPColor( SPColor const& other ) : - icc(0) + icc(0), + device(0) { *this = other; } SPColor::SPColor( float r, float g, float b ) : - icc(0) + icc(0), + device(0) { set( r, g, b ); } SPColor::SPColor( guint32 value ) : - icc(0) + icc(0), + device(0) { set( value ); } @@ -57,20 +62,29 @@ SPColor::SPColor( guint32 value ) : SPColor::~SPColor() { delete icc; + delete device; icc = 0; + device = 0; } SPColor& SPColor::operator= (SPColor const& other) { - SVGICCColor* tmp = other.icc ? new SVGICCColor(*other.icc) : 0; + SVGICCColor* tmp_icc = other.icc ? new SVGICCColor(*other.icc) : 0; + SVGDeviceColor* tmp_device = other.device ? new SVGDeviceColor(*other.device) : 0; + v.c[0] = other.v.c[0]; v.c[1] = other.v.c[1]; v.c[2] = other.v.c[2]; if ( icc ) { delete icc; } - icc = tmp; + icc = tmp_icc; + + if ( device ) { + delete device; + } + device = tmp_device; return *this; } @@ -86,6 +100,7 @@ bool SPColor::operator == (SPColor const& other) const && (v.c[2] != other.v.c[2]); match &= profileMatches( icc, other.icc ); +//TODO?: match &= devicecolorMatches( device, other.device ); return match; } @@ -204,6 +219,38 @@ std::string SPColor::toString() const css << ')'; } + if ( device && device->type != DEVICE_COLOR_INVALID) { + if ( !css.str().empty() ) { + css << " "; + } + + switch(device->type){ + case DEVICE_GRAY: + css << "device-gray("; + break; + case DEVICE_RGB: + css << "device-rgb("; + break; + case DEVICE_CMYK: + css << "device-cmyk("; + break; + case DEVICE_NCHANNEL: + css << "device-nchannel("; + break; + case DEVICE_COLOR_INVALID: + //should not be reached + break; + } + + for (vector<double>::const_iterator i(device->colors.begin()), + iEnd(device->colors.end()); + i != iEnd; ++i) { + if (i!=device->colors.begin()) css << ", "; + css << *i; + } + css << ')'; + } + return css.str(); } diff --git a/src/color.h b/src/color.h index bebeaec60..7fd351360 100644 --- a/src/color.h +++ b/src/color.h @@ -34,6 +34,7 @@ #define SP_RGBA32_F_COMPOSE(r,g,b,a) SP_RGBA32_U_COMPOSE (SP_COLOR_F_TO_U (r), SP_COLOR_F_TO_U (g), SP_COLOR_F_TO_U (b), SP_COLOR_F_TO_U (a)) struct SVGICCColor; +struct SVGDeviceColor; /** * An RGB color with optional icc-color part @@ -59,6 +60,7 @@ struct SPColor { std::string toString() const; SVGICCColor* icc; + SVGDeviceColor* device; union { float c[3]; } v; diff --git a/src/connector-context.cpp b/src/connector-context.cpp index 307d59d1f..c5c23a734 100644 --- a/src/connector-context.cpp +++ b/src/connector-context.cpp @@ -156,8 +156,8 @@ #include "connector-context.h" #include "pixmaps/cursor-connector.xpm" #include "pixmaps/cursor-node.xpm" -#include "pixmaps/cursor-node-m.xpm" -#include "pixmaps/cursor-node-d.xpm" +//#include "pixmaps/cursor-node-m.xpm" +//#include "pixmaps/cursor-node-d.xpm" #include "xml/node-event-vector.h" #include "xml/repr.h" #include "svg/svg.h" diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index c8782051b..2afcd6109 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -44,6 +44,7 @@ #include "desktop-style.h" #include "svg/svg-icc-color.h" +#include "svg/svg-device-color.h" #include "box3d-side.h" /** @@ -432,6 +433,8 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill paint_res->set = TRUE; SVGICCColor* iccColor = 0; + SVGDeviceColor* devColor = 0; + bool iccSeen = false; gfloat c[4]; c[0] = c[1] = c[2] = c[3] = 0.0; @@ -529,6 +532,23 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill c[1] += d[1]; c[2] += d[2]; c[3] += SP_SCALE24_TO_FLOAT (isfill? style->fill_opacity.value : style->stroke_opacity.value); + + // average device color + unsigned int it; + if (i==objects /*if this is the first object in the GList*/ + && paint->value.color.device){ + devColor = new SVGDeviceColor(*paint->value.color.device); + for (it=0; it < paint->value.color.device->colors.size(); it++){ + devColor->colors[it] = 0; + } + } + + if (devColor && paint->value.color.device && paint->value.color.device->type == devColor->type){ + for (it=0; it < paint->value.color.device->colors.size(); it++){ + devColor->colors[it] += paint->value.color.device->colors[it]; + } + } + num ++; } @@ -568,6 +588,14 @@ objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill paint_res->value.color.icc = tmp; } + // divide and store the device-color + if (devColor){ + for (unsigned int it=0; it < devColor->colors.size(); it++){ + devColor->colors[it] /= num; + } + paint_res->value.color.device = devColor; + } + if (num > 1) { if (same_color) return QUERY_STYLE_MULTIPLE_SAME; diff --git a/src/desktop.cpp b/src/desktop.cpp index 319a0d407..0e4d4caf3 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -458,6 +458,9 @@ void SPDesktop::displayModeToggle() { _setDisplayMode(Inkscape::RENDERMODE_OUTLINE); break; case Inkscape::RENDERMODE_OUTLINE: + _setDisplayMode(Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); + break; + case Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW: default: _setDisplayMode(Inkscape::RENDERMODE_NORMAL); } diff --git a/src/desktop.h b/src/desktop.h index cfb977425..a02a31034 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -201,6 +201,9 @@ struct SPDesktop : public Inkscape::UI::View::View void setDisplayModeOutline() { _setDisplayMode(Inkscape::RENDERMODE_OUTLINE); } + void setDisplayModePrintColorsPreview() { + _setDisplayMode(Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); + } void displayModeToggle(); Inkscape::RenderMode _display_mode; Inkscape::RenderMode getMode() const { return _display_mode; } diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index a92e7cf5b..ee05cd01c 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -359,9 +359,9 @@ CanvasAxonomGrid::readRepr() } if ( (value = repr->attribute("snapvisiblegridlinesonly")) ) { - g_assert(snapper != NULL); - snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); - } + g_assert(snapper != NULL); + snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); + } for (GSList *l = canvasitems; l != NULL; l = l->next) { sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) ); @@ -671,9 +671,9 @@ CanvasAxonomGridSnapper::CanvasAxonomGridSnapper(CanvasAxonomGrid *grid, SnapMan */ Geom::Coord CanvasAxonomGridSnapper::getSnapperTolerance() const { - SPDesktop const *dt = _snapmanager->getDesktop(); - double const zoom = dt ? dt->current_zoom() : 1; - return _snapmanager->snapprefs.getGridTolerance() / zoom; + SPDesktop const *dt = _snapmanager->getDesktop(); + double const zoom = dt ? dt->current_zoom() : 1; + return _snapmanager->snapprefs.getGridTolerance() / zoom; } bool CanvasAxonomGridSnapper::getSnapperAlwaysSnap() const @@ -694,22 +694,22 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const double spacing_v; if (getSnapVisibleOnly()) { - // Only snapping to visible grid lines - spacing_h = grid->spacing_ylines; // this is the spacing of the visible grid lines measured in screen pixels - spacing_v = grid->lyw; // vertical - // convert screen pixels to px - // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary - SPDesktop const *dt = _snapmanager->getDesktop(); - if (dt) { - spacing_h /= dt->current_zoom(); - spacing_v /= dt->current_zoom(); - } - } else { - // Snapping to any grid line, whether it's visible or not - spacing_h = grid->lengthy /(grid->tan_angle[X] + grid->tan_angle[Z]); - spacing_v = grid->lengthy; - - } + // Only snapping to visible grid lines + spacing_h = grid->spacing_ylines; // this is the spacing of the visible grid lines measured in screen pixels + spacing_v = grid->lyw; // vertical + // convert screen pixels to px + // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary + SPDesktop const *dt = _snapmanager->getDesktop(); + if (dt) { + spacing_h /= dt->current_zoom(); + spacing_v /= dt->current_zoom(); + } + } else { + // Snapping to any grid line, whether it's visible or not + spacing_h = grid->lengthy /(grid->tan_angle[X] + grid->tan_angle[Z]); + spacing_v = grid->lengthy; + + } // In an axonometric grid, any point will be surrounded by 6 grid lines: // - 2 vertical grid lines, one left and one right from the point @@ -746,18 +746,18 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const Geom::Point p_x(0, y_proj_along_x_max); Geom::Line line_x(p_x, p_x + vers_x); Geom::Point p_z(0, y_proj_along_z_max); - Geom::Line line_z(p_z, p_z + vers_z); + Geom::Line line_z(p_z, p_z + vers_z); Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default - try - { - inters = Geom::intersection(line_x, line_z); - } - catch (Geom::InfiniteSolutions e) - { - // We're probably dealing with parallel lines; this is useless! - return s; - } + try + { + inters = Geom::intersection(line_x, line_z); + } + catch (Geom::InfiniteSolutions e) + { + // We're probably dealing with parallel lines; this is useless! + return s; + } // Determine which half of the parallelogram to use bool use_left_half = true; @@ -765,7 +765,7 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const if (inters) { Geom::Point inters_pt = line_x.pointAt((*inters).ta); - use_left_half = (p[Geom::X] - grid->origin[Geom::X]) < inters_pt[Geom::X]; + use_left_half = (p[Geom::X] - grid->origin[Geom::X]) < inters_pt[Geom::X]; use_right_half = !use_left_half; } @@ -786,16 +786,16 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const return s; } -void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, Geom::Point const point_on_line) const +void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, Geom::Point const point_on_line) const { - SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, Inkscape::SNAPTARGET_GRID, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line); + SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, source_num, Inkscape::SNAPTARGET_GRID, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line); sc.grid_lines.push_back(dummy); } -void CanvasAxonomGridSnapper::_addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const +void CanvasAxonomGridSnapper::_addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const { - SnappedPoint dummy = SnappedPoint(snapped_point, source, Inkscape::SNAPTARGET_GRID, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); - sc.points.push_back(dummy); + SnappedPoint dummy = SnappedPoint(snapped_point, source, source_num, Inkscape::SNAPTARGET_GRID, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); + sc.points.push_back(dummy); } bool CanvasAxonomGridSnapper::ThisSnapperMightSnap() const diff --git a/src/display/canvas-axonomgrid.h b/src/display/canvas-axonomgrid.h index e36804d7c..4b1cd4834 100644 --- a/src/display/canvas-axonomgrid.h +++ b/src/display/canvas-axonomgrid.h @@ -78,8 +78,8 @@ public: private: LineList _getSnapLines(Geom::Point const &p) const; - void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, const Geom::Point point_on_line) const; - void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const; + void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, const Geom::Point point_on_line) const; + void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const; CanvasAxonomGrid *grid; }; diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 5037c0375..3532c504a 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -635,9 +635,9 @@ CanvasXYGrid::readRepr() } if ( (value = repr->attribute("snapvisiblegridlinesonly")) ) { - g_assert(snapper != NULL); - snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); - } + g_assert(snapper != NULL); + snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0); + } for (GSList *l = canvasitems; l != NULL; l = l->next) { sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) ); @@ -972,9 +972,9 @@ CanvasXYGridSnapper::CanvasXYGridSnapper(CanvasXYGrid *grid, SnapManager *sm, Ge */ Geom::Coord CanvasXYGridSnapper::getSnapperTolerance() const { - SPDesktop const *dt = _snapmanager->getDesktop(); - double const zoom = dt ? dt->current_zoom() : 1; - return _snapmanager->snapprefs.getGridTolerance() / zoom; + SPDesktop const *dt = _snapmanager->getDesktop(); + double const zoom = dt ? dt->current_zoom() : 1; + return _snapmanager->snapprefs.getGridTolerance() / zoom; } bool CanvasXYGridSnapper::getSnapperAlwaysSnap() const @@ -993,20 +993,20 @@ CanvasXYGridSnapper::_getSnapLines(Geom::Point const &p) const for (unsigned int i = 0; i < 2; ++i) { - double spacing; - - if (getSnapVisibleOnly()) { - // Only snapping to visible grid lines - spacing = grid->sw[i]; // this is the spacing of the visible grid lines measured in screen pixels - // convert screen pixels to px - // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary - SPDesktop const *dt = _snapmanager->getDesktop(); - if (dt) { - spacing /= dt->current_zoom(); - } + double spacing; + + if (getSnapVisibleOnly()) { + // Only snapping to visible grid lines + spacing = grid->sw[i]; // this is the spacing of the visible grid lines measured in screen pixels + // convert screen pixels to px + // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary + SPDesktop const *dt = _snapmanager->getDesktop(); + if (dt) { + spacing /= dt->current_zoom(); + } } else { - // Snapping to any grid line, whether it's visible or not - spacing = grid->spacing[i]; + // Snapping to any grid line, whether it's visible or not + spacing = grid->spacing[i]; } Geom::Coord rounded; @@ -1024,16 +1024,16 @@ CanvasXYGridSnapper::_getSnapLines(Geom::Point const &p) const return s; } -void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, Geom::Point const point_on_line) const +void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, Geom::Point const point_on_line) const { - SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, Inkscape::SNAPTARGET_GRID, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line); + SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, source_num, Inkscape::SNAPTARGET_GRID, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line); sc.grid_lines.push_back(dummy); } -void CanvasXYGridSnapper::_addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const +void CanvasXYGridSnapper::_addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const { - SnappedPoint dummy = SnappedPoint(snapped_point, source, Inkscape::SNAPTARGET_GRID, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); - sc.points.push_back(dummy); + SnappedPoint dummy = SnappedPoint(snapped_point, source, source_num, Inkscape::SNAPTARGET_GRID, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); + sc.points.push_back(dummy); } /** diff --git a/src/display/canvas-grid.h b/src/display/canvas-grid.h index 58cfbf735..daf28c15c 100644 --- a/src/display/canvas-grid.h +++ b/src/display/canvas-grid.h @@ -166,8 +166,8 @@ public: private: LineList _getSnapLines(Geom::Point const &p) const; - void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, const Geom::Point point_on_line) const; - void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const; + void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, const Geom::Point point_on_line) const; + void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const; CanvasXYGrid *grid; }; diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index 429f1ed32..db0922915 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -444,6 +444,7 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi SPStyle const *style = ggroup->style; guint ret = item->state; + bool print_colors_preview = (item->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); if (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE) { @@ -511,6 +512,10 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi } else { rgba = style->fill.value.color.toRGBA32( SP_SCALE24_TO_FLOAT(style->fill_opacity.value) ); } + + if (print_colors_preview) + nr_arena_separate_color_plates(&rgba); + nr_blit_pixblock_mask_rgba32(pb, &m, rgba); pb->empty = FALSE; } @@ -551,6 +556,10 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi } else { rgba = style->stroke.value.color.toRGBA32( SP_SCALE24_TO_FLOAT(style->stroke_opacity.value) ); } + + if (print_colors_preview) + nr_arena_separate_color_plates(&rgba); + nr_blit_pixblock_mask_rgba32(pb, &m, rgba); pb->empty = FALSE; } else { diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index bdab5b479..b80df7273 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -312,7 +312,9 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area NRPixBlock *pb, unsigned int flags) { bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); - bool filter = (item->arena->rendermode == Inkscape::RENDERMODE_NORMAL); + bool filter = (item->arena->rendermode != Inkscape::RENDERMODE_OUTLINE && + item->arena->rendermode != Inkscape::RENDERMODE_NO_FILTERS); + bool print_colors = (item->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 96ea76cbe..e2a9e9580 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -35,6 +35,7 @@ #include "display/nr-filter.h" #include <typeinfo> #include <cairo.h> +#include "preferences.h" #include <glib.h> #include "svg/svg.h" @@ -831,7 +832,6 @@ cairo_arena_shape_render_stroke(NRArenaItem *item, NRRectL *area, NRPixBlock *pb pb->empty = FALSE; } - /** * Renders the item. Markers are just composed into the parent buffer. */ @@ -844,6 +844,7 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock if (!shape->style) return item->state; bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); + bool print_colors_preview = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW); if (outline) { // cairo outline rendering @@ -874,6 +875,7 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock } SPStyle const *style = shape->style; + if (shape->fill_shp) { NRPixBlock m; guint32 rgba; @@ -893,12 +895,18 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock if (shape->_fill.paint.type() == NRArenaShape::Paint::NONE) { // do not render fill in any way } else if (shape->_fill.paint.type() == NRArenaShape::Paint::COLOR) { + + const SPColor* fill_color = &shape->_fill.paint.color(); if ( item->render_opacity ) { - rgba = shape->_fill.paint.color().toRGBA32( shape->_fill.opacity * - SP_SCALE24_TO_FLOAT(style->opacity.value) ); + rgba = fill_color->toRGBA32( shape->_fill.opacity * + SP_SCALE24_TO_FLOAT(style->opacity.value) ); } else { - rgba = shape->_fill.paint.color().toRGBA32( shape->_fill.opacity ); + rgba = fill_color->toRGBA32( shape->_fill.opacity ); } + + if (print_colors_preview) + nr_arena_separate_color_plates(&rgba); + nr_blit_pixblock_mask_rgba32(pb, &m, rgba); pb->empty = FALSE; } else if (shape->_fill.paint.type() == NRArenaShape::Paint::SERVER) { @@ -929,14 +937,19 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock nr_pixblock_render_shape_mask_or(m, shape->stroke_shp); m.empty = FALSE; - if ( item->render_opacity ) { - rgba = shape->_stroke.paint.color().toRGBA32( shape->_stroke.opacity * - SP_SCALE24_TO_FLOAT(style->opacity.value) ); - } else { - rgba = shape->_stroke.paint.color().toRGBA32( shape->_stroke.opacity ); - } - nr_blit_pixblock_mask_rgba32(pb, &m, rgba); - pb->empty = FALSE; + const SPColor* stroke_color = &shape->_stroke.paint.color(); + if ( item->render_opacity ) { + rgba = stroke_color->toRGBA32( shape->_stroke.opacity * + SP_SCALE24_TO_FLOAT(style->opacity.value) ); + } else { + rgba = stroke_color->toRGBA32( shape->_stroke.opacity ); + } + + if (print_colors_preview) + nr_arena_separate_color_plates(&rgba); + + nr_blit_pixblock_mask_rgba32(pb, &m, rgba); + pb->empty = FALSE; nr_pixblock_release(&m); diff --git a/src/display/nr-arena.cpp b/src/display/nr-arena.cpp index 74e0f409c..33870a118 100644 --- a/src/display/nr-arena.cpp +++ b/src/display/nr-arena.cpp @@ -18,6 +18,7 @@ #include "nr-filter-types.h" #include <libnr/nr-blit.h> #include "preferences.h" +#include "color.h" static void nr_arena_class_init (NRArenaClass *klass); static void nr_arena_init (NRArena *arena); @@ -181,6 +182,29 @@ nr_arena_set_renderoffscreen (NRArena *arena) } +#define FLOAT_TO_UINT8(f) (int(f*255)) +#define RGBA_R(v) ((v) >> 24) +#define RGBA_G(v) (((v) >> 16) & 0xff) +#define RGBA_B(v) (((v) >> 8) & 0xff) +#define RGBA_A(v) ((v) & 0xff) + +void nr_arena_separate_color_plates(guint32* rgba){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool render_cyan = prefs->getBool("/options/printcolorspreview/cyan", true); + bool render_magenta = prefs->getBool("/options/printcolorspreview/magenta", true); + bool render_yellow = prefs->getBool("/options/printcolorspreview/yellow", true); + bool render_black = prefs->getBool("/options/printcolorspreview/black", true); + + float rgb_v[3]; + float cmyk_v[4]; + sp_color_rgb_to_cmyk_floatv (cmyk_v, RGBA_R(*rgba)/256.0, RGBA_G(*rgba)/256.0, RGBA_B(*rgba)/256.0); + sp_color_cmyk_to_rgb_floatv (rgb_v, render_cyan ? cmyk_v[0] : 0, + render_magenta ? cmyk_v[1] : 0, + render_yellow ? cmyk_v[2] : 0, + render_black ? cmyk_v[3] : 0); + *rgba = (FLOAT_TO_UINT8(rgb_v[0])<<24) + (FLOAT_TO_UINT8(rgb_v[1])<<16) + (FLOAT_TO_UINT8(rgb_v[2])<<8) + 0xff; +} + /* Local Variables: mode:c++ diff --git a/src/display/nr-arena.h b/src/display/nr-arena.h index 1c091b7c7..d2f9dc246 100644 --- a/src/display/nr-arena.h +++ b/src/display/nr-arena.h @@ -64,4 +64,6 @@ void nr_arena_set_renderoffscreen (NRArena *arena); void nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *painter, float opacity, NRPixBlock *mask); +void nr_arena_separate_color_plates(guint32* rgba); + #endif diff --git a/src/display/nr-filter-colormatrix.cpp b/src/display/nr-filter-colormatrix.cpp index 66fb196cb..0b24649a9 100644 --- a/src/display/nr-filter-colormatrix.cpp +++ b/src/display/nr-filter-colormatrix.cpp @@ -2,7 +2,7 @@ * feColorMatrix filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Jasper van de Gronde <th.v.d.gronde@hccnet.nl> * * Copyright (C) 2007 authors diff --git a/src/display/nr-filter-colormatrix.h b/src/display/nr-filter-colormatrix.h index 1c331a5b0..47b454c53 100644 --- a/src/display/nr-filter-colormatrix.h +++ b/src/display/nr-filter-colormatrix.h @@ -5,7 +5,7 @@ * feColorMatrix filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-component-transfer.cpp b/src/display/nr-filter-component-transfer.cpp index 87f87c95a..ab9990360 100644 --- a/src/display/nr-filter-component-transfer.cpp +++ b/src/display/nr-filter-component-transfer.cpp @@ -2,7 +2,7 @@ * feComponentTransfer filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Jasper van de Gronde <th.v.d.gronde@hccnet.nl> * * Copyright (C) 2007 authors diff --git a/src/display/nr-filter-component-transfer.h b/src/display/nr-filter-component-transfer.h index 3d8be272e..eb76bd543 100644 --- a/src/display/nr-filter-component-transfer.h +++ b/src/display/nr-filter-component-transfer.h @@ -5,7 +5,7 @@ * feComponentTransfer filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-convolve-matrix.cpp b/src/display/nr-filter-convolve-matrix.cpp index e9f7e7dfe..fc88102d8 100644 --- a/src/display/nr-filter-convolve-matrix.cpp +++ b/src/display/nr-filter-convolve-matrix.cpp @@ -2,7 +2,7 @@ * feConvolveMatrix filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Jasper van de Gronde <th.v.d.gronde@hccnet.nl> * * Copyright (C) 2007,2009 authors @@ -41,7 +41,7 @@ static inline void convolve2D_XY(unsigned int const x, unsigned int const y, uns unsigned int jEnd = X_UPPER ? width+targetX-x : orderX; for (unsigned int i=iBegin; i<iEnd; i++){ - for (int j=jBegin; j<jEnd; j++){ + for (unsigned int j=jBegin; j<jEnd; j++){ unsigned int index = 4*( x - targetX + j + width*(y - targetY + i) ); unsigned int kernel_index = orderX-j-1 + orderX*(orderY-i-1); double k = PREMULTIPLIED ? kernel[kernel_index] : in_data[index+3] * kernel[kernel_index]; diff --git a/src/display/nr-filter-convolve-matrix.h b/src/display/nr-filter-convolve-matrix.h index d7a04a766..e7416f9cc 100644 --- a/src/display/nr-filter-convolve-matrix.h +++ b/src/display/nr-filter-convolve-matrix.h @@ -5,7 +5,7 @@ * feConvolveMatrix filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-displacement-map.cpp b/src/display/nr-filter-displacement-map.cpp index 869a184ac..4de5e658c 100644 --- a/src/display/nr-filter-displacement-map.cpp +++ b/src/display/nr-filter-displacement-map.cpp @@ -2,7 +2,7 @@ * feDisplacementMap filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-displacement-map.h b/src/display/nr-filter-displacement-map.h index 180030c85..bb15b77a3 100644 --- a/src/display/nr-filter-displacement-map.h +++ b/src/display/nr-filter-displacement-map.h @@ -5,7 +5,7 @@ * feDisplacementMap filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-flood.cpp b/src/display/nr-filter-flood.cpp index 026cbce16..1d804f969 100644 --- a/src/display/nr-filter-flood.cpp +++ b/src/display/nr-filter-flood.cpp @@ -2,15 +2,21 @@ * feFlood filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "display/nr-filter-flood.h" #include "display/nr-filter-utils.h" +#include "svg/svg-icc-color.h" +#include "svg/svg-color.h" namespace Inkscape { namespace Filters { @@ -26,6 +32,7 @@ FilterFlood::~FilterFlood() {} int FilterFlood::render(FilterSlot &slot, FilterUnits const &/*units*/) { +g_message("rendering feflood"); NRPixBlock *in = slot.get(_input); if (!in) { g_warning("Missing source image for feFlood (in=%d)", _input); @@ -43,12 +50,18 @@ int FilterFlood::render(FilterSlot &slot, FilterUnits const &/*units*/) { true); unsigned char *out_data = NR_PIXBLOCK_PX(out); - unsigned char r,g,b,a; - r = CLAMP_D_TO_U8((color >> 24) % 256); - g = CLAMP_D_TO_U8((color >> 16) % 256); - b = CLAMP_D_TO_U8((color >> 8) % 256); - a = CLAMP_D_TO_U8(opacity*255); + + + r = CLAMP_D_TO_U8((color >> 24) % 256); + g = CLAMP_D_TO_U8((color >> 16) % 256); + b = CLAMP_D_TO_U8((color >> 8) % 256); + a = CLAMP_D_TO_U8(opacity*255); + +#if ENABLE_LCMS + icc_color_to_sRGB(icc, &r, &g, &b); +g_message("result: r:%d g:%d b:%d", r, g, b); +#endif //ENABLE_LCMS for(i=0; i < 4*in_h*in_w; i+=4){ out_data[i]=r; @@ -70,6 +83,10 @@ void FilterFlood::set_opacity(double o) { opacity = o; } +void FilterFlood::set_icc(SVGICCColor *icc_color) { + icc = icc_color; +} + void FilterFlood::area_enlarge(NRRectL &/*area*/, Geom::Matrix const &/*trans*/) { } diff --git a/src/display/nr-filter-flood.h b/src/display/nr-filter-flood.h index 9e6a53abb..98c374bbd 100644 --- a/src/display/nr-filter-flood.h +++ b/src/display/nr-filter-flood.h @@ -5,7 +5,7 @@ * feFlood filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * @@ -15,6 +15,7 @@ #include "display/nr-filter-primitive.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" +#include "svg/svg-color.h" namespace Inkscape { namespace Filters { @@ -27,11 +28,13 @@ public: virtual void set_opacity(double o); virtual void set_color(guint32 c); + virtual void set_icc(SVGICCColor *icc_color); virtual int render(FilterSlot &slot, FilterUnits const &units); virtual void area_enlarge(NRRectL &area, Geom::Matrix const &trans); private: double opacity; guint32 color; + SVGICCColor *icc; }; } /* namespace Filters */ diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 2b799f8d2..4ad6982f3 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -2,7 +2,7 @@ * feImage filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 2007 authors diff --git a/src/display/nr-filter-morphology.cpp b/src/display/nr-filter-morphology.cpp index 2df3ff807..258298751 100644 --- a/src/display/nr-filter-morphology.cpp +++ b/src/display/nr-filter-morphology.cpp @@ -2,7 +2,7 @@ * feMorphology filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-morphology.h b/src/display/nr-filter-morphology.h index 1d3e16be3..16ccad5e6 100644 --- a/src/display/nr-filter-morphology.h +++ b/src/display/nr-filter-morphology.h @@ -5,7 +5,7 @@ * feMorphology filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-tile.cpp b/src/display/nr-filter-tile.cpp index 53399eba2..898db9f53 100644 --- a/src/display/nr-filter-tile.cpp +++ b/src/display/nr-filter-tile.cpp @@ -2,7 +2,7 @@ * feTile filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-tile.h b/src/display/nr-filter-tile.h index ea826dfd7..5a6a5a78c 100644 --- a/src/display/nr-filter-tile.h +++ b/src/display/nr-filter-tile.h @@ -5,7 +5,7 @@ * feTile filter primitive renderer * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2007 authors * diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index a91db3d56..8d22b180d 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -3,7 +3,7 @@ * * Authors: * World Wide Web Consortium <http://www.w3.org/> - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * This file has a considerable amount of code adapted from * the W3C SVG filter specs, available at: diff --git a/src/display/nr-filter-turbulence.h b/src/display/nr-filter-turbulence.h index b12e6395a..b841cc37f 100644 --- a/src/display/nr-filter-turbulence.h +++ b/src/display/nr-filter-turbulence.h @@ -6,7 +6,7 @@ * * Authors: * World Wide Web Consortium <http://www.w3.org/> - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Niko Kiirala <niko@kiirala.com> * * This file has a considerable amount of code adapted from diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 2d71504d2..7a0db664a 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -4,7 +4,7 @@ * SVGFonts rendering implementation * * Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * diff --git a/src/display/nr-svgfonts.h b/src/display/nr-svgfonts.h index ebf5ad08b..ddf4ba327 100644 --- a/src/display/nr-svgfonts.h +++ b/src/display/nr-svgfonts.h @@ -5,7 +5,7 @@ * SVGFonts rendering headear * * Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * diff --git a/src/display/rendermode.h b/src/display/rendermode.h index 1b59ae9bb..abcdb3db4 100644 --- a/src/display/rendermode.h +++ b/src/display/rendermode.h @@ -12,7 +12,8 @@ namespace Inkscape { enum RenderMode { RENDERMODE_NORMAL, RENDERMODE_NO_FILTERS, - RENDERMODE_OUTLINE + RENDERMODE_OUTLINE, + RENDERMODE_PRINT_COLORS_PREVIEW }; } diff --git a/src/document.cpp b/src/document.cpp index a3ad6f7be..3104ade28 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -97,10 +97,9 @@ SPDocument::SPDocument() : rerouting_handler_id(0), profileManager(0), // deferred until after other initialization router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)), - perspectives(0), - current_persp3d(0), _collection_queue(0), - oldSignalsConnected(false) + oldSignalsConnected(false), + current_persp3d(0) { // Penalise libavoid for choosing paths with needless extra segments. // This results in much better looking orthogonal connector paths. @@ -216,26 +215,43 @@ SPDocument::~SPDocument() { //delete this->_whiteboard_session_manager; } -void SPDocument::add_persp3d (Persp3D * const /*persp*/) -{ - SPDefs *defs = SP_ROOT(this->root)->defs; - for (SPObject *i = sp_object_first_child(SP_OBJECT(defs)); i != NULL; i = SP_OBJECT_NEXT(i) ) { - if (SP_IS_PERSP3D(i)) { - g_print ("Encountered a Persp3D in defs\n"); - } +Persp3D * +SPDocument::getCurrentPersp3D() { + // Check if current_persp3d is still valid + std::vector<Persp3D*> plist; + getPerspectivesInDefs(plist); + for (unsigned int i = 0; i < plist.size(); ++i) { + if (current_persp3d == plist[i]) + return current_persp3d; } - g_print ("Adding Persp3D to defs\n"); - persp3d_create_xml_element (this); + // If not, return the first perspective in defs (which may be NULL of none exists) + current_persp3d = persp3d_document_first_persp (this); + + return current_persp3d; } -void SPDocument::remove_persp3d (Persp3D * const /*persp*/) -{ - // TODO: Delete the repr, maybe perform a check if any boxes are still linked to the perspective. - // Anything else? - g_print ("Please implement deletion of perspectives here.\n"); +Persp3DImpl * +SPDocument::getCurrentPersp3DImpl() { + return current_persp3d_impl; } +void +SPDocument::setCurrentPersp3D(Persp3D * const persp) { + current_persp3d = persp; + //current_persp3d_impl = persp->perspective_impl; +} + +void +SPDocument::getPerspectivesInDefs(std::vector<Persp3D*> &list) { + SPDefs *defs = SP_ROOT(this->root)->defs; + for (SPObject *i = sp_object_first_child(SP_OBJECT(defs)); i != NULL; i = SP_OBJECT_NEXT(i) ) { + if (SP_IS_PERSP3D(i)) + list.push_back(SP_PERSP3D(i)); + } +} + +/** void SPDocument::initialize_current_persp3d() { this->current_persp3d = persp3d_document_first_persp(this); @@ -243,6 +259,7 @@ void SPDocument::initialize_current_persp3d() this->current_persp3d = persp3d_create_xml_element(this); } } +**/ unsigned long SPDocument::serial() const { return priv->serial; @@ -390,10 +407,14 @@ sp_document_create(Inkscape::XML::Document *rdoc, inkscape_ref(); } - // Remark: Here, we used to create a "currentpersp3d" element in the document defs. - // But this is probably a bad idea since we need to adapt it for every change of selection, which will - // completely clutter the undo history. Maybe rather save it to prefs on exit and re-read it on startup? - document->initialize_current_persp3d(); + // Check if the document already has a perspective (e.g., when opening an existing + // document). If not, create a new one and set it as the current perspective. + document->setCurrentPersp3D(persp3d_document_first_persp(document)); + if (!document->getCurrentPersp3D()) { + //document->setCurrentPersp3D(persp3d_create_xml_element (document)); + Persp3DImpl *persp_impl = new Persp3DImpl(); + document->setCurrentPersp3DImpl(persp_impl); + } sp_document_set_undo_sensitive(document, true); @@ -746,11 +767,13 @@ SPDocument::emitReconstructionFinish(void) { // printf("Finishing Reconstruction\n"); priv->_reconstruction_finish_signal.emit(); - + +/** // Reference to the old persp3d object is invalid after reconstruction. initialize_current_persp3d(); return; +**/ } sigc::connection SPDocument::connectCommit(SPDocument::CommitSignal::slot_type slot) diff --git a/src/document.h b/src/document.h index 06174c265..e83c37a96 100644 --- a/src/document.h +++ b/src/document.h @@ -55,6 +55,7 @@ namespace Inkscape { class SP3DBox; class Persp3D; +class Persp3DImpl; namespace Proj { class TransfMat3x4; @@ -107,17 +108,26 @@ struct SPDocument : public Inkscape::GC::Managed<>, // Instance of the connector router Avoid::Router *router; - GSList *perspectives; - - Persp3D *current_persp3d; // "currently active" perspective (e.g., newly created boxes are attached to this one) - GSList *_collection_queue; bool oldSignalsConnected; - void add_persp3d(Persp3D * const persp); - void remove_persp3d(Persp3D * const persp); - void initialize_current_persp3d(); + void setCurrentPersp3D(Persp3D * const persp); + inline void setCurrentPersp3DImpl(Persp3DImpl * const persp_impl) { current_persp3d_impl = persp_impl; } + /* + * getCurrentPersp3D returns current_persp3d (if non-NULL) or the first + * perspective in the defs. If no perspective exists, returns NULL. + */ + Persp3D * getCurrentPersp3D(); + Persp3DImpl * getCurrentPersp3DImpl(); + void getPerspectivesInDefs(std::vector<Persp3D*> &list); + unsigned int numPerspectivesInDefs() { + std::vector<Persp3D*> list; + getPerspectivesInDefs(list); + return list.size(); + } + + //void initialize_current_persp3d(); sigc::connection connectModified(ModifiedSignal::slot_type slot); sigc::connection connectURISet(URISetSignal::slot_type slot); @@ -155,6 +165,9 @@ private: SPDocument(SPDocument const &); // no copy void operator=(SPDocument const &); // no assign + Persp3D *current_persp3d; /**< Currently 'active' perspective (to which, e.g., newly created boxes are attached) */ + Persp3DImpl *current_persp3d_impl; + public: sigc::connection connectReconstructionStart(ReconstructionStart::slot_type slot); sigc::connection connectReconstructionFinish(ReconstructionFinish::slot_type slot); diff --git a/src/dom/ucd.cpp b/src/dom/ucd.cpp index 3747334d2..f9c36ad19 100644 --- a/src/dom/ucd.cpp +++ b/src/dom/ucd.cpp @@ -2514,11 +2514,12 @@ int uni_to_title(int ch) int uni_block(int ch) { - int ret; - UcdBlockData *entry; - for (entry = ucd_blocks, ret=0 ; entry->name ; entry++, ret++) - if (ch >= entry->low && ch <= entry->high) + int ret = 0; + for (UcdBlockData *entry = ucd_blocks; entry->name ; entry++, ret++) { + if ((ch >= entry->low) && (ch <= entry->high)) { return ret; + } + } return UCD_BLOCK_NO_BLOCK; } diff --git a/src/dom/util/ziptool.cpp b/src/dom/util/ziptool.cpp index 40f456bd6..1e915ab0a 100644 --- a/src/dom/util/ziptool.cpp +++ b/src/dom/util/ziptool.cpp @@ -2207,6 +2207,7 @@ ZipEntry *ZipFile::addFile(const std::string &fileName, ZipEntry *ze = new ZipEntry(); if (!ze->readFile(fileName, comment)) { + delete ze; return NULL; } entries.push_back(ze); diff --git a/src/dropper-context.cpp b/src/dropper-context.cpp index aa17ea859..5415fdc80 100644 --- a/src/dropper-context.cpp +++ b/src/dropper-context.cpp @@ -143,6 +143,16 @@ static void sp_dropper_context_finish(SPEventContext *ec) /** + * Returns the current dropper context icc-color. + */ +SPColor* sp_dropper_context_get_icc_color(SPEventContext */*ec*/) +{ + //TODO: implement-me! + + return 0; // At least we will cause a clean crash, instead of random corruption. +} + +/** * Returns the current dropper context color. */ guint32 sp_dropper_context_get_color(SPEventContext *ec) diff --git a/src/extension/dxf2svg/entities2elements.cpp b/src/extension/dxf2svg/entities2elements.cpp index cf42dac32..ab160e265 100644 --- a/src/extension/dxf2svg/entities2elements.cpp +++ b/src/extension/dxf2svg/entities2elements.cpp @@ -80,7 +80,7 @@ void pline2svg(polyline pline, int type, int precision, char * units, double sca // 2 is pline2polygon - char delim[1]; + char delim[2]; double mag_bulge = 0; double prev_mag_bulge = 0; @@ -185,7 +185,7 @@ void lwpline2svg(lwpolyline pline, int type, int precision, char * units, double // 2 is pline2polygon - char delim[1]; + char delim[2]; double mag_bulge = 0; double prev_mag_bulge = 0; diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 9ac19326f..737bb2885 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -42,22 +42,22 @@ namespace Inkscape { namespace Extension { namespace Internal { -bool -CairoPsOutput::check (Inkscape::Extension::Extension * module) +bool CairoPsOutput::check (Inkscape::Extension::Extension * /*module*/) { - if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS)) - return FALSE; - - return TRUE; + if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_PS)) { + return FALSE; + } else { + return TRUE; + } } -bool -CairoEpsOutput::check (Inkscape::Extension::Extension * module) +bool CairoEpsOutput::check (Inkscape::Extension::Extension * /*module*/) { - if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS)) - return FALSE; - - return TRUE; + if (NULL == Inkscape::Extension::db.get(SP_MODULE_KEY_PRINT_CAIRO_EPS)) { + return FALSE; + } else { + return TRUE; + } } static bool diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index e6f2d698e..a1f902457 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -71,12 +71,12 @@ public: CairoRenderer *getRenderer(void) const; cairo_t *getCairoContext(void) const; - typedef enum CairoRenderMode { + enum CairoRenderMode { RENDER_MODE_NORMAL, RENDER_MODE_CLIP }; - typedef enum CairoClipMode { + enum CairoClipMode { CLIP_MODE_PATH, CLIP_MODE_MASK }; diff --git a/src/extension/internal/emf-win32-inout.cpp b/src/extension/internal/emf-win32-inout.cpp index f400a3649..9d25f3a7f 100644 --- a/src/extension/internal/emf-win32-inout.cpp +++ b/src/extension/internal/emf-win32-inout.cpp @@ -127,6 +127,7 @@ emf_print_document_to_file(SPDocument *doc, gchar const *filename) /* Print document */ ret = mod->begin(doc); if (ret) { + g_free(oldoutput); throw Inkscape::Extension::Output::save_failed(); } sp_item_invoke_print(mod->base, &context); diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index cc8489302..46e0361ce 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -795,8 +795,8 @@ void SingularValueDecomposition::calculate() } } - delete e; - delete work; + delete [] e; + delete [] work; } diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index c2d417f2c..ba00fe343 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -734,6 +734,7 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { delete builder; g_free(docname); delete pdf_doc; + delete dlg; // Restore undo sp_document_set_undo_sensitive(doc, saved); diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp index 00bd8fa4d..b9583545f 100644 --- a/src/extension/internal/pdfinput/svg-builder.cpp +++ b/src/extension/internal/pdfinput/svg-builder.cpp @@ -1536,7 +1536,7 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height } png_write_row(png_ptr, (png_bytep)buffer); } - delete buffer; + delete [] buffer; } else if (color_map) { image_stream = new ImageStream(str, width, color_map->getNumPixelComps(), @@ -1575,7 +1575,7 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height png_write_row(png_ptr, (png_bytep)buffer); } } - delete buffer; + delete [] buffer; } else { // A colormap must be provided, so quit png_destroy_write_struct(&png_ptr, &info_ptr); diff --git a/src/filters/colormatrix.cpp b/src/filters/colormatrix.cpp index 55cfcbeb7..3f60ea05c 100644 --- a/src/filters/colormatrix.cpp +++ b/src/filters/colormatrix.cpp @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Sanches <felipe.sanches@gmail.com> + * Felipe Sanches <juca@members.fsf.org> * hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2007 Felipe C. da S. Sanches diff --git a/src/filters/componenttransfer-funcnode.cpp b/src/filters/componenttransfer-funcnode.cpp index e66f85e70..8edb9cf2d 100644 --- a/src/filters/componenttransfer-funcnode.cpp +++ b/src/filters/componenttransfer-funcnode.cpp @@ -7,7 +7,7 @@ * Authors: * Hugo Rodrigues <haa.rodrigues@gmail.com> * Niko Kiirala <niko@kiirala.com> - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2006, 2007, 2008 Authors * diff --git a/src/filters/componenttransfer-funcnode.h b/src/filters/componenttransfer-funcnode.h index 4db6ab785..52873f6d3 100644 --- a/src/filters/componenttransfer-funcnode.h +++ b/src/filters/componenttransfer-funcnode.h @@ -8,7 +8,7 @@ * Authors: * Hugo Rodrigues <haa.rodrigues@gmail.com> * Niko Kiirala <niko@kiirala.com> - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2006,2007 Authors * diff --git a/src/filters/convolvematrix.cpp b/src/filters/convolvematrix.cpp index 3e1c36f0a..6440f340a 100644 --- a/src/filters/convolvematrix.cpp +++ b/src/filters/convolvematrix.cpp @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2006 Hugo Rodrigues diff --git a/src/filters/convolvematrix.h b/src/filters/convolvematrix.h index beb5fad75..1e8545040 100644 --- a/src/filters/convolvematrix.h +++ b/src/filters/convolvematrix.h @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2006 Hugo Rodrigues diff --git a/src/filters/flood.cpp b/src/filters/flood.cpp index 625e35d42..221b0daf2 100644 --- a/src/filters/flood.cpp +++ b/src/filters/flood.cpp @@ -17,12 +17,13 @@ # include "config.h" #endif +#include "strneq.h" + #include "attributes.h" #include "svg/svg.h" #include "flood.h" #include "xml/repr.h" #include "helper-fns.h" -#include "svg/svg-color.h" /* FeFlood base class */ @@ -79,6 +80,7 @@ static void sp_feFlood_init(SPFeFlood *feFlood) { feFlood->opacity = 1; + feFlood->icc = NULL; } /** @@ -120,16 +122,34 @@ sp_feFlood_set(SPObject *object, unsigned int key, gchar const *value) gchar *end_ptr = NULL; guint32 read_color; double read_num; + bool dirty = false; switch(key) { /*DEAL WITH SETTING ATTRIBUTES HERE*/ case SP_PROP_FLOOD_COLOR: cend_ptr = NULL; read_color = sp_svg_read_color(value, &cend_ptr, 0xffffffff); + if (cend_ptr && read_color != feFlood->color){ feFlood->color = read_color; - object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); + dirty=true; + } + + if (cend_ptr){ + while (g_ascii_isspace(*cend_ptr)) { + ++cend_ptr; + } + if (strneq(cend_ptr, "icc-color(", 10)) { + if (!feFlood->icc) feFlood->icc = new SVGICCColor(); + if ( ! sp_svg_read_icc_color( cend_ptr, feFlood->icc ) ) { + delete feFlood->icc; + feFlood->icc = NULL; + } + dirty = true; + } } + if (dirty) + object->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_PROP_FLOOD_OPACITY: if (value) { @@ -208,6 +228,7 @@ static void sp_feFlood_build_renderer(SPFilterPrimitive *primitive, Inkscape::Fi nr_flood->set_opacity(sp_flood->opacity); nr_flood->set_color(sp_flood->color); + nr_flood->set_icc(sp_flood->icc); } diff --git a/src/filters/flood.h b/src/filters/flood.h index 046c0e868..f386e2cd4 100644 --- a/src/filters/flood.h +++ b/src/filters/flood.h @@ -15,6 +15,7 @@ #include "sp-filter.h" #include "flood-fns.h" +#include "svg/svg-icc-color.h" #include "display/nr-filter.h" #include "display/nr-filter-flood.h" @@ -25,6 +26,7 @@ class SPFeFloodClass; struct SPFeFlood : public SPFilterPrimitive { /** FLOOD ATTRIBUTES HERE */ guint32 color; + SVGICCColor *icc; double opacity; }; diff --git a/src/filters/image.cpp b/src/filters/image.cpp index d8e5a417f..eb6dfc22a 100644 --- a/src/filters/image.cpp +++ b/src/filters/image.cpp @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2007 Felipe Sanches @@ -43,8 +43,7 @@ static void sp_feImage_build_renderer(SPFilterPrimitive *primitive, Inkscape::Fi static SPFilterPrimitiveClass *feImage_parent_class; -GType -sp_feImage_get_type() +GType sp_feImage_get_type() { static GType feImage_type = 0; @@ -64,8 +63,7 @@ sp_feImage_get_type() return feImage_type; } -static void -sp_feImage_class_init(SPFeImageClass *klass) +static void sp_feImage_class_init(SPFeImageClass *klass) { SPObjectClass *sp_object_class = (SPObjectClass *)klass; SPFilterPrimitiveClass * sp_primitive_class = (SPFilterPrimitiveClass *)klass; @@ -81,8 +79,7 @@ sp_feImage_class_init(SPFeImageClass *klass) sp_primitive_class->build_renderer = sp_feImage_build_renderer; } -static void -sp_feImage_init(SPFeImage */*feImage*/) +static void sp_feImage_init(SPFeImage */*feImage*/) { } @@ -91,8 +88,7 @@ sp_feImage_init(SPFeImage */*feImage*/) * our name must be associated with a repr via "sp_object_type_register". Best done through * sp-object-repr.cpp's repr_name_entries array. */ -static void -sp_feImage_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +static void sp_feImage_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { // Save document reference so we can load images with relative paths. SPFeImage *feImage = SP_FEIMAGE(object); @@ -115,8 +111,7 @@ sp_feImage_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *re /** * Drops any allocated memory. */ -static void -sp_feImage_release(SPObject *object) +static void sp_feImage_release(SPObject *object) { SPFeImage *feImage = SP_FEIMAGE(object); feImage->_image_modified_connection.disconnect(); @@ -127,14 +122,12 @@ sp_feImage_release(SPObject *object) ((SPObjectClass *) feImage_parent_class)->release(object); } -static void -sp_feImage_elem_modified(SPObject* /*href*/, guint /*flags*/, SPObject* obj) +static void sp_feImage_elem_modified(SPObject* /*href*/, guint /*flags*/, SPObject* obj) { obj->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); } -static void -sp_feImage_href_modified(SPObject* old_elem, SPObject* new_elem, SPObject* obj) +static void sp_feImage_href_modified(SPObject* /*old_elem*/, SPObject* new_elem, SPObject* obj) { SPFeImage *feImage = SP_FEIMAGE(obj); feImage->_image_modified_connection.disconnect(); @@ -151,8 +144,7 @@ sp_feImage_href_modified(SPObject* old_elem, SPObject* new_elem, SPObject* obj) /** * Sets a specific value in the SPFeImage. */ -static void -sp_feImage_set(SPObject *object, unsigned int key, gchar const *value) +static void sp_feImage_set(SPObject *object, unsigned int key, gchar const *value) { SPFeImage *feImage = SP_FEIMAGE(object); (void)feImage; @@ -221,8 +213,7 @@ sp_feImage_set(SPObject *object, unsigned int key, gchar const *value) /** * Receives update notifications. */ -static void -sp_feImage_update(SPObject *object, SPCtx *ctx, guint flags) +static void sp_feImage_update(SPObject *object, SPCtx *ctx, guint flags) { if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | @@ -239,8 +230,7 @@ sp_feImage_update(SPObject *object, SPCtx *ctx, guint flags) /** * Writes its settings to an incoming repr object, if any. */ -static Inkscape::XML::Node * -sp_feImage_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) +static Inkscape::XML::Node * sp_feImage_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) { /* TODO: Don't just clone, but create a new repr node and write all * relevant values into it */ diff --git a/src/filters/image.h b/src/filters/image.h index 7207918e1..78e719ac7 100644 --- a/src/filters/image.h +++ b/src/filters/image.h @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2006 Hugo Rodrigues diff --git a/src/filters/morphology.cpp b/src/filters/morphology.cpp index 9a34bbccb..1530dae8c 100644 --- a/src/filters/morphology.cpp +++ b/src/filters/morphology.cpp @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Sanches <felipe.sanches@gmail.com> + * Felipe Sanches <juca@members.fsf.org> * Hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2006 Hugo Rodrigues diff --git a/src/filters/turbulence.cpp b/src/filters/turbulence.cpp index f3c143056..eed056ecc 100644 --- a/src/filters/turbulence.cpp +++ b/src/filters/turbulence.cpp @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2007 Felipe Sanches diff --git a/src/filters/turbulence.h b/src/filters/turbulence.h index 5edf678a7..792a6181a 100644 --- a/src/filters/turbulence.h +++ b/src/filters/turbulence.h @@ -6,7 +6,7 @@ */ /* * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * Hugo Rodrigues <haa.rodrigues@gmail.com> * * Copyright (C) 2006 Hugo Rodrigues diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index c16ed2456..e61bd9552 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -609,7 +609,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp dist = fabs(p[Geom::Y] - dragger->parent->hor_levels[i]); if (dist < snap_dist) { p[Geom::Y] = dragger->parent->hor_levels[i]; - s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, Inkscape::SNAPTARGET_GRADIENTS_PARENT_BBOX, dist, snap_dist, false, false); + s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, 0, Inkscape::SNAPTARGET_GRADIENTS_PARENT_BBOX, dist, snap_dist, false, false); was_snapped = true; sp_knot_moveto (knot, p); } @@ -618,7 +618,7 @@ gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gp dist = fabs(p[Geom::X] - dragger->parent->vert_levels[i]); if (dist < snap_dist) { p[Geom::X] = dragger->parent->vert_levels[i]; - s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, Inkscape::SNAPTARGET_GRADIENTS_PARENT_BBOX, dist, snap_dist, false, false); + s = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_HANDLE, 0, Inkscape::SNAPTARGET_GRADIENTS_PARENT_BBOX, dist, snap_dist, false, false); was_snapped = true; sp_knot_moveto (knot, p); } diff --git a/src/guide-snapper.cpp b/src/guide-snapper.cpp index 5cf97958a..9121e3ee2 100644 --- a/src/guide-snapper.cpp +++ b/src/guide-snapper.cpp @@ -68,22 +68,22 @@ bool Inkscape::GuideSnapper::ThisSnapperMightSnap() const return (_snap_enabled && _snapmanager->snapprefs.getSnapToGuides() && _snapmanager->getNamedView()->showguides); } -void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, Geom::Point const point_on_line) const +void Inkscape::GuideSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, Geom::Point const point_on_line) const { - SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, Inkscape::SNAPTARGET_GUIDE, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line); + SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, source_num, Inkscape::SNAPTARGET_GUIDE, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line); sc.guide_lines.push_back(dummy); } -void Inkscape::GuideSnapper::_addSnappedLinesOrigin(SnappedConstraints &sc, Geom::Point const origin, Geom::Coord const snapped_distance, SnapSourceType const &source) const +void Inkscape::GuideSnapper::_addSnappedLinesOrigin(SnappedConstraints &sc, Geom::Point const origin, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const { - SnappedPoint dummy = SnappedPoint(origin, source, Inkscape::SNAPTARGET_GUIDE_ORIGIN, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); + SnappedPoint dummy = SnappedPoint(origin, source, source_num, Inkscape::SNAPTARGET_GUIDE_ORIGIN, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); sc.points.push_back(dummy); } -void Inkscape::GuideSnapper::_addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const +void Inkscape::GuideSnapper::_addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const { - SnappedPoint dummy = SnappedPoint(snapped_point, source, Inkscape::SNAPTARGET_GUIDE, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); + SnappedPoint dummy = SnappedPoint(snapped_point, source, source_num, Inkscape::SNAPTARGET_GUIDE, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true); sc.points.push_back(dummy); } diff --git a/src/guide-snapper.h b/src/guide-snapper.h index 1dc602f72..5adac6e22 100644 --- a/src/guide-snapper.h +++ b/src/guide-snapper.h @@ -30,13 +30,13 @@ public: bool ThisSnapperMightSnap() const; Geom::Coord getSnapperTolerance() const; //returns the tolerance of the snapper in screen pixels (i.e. independent of zoom) - bool getSnapperAlwaysSnap() const; //if true, then the snapper will always snap, regardless of its tolerance + bool getSnapperAlwaysSnap() const; //if true, then the snapper will always snap, regardless of its tolerance private: LineList _getSnapLines(Geom::Point const &p) const; - void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, Geom::Point const point_on_line) const; - void _addSnappedLinesOrigin(SnappedConstraints &sc, Geom::Point const origin, Geom::Coord const snapped_distance, SnapSourceType const &source) const; - void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const; + void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, Geom::Point const point_on_line) const; + void _addSnappedLinesOrigin(SnappedConstraints &sc, Geom::Point const origin, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const; + void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const; }; } diff --git a/src/helper-fns.h b/src/helper-fns.h index d2a6c9b22..2c2db92c4 100644 --- a/src/helper-fns.h +++ b/src/helper-fns.h @@ -5,7 +5,7 @@ * Some helper functions * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * * Copyright (C) 2006 Hugo Rodrigues diff --git a/src/inkjar/jar.cpp b/src/inkjar/jar.cpp index d53901de5..6897cb317 100644 --- a/src/inkjar/jar.cpp +++ b/src/inkjar/jar.cpp @@ -66,7 +66,7 @@ namespace Inkjar { JarFile::JarFile(gchar const*new_filename) { - _filename = strdup(new_filename); + _filename = g_strdup(new_filename); _last_filename = NULL; fd = -1; } @@ -75,7 +75,7 @@ JarFile::JarFile(gchar const*new_filename) // use strdup gchar *JarFile::get_last_filename() const { - return (_last_filename != NULL ? strdup(_last_filename) : NULL); + return (_last_filename != NULL ? g_strdup(_last_filename) : NULL); } JarFile::~JarFile() @@ -445,11 +445,11 @@ JarFile& JarFile::operator=(JarFile const& rhs) if (_filename == NULL) _filename = NULL; else - _filename = strdup(rhs._filename); + _filename = g_strdup(rhs._filename); if (_last_filename == NULL) _last_filename = NULL; else - _last_filename = strdup(rhs._last_filename); + _last_filename = g_strdup(rhs._last_filename); fd = rhs.fd; return *this; diff --git a/src/interface.cpp b/src/interface.cpp index 415593b78..b29b91d18 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -703,6 +703,8 @@ update_view_menu(GtkWidget *widget, GdkEventExpose */*event*/, gpointer user_dat new_state = mode == Inkscape::RENDERMODE_NO_FILTERS; } else if (!strcmp(action->id, "ViewModeOutline")) { new_state = mode == Inkscape::RENDERMODE_OUTLINE; + } else if (!strcmp(action->id, "ViewModePrintColorsPreview")) { + new_state = mode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW; } else { g_warning("update_view_menu does not handle this verb"); } diff --git a/src/libavoid/connector.cpp b/src/libavoid/connector.cpp index d9088dfe7..3dbd941a4 100644 --- a/src/libavoid/connector.cpp +++ b/src/libavoid/connector.cpp @@ -586,7 +586,7 @@ Router *ConnRef::router(void) const } -bool ConnRef::generatePath(Point p0, Point p1) +bool ConnRef::generatePath(Point /*p0*/, Point /*p1*/) { // XXX Code to determine when connectors really need to be rerouted // does not yet work for orthogonal connectors. diff --git a/src/libavoid/orthogonal.cpp b/src/libavoid/orthogonal.cpp index 747fd1f86..4a7b0af2d 100644 --- a/src/libavoid/orthogonal.cpp +++ b/src/libavoid/orthogonal.cpp @@ -12,12 +12,12 @@ * See the file LICENSE.LGPL distributed with the library. * * Licensees holding a valid commercial license may use this file in - * accordance with the commercial license agreement provided with the + * accordance with the commercial license agreement provided with the * library. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Author(s): Michael Wybrow <mjwybrow@users.sourceforge.net> */ @@ -52,11 +52,11 @@ static const size_t XDIM = 0; static const size_t YDIM = 1; -class ShiftSegment +class ShiftSegment { public: // For shiftable segments. - ShiftSegment(ConnRef *conn, const size_t low, const size_t high, + ShiftSegment(ConnRef *conn, const size_t low, const size_t high, bool isSBend, const size_t dim, double minLim, double maxLim) : connRef(conn), indexLow(low), @@ -69,8 +69,9 @@ class ShiftSegment maxSpaceLimit(maxLim) { } + // For fixed segments. - ShiftSegment(ConnRef *conn, const size_t low, const size_t high, + ShiftSegment(ConnRef *conn, const size_t low, const size_t high, const size_t dim) : connRef(conn), indexLow(low), @@ -84,23 +85,28 @@ class ShiftSegment minSpaceLimit = lowPoint()[dim]; maxSpaceLimit = lowPoint()[dim]; } + Point& lowPoint(void) { return connRef->displayRoute().ps[indexLow]; } + Point& highPoint(void) { return connRef->displayRoute().ps[indexHigh]; } + const Point& lowPoint(void) const { return connRef->displayRoute().ps[indexLow]; } - const Point& highPoint(void) const + + const Point& highPoint(void) const { return connRef->displayRoute().ps[indexHigh]; } - const int fixedOrder(bool& isFixed) const + + int fixedOrder(bool& isFixed) const { if (fixed) { @@ -117,7 +123,8 @@ class ShiftSegment } return 0; } - const int order(void) const + + int order(void) const { if (lowC()) { @@ -129,17 +136,19 @@ class ShiftSegment } return 0; } + bool operator<(const ShiftSegment& rhs) const { const Point& lowPt = lowPoint(); const Point& rhsLowPt = rhs.lowPoint(); - + if (lowPt[dimension] != rhsLowPt[dimension]) { return lowPt[dimension] < rhsLowPt[dimension]; } return this < &rhs; } + // This counts segments that are colliear and share an endpoint as // overlapping. This allows them to be nudged apart where possible. bool overlapsWith(const ShiftSegment& rhs, const size_t dim) const @@ -171,7 +180,7 @@ class ShiftSegment double minSpaceLimit; double maxSpaceLimit; private: - const bool lowC(void) const + bool lowC(void) const { // This is true if this is a cBend and its adjoining points // are at lower positions. @@ -181,7 +190,8 @@ class ShiftSegment } return false; } - const bool highC(void) const + + bool highC(void) const { // This is true if this is a cBend and its adjoining points // are at higher positions. @@ -204,7 +214,7 @@ struct Node; struct CmpNodePos { bool operator()(const Node* u, const Node* v) const; }; typedef std::set<Node*,CmpNodePos> NodeSet; -struct Node +struct Node { ShapeRef *v; VertInf *c; @@ -221,10 +231,10 @@ struct Node pos(p), firstAbove(NULL), firstBelow(NULL) - { + { //COLA_ASSERT(r->width()<1e40); v->polygon().getBoundingRect(&min[0], &min[1], &max[0], &max[1]); - } + } Node(VertInf *c, const double p) : v(NULL), c(c), @@ -235,7 +245,7 @@ struct Node { min[0] = max[0] = c->point.x; min[1] = max[1] = c->point.y; - } + } Node(ShiftSegment *ss, const double p) : v(NULL), c(NULL), @@ -246,8 +256,8 @@ struct Node { // These values shouldn't ever be used, so they don't matter. min[0] = max[0] = min[1] = max[1] = 0; - } - ~Node() + } + ~Node() { } // Find the first Node above in the scanline that is a shape edge, @@ -260,7 +270,7 @@ struct Node { curr = curr->firstAbove; } - + if (curr) { return curr->max[dim]; @@ -277,14 +287,14 @@ struct Node { curr = curr->firstBelow; } - + if (curr) { return curr->min[dim]; } return DBL_MAX; } - // Mark all connector segments above in the scanline as being able + // Mark all connector segments above in the scanline as being able // to see to this shape edge. void markShiftSegmentsAbove(size_t dim) { @@ -293,13 +303,13 @@ struct Node { if (curr->ss && (curr->pos <= min[dim])) { - curr->ss->maxSpaceLimit = + curr->ss->maxSpaceLimit = std::min(min[dim], curr->ss->maxSpaceLimit); } curr = curr->firstAbove; } } - // Mark all connector segments below in the scanline as being able + // Mark all connector segments below in the scanline as being able // to see to this shape edge. void markShiftSegmentsBelow(size_t dim) { @@ -308,7 +318,7 @@ struct Node { if (curr->ss && (curr->pos >= max[dim])) { - curr->ss->minSpaceLimit = + curr->ss->minSpaceLimit = std::max(max[dim], curr->ss->minSpaceLimit); } curr = curr->firstBelow; @@ -320,8 +330,8 @@ struct Node bool clearVisibility = true; firstAbovePos = -DBL_MAX; firstBelowPos = DBL_MAX; - // We start looking left from the right side of the shape, - // and vice versa. + // We start looking left from the right side of the shape, + // and vice versa. lastAbovePos = max[dim]; lastBelowPos = min[dim]; @@ -353,7 +363,7 @@ struct Node } curr = curr->firstAbove; } - + // Find the first blocking edge below this point. Don't count the // edges as we are travelling out of shapes we are inside, but then // mark clearVisibility as false. @@ -385,35 +395,35 @@ struct Node return clearVisibility; } - double firstPointAbove(size_t dim) - { - Node *curr = firstAbove; - while (curr && (curr->max[dim] >= pos)) - { - curr = curr->firstAbove; - } - - if (curr) - { - return curr->max[dim]; - } - return -DBL_MAX; - } - double firstPointBelow(size_t dim) - { - Node *curr = firstBelow; - while (curr && (curr->min[dim] <= pos)) - { - curr = curr->firstBelow; - } - - if (curr) - { - return curr->min[dim]; - } - return DBL_MAX; - } - // This is a bit inefficient, but we won't need to do it once we have + double firstPointAbove(size_t dim) + { + Node *curr = firstAbove; + while (curr && (curr->max[dim] >= pos)) + { + curr = curr->firstAbove; + } + + if (curr) + { + return curr->max[dim]; + } + return -DBL_MAX; + } + double firstPointBelow(size_t dim) + { + Node *curr = firstBelow; + while (curr && (curr->min[dim] <= pos)) + { + curr = curr->firstBelow; + } + + if (curr) + { + return curr->min[dim]; + } + return DBL_MAX; + } + // This is a bit inefficient, but we won't need to do it once we have // connection points. bool isInsideShape(size_t dimension) { @@ -436,17 +446,17 @@ struct Node }; -bool CmpNodePos::operator() (const Node* u, const Node* v) const +bool CmpNodePos::operator() (const Node* u, const Node* v) const { - if (u->pos != v->pos) + if (u->pos != v->pos) { return u->pos < v->pos; } - + // Use the pointers to the base objects to differentiate them. - void *up = (u->v) ? (void *) u->v : + void *up = (u->v) ? (void *) u->v : ((u->c) ? (void *) u->c : (void *) u->ss); - void *vp = (v->v) ? (void *) v->v : + void *vp = (v->v) ? (void *) v->v : ((v->c) ? (void *) v->c : (void *) v->ss); return up < vp; } @@ -456,7 +466,7 @@ bool CmpNodePos::operator() (const Node* u, const Node* v) const typedef enum { Open = 1, SegOpen = 2, - ConnPoint = 3, + ConnPoint = 3, SegClose = 4, Close = 5 } EventType; @@ -464,7 +474,7 @@ typedef enum { struct Event { - Event(EventType t, Node *v, double p) + Event(EventType t, Node *v, double p) : type(t), v(v), pos(p) @@ -496,7 +506,7 @@ int compare_events(const void *a, const void *b) // Returns a bitfield of the direction of visibility (in this dimension) -// made up of ConnDirDown (for visibility towards lower position values) +// made up of ConnDirDown (for visibility towards lower position values) // and ConnDirUp (for visibility towards higher position values). // static ConnDirFlags getPosVertInfDirection(VertInf *v, size_t dim) @@ -526,13 +536,13 @@ static ConnDirFlags getPosVertInfDirection(VertInf *v, size_t dim) } else if (dirs == ConnDirDown) { - // For libavoid the Y-axis points downwards, so in terms of + // For libavoid the Y-axis points downwards, so in terms of // smaller or larger position values, Down is Up and vice versa. return ConnDirUp; } else if (dirs == ConnDirUp) { - // For libavoid the Y-axis points downwards, so in terms of + // For libavoid the Y-axis points downwards, so in terms of // smaller or larger position values, Down is Up and vice versa. return ConnDirDown; } @@ -551,8 +561,8 @@ struct PosVertInf dir(d) { } - - bool operator<(const PosVertInf& rhs) const + + bool operator<(const PosVertInf& rhs) const { if (pos != rhs.pos) { @@ -565,7 +575,7 @@ struct PosVertInf VertInf *vert; // A bitfield marking the direction of visibility (in this dimension) - // made up of ConnDirDown (for visibility towards lower position values) + // made up of ConnDirDown (for visibility towards lower position values) // and ConnDirUp (for visibility towards higher position values). // ConnDirFlags dir; @@ -573,7 +583,7 @@ struct PosVertInf struct CmpVertInf -{ +{ bool operator()(const VertInf* u, const VertInf* v) const { // Comparator for VertSet, an ordered set of VertInf pointers. @@ -596,17 +606,17 @@ struct CmpVertInf typedef std::set<VertInf *, CmpVertInf> VertSet; -// A set of points to break the line segment, +// A set of points to break the line segment, // along with vertices for these points. typedef std::set<PosVertInf> BreakpointSet; -// Temporary structure used to store the possible horizontal visibility +// Temporary structure used to store the possible horizontal visibility // lines arising from the vertical sweep. -class LineSegment +class LineSegment { public: - LineSegment(const double& b, const double& f, const double& p, - bool ss = false, VertInf *bvi = NULL, VertInf *fvi = NULL) + LineSegment(const double& b, const double& f, const double& p, + bool /*ss*/ = false, VertInf *bvi = NULL, VertInf *fvi = NULL) : begin(b), finish(f), pos(p), @@ -623,6 +633,7 @@ public: vertInfs.insert(fvi); } } + LineSegment(const double& bf, const double& p, VertInf *bfvi = NULL) : begin(bf), finish(bf), @@ -634,9 +645,9 @@ public: vertInfs.insert(bfvi); } } - + // Order by begin, pos, finish. - bool operator<(const LineSegment& rhs) const + bool operator<(const LineSegment& rhs) const { if (begin != rhs.begin) { @@ -662,7 +673,7 @@ public: // Lines are exactly equal. return true; } - + if (pos == rhs.pos) { if (((begin >= rhs.begin) && (begin <= rhs.finish)) || @@ -681,7 +692,7 @@ public: finish = std::max(finish, segment.finish); vertInfs.insert(segment.vertInfs.begin(), segment.vertInfs.end()); } - + VertInf *beginVertInf(void) const { if (vertInfs.empty()) @@ -750,12 +761,12 @@ public: } } - // Converts a section of the points list to a set of breakPoints. + // Converts a section of the points list to a set of breakPoints. // Returns the first of the intersection points occuring at finishPos. - VertSet::iterator addSegmentsUpTo(Router *router, double finishPos) + VertSet::iterator addSegmentsUpTo(Router */*router*/, double finishPos) { VertSet::iterator firstIntersectionPt = vertInfs.end(); - for (VertSet::iterator vert = vertInfs.begin(); + for (VertSet::iterator vert = vertInfs.begin(); vert != vertInfs.end(); ++vert) { if ((*vert)->point.x > finishPos) @@ -763,11 +774,11 @@ public: // We're done. break; } - + breakPoints.insert(PosVertInf((*vert)->point.x, (*vert), getPosVertInfDirection(*vert, XDIM))); - if ((firstIntersectionPt == vertInfs.end()) && + if ((firstIntersectionPt == vertInfs.end()) && ((*vert)->point.x == finishPos)) { firstIntersectionPt = vert; @@ -777,22 +788,22 @@ public: return firstIntersectionPt; } - // Add visibility edge(s) for this segment. There may be multiple if + // Add visibility edge(s) for this segment. There may be multiple if // one of the endpoints is shared by multiple connector endpoints. void addEdgeHorizontal(Router *router) { commitBegin(router); commitFinish(router); - + addSegmentsUpTo(router, finish); } // Add visibility edge(s) for this segment up until an intersection. // Then, move the segment beginning to the intersection point, so we // later only consider the remainder of the segment. - // There may be multiple segments added to the graph if the beginning + // There may be multiple segments added to the graph if the beginning // endpoint of the segment is shared by multiple connector endpoints. - VertSet addEdgeHorizontalTillIntersection(Router *router, + VertSet addEdgeHorizontalTillIntersection(Router *router, LineSegment& vertLine) { VertSet intersectionSet; @@ -801,14 +812,14 @@ public: // Does a vertex already exist for this point. commitPositionX(router, vertLine.pos); - - // Generate segments and set end iterator to the first point + + // Generate segments and set end iterator to the first point // at the intersection position. VertSet::iterator restBegin = addSegmentsUpTo(router, vertLine.pos); // Add the intersections points to intersectionSet. VertSet::iterator restEnd = restBegin; - while ((restEnd != vertInfs.end()) && + while ((restEnd != vertInfs.end()) && (*restEnd)->point.x == vertLine.pos) { ++restEnd; @@ -821,7 +832,7 @@ public: return intersectionSet; } - + // Insert vertical breakpoints. void insertBreakpointsBegin(Router *router, LineSegment& vertLine) { @@ -841,7 +852,7 @@ public: { if ((*v)->point.x == begin) { - vertLine.breakPoints.insert(PosVertInf(pos, *v, + vertLine.breakPoints.insert(PosVertInf(pos, *v, getPosVertInfDirection(*v, YDIM))); } } @@ -911,7 +922,7 @@ public: { // Here we have a pair of two endpoints that are both // connector endpoints and both are inside a shape. - + // Give vert visibility back to the first non-connector // endpoint vertex (i.e., the side of the shape). BreakpointSet::iterator side = last; @@ -926,16 +937,16 @@ public: bool canSeeDown = (vert->dir & ConnDirDown); if (canSeeDown && side->vert->id.isShape) { - EdgeInf *edge = new + EdgeInf *edge = new EdgeInf(side->vert, vert->vert, orthogonal); - edge->setDist(vert->vert->point[dim] - + edge->setDist(vert->vert->point[dim] - side->vert->point[dim]); } // Give last visibility back to the first non-connector // endpoint vertex (i.e., the side of the shape). side = vert; - while ((side != breakPoints.end()) && + while ((side != breakPoints.end()) && !side->vert->id.isShape) { ++side; @@ -943,17 +954,17 @@ public: bool canSeeUp = (last->dir & ConnDirUp); if (canSeeUp && (side != breakPoints.end())) { - EdgeInf *edge = new + EdgeInf *edge = new EdgeInf(last->vert, side->vert, orthogonal); - edge->setDist(side->vert->point[dim] - + edge->setDist(side->vert->point[dim] - last->vert->point[dim]); } } - + // The normal case. // - // Note: It's okay to give two connector endpoints visbility - // here since we only consider the partner endpoint as a + // Note: It's okay to give two connector endpoints visbility + // here since we only consider the partner endpoint as a // candidate while searching if it is the other endpoint of // the connector in question. // @@ -968,9 +979,9 @@ public: } if (generateEdge) { - EdgeInf *edge = + EdgeInf *edge = new EdgeInf(last->vert, vert->vert, orthogonal); - edge->setDist(vert->vert->point[dim] - + edge->setDist(vert->vert->point[dim] - last->vert->point[dim]); } @@ -997,12 +1008,12 @@ public: double finish; double pos; bool shapeSide; - + VertSet vertInfs; BreakpointSet breakPoints; private: - // MSVC wants to generate the assignment operator and the default - // constructor, but fails. Therefore we declare them private and + // MSVC wants to generate the assignment operator and the default + // constructor, but fails. Therefore we declare them private and // don't implement them. LineSegment & operator=(LineSegment const &); LineSegment(); @@ -1032,7 +1043,7 @@ class SegmentListWrapper } else { - // This is the first overlapping segment, so just + // This is the first overlapping segment, so just // merge the new segment with this one. curr->mergeVertInfs(segment); found = curr; @@ -1061,7 +1072,7 @@ class SegmentListWrapper // Given a router instance and a set of possible horizontal segments, and a // possible vertical visibility segment, compute and add edges to the // orthogonal visibility graph for all the visibility edges. -static void intersectSegments(Router *router, SegmentList& segments, +static void intersectSegments(Router *router, SegmentList& segments, LineSegment& vertLine) { COLA_ASSERT(vertLine.beginVertInf() == NULL); @@ -1104,9 +1115,9 @@ static void intersectSegments(Router *router, SegmentList& segments, { // Add horizontal visibility segment. horiLine.addEdgeHorizontal(router); - + horiLine.insertBreakpointsFinish(router, vertLine); - + size_t dim = XDIM; // x-dimension horiLine.generateVisibilityEdgesFromBreakpointSet(router, dim); @@ -1123,7 +1134,7 @@ static void intersectSegments(Router *router, SegmentList& segments, if (inVertSegRegion) { // Add horizontal visibility segment. - VertSet intersectionVerts = + VertSet intersectionVerts = horiLine.addEdgeHorizontalTillIntersection( router, vertLine); @@ -1144,16 +1155,16 @@ static void intersectSegments(Router *router, SegmentList& segments, } -// Processes an event for the vertical sweep used for computing the static -// orthogonal visibility graph. This adds possible visibility sgments to +// Processes an event for the vertical sweep used for computing the static +// orthogonal visibility graph. This adds possible visibility sgments to // the segments list. // The first pass is adding the event to the scanline, the second is for // processing the event and the third for removing it from the scanline. -static void processEventVert(Router *router, NodeSet& scanline, +static void processEventVert(Router *router, NodeSet& scanline, SegmentListWrapper& segments, Event *e, unsigned int pass) { Node *v = e->v; - + if ( ((pass == 1) && (e->type == Open)) || ((pass == 2) && (e->type == ConnPoint)) ) { @@ -1163,21 +1174,21 @@ static void processEventVert(Router *router, NodeSet& scanline, NodeSet::iterator it = v->iter; // Work out neighbours - if (it != scanline.begin()) + if (it != scanline.begin()) { Node *u = *(--it); v->firstAbove = u; u->firstBelow = v; } it = v->iter; - if (++it != scanline.end()) + if (++it != scanline.end()) { Node *u = *it; v->firstBelow = u; u->firstAbove = v; } } - + if (pass == 2) { if ((e->type == Open) || (e->type == Close)) @@ -1198,18 +1209,18 @@ static void processEventVert(Router *router, NodeSet& scanline, if (minLimitMax >= maxLimitMin) { // Insert possible visibility segments. - VertInf *vI1 = new VertInf(router, dummyOrthogID, + VertInf *vI1 = new VertInf(router, dummyOrthogID, Point(minShape, lineY)); - VertInf *vI2 = new VertInf(router, dummyOrthogID, + VertInf *vI2 = new VertInf(router, dummyOrthogID, Point(maxShape, lineY)); - + // There are no overlapping shapes, so give full visibility. if (minLimit < minShape) { segments.insert(LineSegment(minLimit, minShape, lineY, true, NULL, vI1)); } - segments.insert(LineSegment(minShape, maxShape, lineY, + segments.insert(LineSegment(minShape, maxShape, lineY, true, vI1, vI2)); if (maxShape < maxLimit) { @@ -1245,12 +1256,12 @@ static void processEventVert(Router *router, NodeSet& scanline, LineSegment *line1 = NULL, *line2 = NULL; if (!inShape || (centreVert->visDirections & ConnDirLeft)) { - line1 = segments.insert(LineSegment(minLimit, cp.x, e->pos, + line1 = segments.insert(LineSegment(minLimit, cp.x, e->pos, true, NULL, centreVert)); } if (!inShape || (centreVert->visDirections & ConnDirRight)) { - line2 = segments.insert(LineSegment(cp.x, maxLimit, e->pos, + line2 = segments.insert(LineSegment(cp.x, maxLimit, e->pos, true, centreVert, NULL)); } if (!line1 && !line2) @@ -1258,7 +1269,7 @@ static void processEventVert(Router *router, NodeSet& scanline, // Add a point segment for the centre point. segments.insert(LineSegment(cp.x, e->pos, centreVert)); } - + if (!inShape) { // This is not contained within a shape so add a normal @@ -1279,13 +1290,13 @@ static void processEventVert(Router *router, NodeSet& scanline, } } } - + if ( ((pass == 3) && (e->type == Close)) || ((pass == 2) && (e->type == ConnPoint)) ) { // Clean up neighbour pointers. Node *l = v->firstAbove, *r = v->firstBelow; - if (l != NULL) + if (l != NULL) { l->firstBelow = v->firstBelow; } @@ -1310,16 +1321,16 @@ static void processEventVert(Router *router, NodeSet& scanline, } -// Processes an event for the vertical sweep used for computing the static -// orthogonal visibility graph. This adds possible visibility sgments to +// Processes an event for the vertical sweep used for computing the static +// orthogonal visibility graph. This adds possible visibility sgments to // the segments list. // The first pass is adding the event to the scanline, the second is for // processing the event and the third for removing it from the scanline. -static void processEventHori(Router *router, NodeSet& scanline, +static void processEventHori(Router */*router*/, NodeSet& scanline, SegmentListWrapper& segments, Event *e, unsigned int pass) { Node *v = e->v; - + if ( ((pass == 1) && (e->type == Open)) || ((pass == 2) && (e->type == ConnPoint)) ) { @@ -1329,21 +1340,21 @@ static void processEventHori(Router *router, NodeSet& scanline, NodeSet::iterator it = v->iter; // Work out neighbours - if (it != scanline.begin()) + if (it != scanline.begin()) { Node *u = *(--it); v->firstAbove = u; u->firstBelow = v; } it = v->iter; - if (++it != scanline.end()) + if (++it != scanline.end()) { Node *u = *it; v->firstBelow = u; u->firstAbove = v; } } - + if (pass == 2) { if ((e->type == Open) || (e->type == Close)) @@ -1370,13 +1381,13 @@ static void processEventHori(Router *router, NodeSet& scanline, { if ((minLimitMax > minLimit) && (minLimitMax >= minShape)) { - LineSegment vertSeg = + LineSegment vertSeg = LineSegment(minLimit, minLimitMax, lineX); segments.insert(vertSeg); } if ((maxLimitMin < maxLimit) && (maxLimitMin <= maxShape)) { - LineSegment vertSeg = + LineSegment vertSeg = LineSegment(maxLimitMin, maxLimit, lineX); segments.insert(vertSeg); } @@ -1392,7 +1403,7 @@ static void processEventHori(Router *router, NodeSet& scanline, double minLimit = v->firstPointAbove(1); double maxLimit = v->firstPointBelow(1); bool inShape = v->isInsideShape(1); - + if (!inShape || (centreVert->visDirections & ConnDirUp)) { segments.insert(LineSegment(minLimit, cp.y, e->pos)); @@ -1403,13 +1414,13 @@ static void processEventHori(Router *router, NodeSet& scanline, } } } - + if ( ((pass == 3) && (e->type == Close)) || ((pass == 2) && (e->type == ConnPoint)) ) { // Clean up neighbour pointers. Node *l = v->firstAbove, *r = v->firstBelow; - if (l != NULL) + if (l != NULL) { l->firstBelow = v->firstBelow; } @@ -1455,8 +1466,8 @@ extern void generateStaticOrthogonalVisGraph(Router *router) ++shRefIt; } - for (VertInf *curr = router->vertices.connsBegin(); - curr && (curr != router->vertices.shapesBegin()); + for (VertInf *curr = router->vertices.connsBegin(); + curr && (curr != router->vertices.shapesBegin()); curr = curr->lstNext) { Point& point = curr->point; @@ -1485,7 +1496,7 @@ extern void generateStaticOrthogonalVisGraph(Router *router) { for (unsigned j = posStartIndex; j < posFinishIndex; ++j) { - processEventVert(router, scanline, segments, + processEventVert(router, scanline, segments, events[j], pass); } } @@ -1500,7 +1511,7 @@ extern void generateStaticOrthogonalVisGraph(Router *router) posStartIndex = i; } - // Do the first sweep event handling -- building the correct + // Do the first sweep event handling -- building the correct // structure of the scanline. const int pass = 1; processEventVert(router, scanline, segments, events[i], pass); @@ -1529,8 +1540,8 @@ extern void generateStaticOrthogonalVisGraph(Router *router) ++shRefIt; } - for (VertInf *curr = router->vertices.connsBegin(); - curr && (curr != router->vertices.shapesBegin()); + for (VertInf *curr = router->vertices.connsBegin(); + curr && (curr != router->vertices.shapesBegin()); curr = curr->lstNext) { Point& point = curr->point; @@ -1555,11 +1566,11 @@ extern void generateStaticOrthogonalVisGraph(Router *router) { for (unsigned j = posStartIndex; j < posFinishIndex; ++j) { - processEventHori(router, scanline, vertSegments, + processEventHori(router, scanline, vertSegments, events[j], pass); } } - + // Process the merged line segments. vertSegments.list().sort(); for (SegmentList::iterator curr = vertSegments.list().begin(); @@ -1579,7 +1590,7 @@ extern void generateStaticOrthogonalVisGraph(Router *router) posStartIndex = i; } - // Do the first sweep event handling -- building the correct + // Do the first sweep event handling -- building the correct // structure of the scanline. const int pass = 1; processEventHori(router, scanline, vertSegments, events[i], pass); @@ -1593,13 +1604,13 @@ extern void generateStaticOrthogonalVisGraph(Router *router) // Add portions of the horizontal line that are after the final vertical // position we considered. - for (SegmentList::iterator it = segments.list().begin(); + for (SegmentList::iterator it = segments.list().begin(); it != segments.list().end(); ) { LineSegment& horiLine = *it; horiLine.addEdgeHorizontal(router); - + size_t dim = XDIM; // x-dimension horiLine.generateVisibilityEdgesFromBreakpointSet(router, dim); @@ -1615,20 +1626,20 @@ extern void generateStaticOrthogonalVisGraph(Router *router) -// Processes sweep events used to determine each horizontal and vertical -// line segment in a connector's channel of visibility. +// Processes sweep events used to determine each horizontal and vertical +// line segment in a connector's channel of visibility. // Four calls to this function are made at each position by the scanline: // 1) Handle all Close event processing. // 2) Remove Close event objects from the scanline. // 3) Add Open event objects to the scanline. // 4) Handle all Open event processing. // -static void processShiftEvent(Router *router, NodeSet& scanline, - ShiftSegmentList& segments, Event *e, size_t dim, - unsigned int pass) +static void processShiftEvent(Router */*router*/, NodeSet& scanline, + ShiftSegmentList& /*segments*/, Event *e, size_t dim, + unsigned int pass) { Node *v = e->v; - + if ( ((pass == 3) && (e->type == Open)) || ((pass == 3) && (e->type == SegOpen)) ) { @@ -1638,21 +1649,21 @@ static void processShiftEvent(Router *router, NodeSet& scanline, NodeSet::iterator it = v->iter; // Work out neighbours - if (it != scanline.begin()) + if (it != scanline.begin()) { Node *u = *(--it); v->firstAbove = u; u->firstBelow = v; } it = v->iter; - if (++it != scanline.end()) + if (++it != scanline.end()) { Node *u = *it; v->firstBelow = u; u->firstAbove = v; } } - + if ( ((pass == 4) && (e->type == Open)) || ((pass == 4) && (e->type == SegOpen)) || ((pass == 1) && (e->type == SegClose)) || @@ -1664,9 +1675,9 @@ static void processShiftEvent(Router *router, NodeSet& scanline, double minLimit = v->firstObstacleAbove(dim); double maxLimit = v->firstObstacleBelow(dim); - v->ss->minSpaceLimit = + v->ss->minSpaceLimit = std::max(minLimit, v->ss->minSpaceLimit); - v->ss->maxSpaceLimit = + v->ss->maxSpaceLimit = std::min(maxLimit, v->ss->maxSpaceLimit); } else @@ -1675,13 +1686,13 @@ static void processShiftEvent(Router *router, NodeSet& scanline, v->markShiftSegmentsBelow(dim); } } - + if ( ((pass == 2) && (e->type == SegClose)) || ((pass == 2) && (e->type == Close)) ) { // Clean up neighbour pointers. Node *l = v->firstAbove, *r = v->firstBelow; - if (l != NULL) + if (l != NULL) { l->firstBelow = v->firstBelow; } @@ -1698,7 +1709,7 @@ static void processShiftEvent(Router *router, NodeSet& scanline, } -static void buildOrthogonalChannelInfo(Router *router, +static void buildOrthogonalChannelInfo(Router *router, const size_t dim, ShiftSegmentList& segmentList) { if (router->routingPenalty(segmentPenalty) == 0) @@ -1710,15 +1721,15 @@ static void buildOrthogonalChannelInfo(Router *router, size_t altDim = (dim + 1) % 2; // For each connector. - for (ConnRefList::const_iterator curr = router->connRefs.begin(); - curr != router->connRefs.end(); ++curr) + for (ConnRefList::const_iterator curr = router->connRefs.begin(); + curr != router->connRefs.end(); ++curr) { if ((*curr)->routingType() != ConnType_Orthogonal) { continue; } Polygon& displayRoute = (*curr)->displayRoute(); - // Determine all line segments that we are interested in shifting. + // Determine all line segments that we are interested in shifting. // We don't consider the first or last segment of a path. for (size_t i = 1; i < displayRoute.size(); ++i) { @@ -1732,12 +1743,12 @@ static void buildOrthogonalChannelInfo(Router *router, indexLow = i; indexHigh = i - 1; } - COLA_ASSERT(displayRoute.at(indexLow)[altDim] < + COLA_ASSERT(displayRoute.at(indexLow)[altDim] < displayRoute.at(indexHigh)[altDim]); if ((i == 1) || ((i + 1) == displayRoute.size())) { - // The first and last segment of a connector can't be + // The first and last segment of a connector can't be // shifted. We call them fixed segments. Note: this // will change if we later allow connection channels. segmentList.push_back( @@ -1753,15 +1764,15 @@ static void buildOrthogonalChannelInfo(Router *router, double prevPos = displayRoute.ps[i - 2][dim]; double nextPos = displayRoute.ps[i + 1][dim]; if (((prevPos < displayRoute.ps[i][dim]) && - (nextPos > displayRoute.ps[i][dim])) + (nextPos > displayRoute.ps[i][dim])) || ((prevPos > displayRoute.ps[i][dim]) && (nextPos < displayRoute.ps[i][dim])) ) { isSBend = true; - // Determine limits if the s-bend is not due to an - // obstacle. In this case we need to limit the channel + // Determine limits if the s-bend is not due to an + // obstacle. In this case we need to limit the channel // to the span of the adjoining segments to this one. if ((prevPos < displayRoute.ps[i][dim]) && (nextPos > displayRoute.ps[i][dim])) @@ -1778,7 +1789,7 @@ static void buildOrthogonalChannelInfo(Router *router, else { // isCBend: Both adjoining segments are in the same - // direction. We indicate this for later by setting + // direction. We indicate this for later by setting // the maxLim or minLim to the segment position. if (prevPos < displayRoute.ps[i][dim]) { @@ -1790,7 +1801,7 @@ static void buildOrthogonalChannelInfo(Router *router, } } - segmentList.push_back(ShiftSegment(*curr, indexLow, + segmentList.push_back(ShiftSegment(*curr, indexLow, indexHigh, isSBend, dim, minLim, maxLim)); } } @@ -1800,7 +1811,7 @@ static void buildOrthogonalChannelInfo(Router *router, // There are no segments, so we can just return now. return; } - + // Do a sweep and shift these segments. const size_t n = router->shapeRefs.size(); const size_t cpn = segmentList.size(); @@ -1821,7 +1832,7 @@ static void buildOrthogonalChannelInfo(Router *router, ++shRefIt; } - for (ShiftSegmentList::iterator curr = segmentList.begin(); + for (ShiftSegmentList::iterator curr = segmentList.begin(); curr != segmentList.end(); ++curr) { const Point& lowPt = curr->lowPoint(); @@ -1853,7 +1864,7 @@ static void buildOrthogonalChannelInfo(Router *router, { for (unsigned j = posStartIndex; j < posFinishIndex; ++j) { - processShiftEvent(router, scanline, segmentList, events[j], + processShiftEvent(router, scanline, segmentList, events[j], dim, pass); } } @@ -1868,7 +1879,7 @@ static void buildOrthogonalChannelInfo(Router *router, posStartIndex = i; } - // Do the first sweep event handling -- building the correct + // Do the first sweep event handling -- building the correct // structure of the scanline. const int pass = 1; processShiftEvent(router, scanline, segmentList, events[i], @@ -1886,8 +1897,8 @@ static void buildOrthogonalChannelInfo(Router *router, static void simplifyOrthogonalRoutes(Router *router) { // Simplify routes. - for (ConnRefList::const_iterator curr = router->connRefs.begin(); - curr != router->connRefs.end(); ++curr) + for (ConnRefList::const_iterator curr = router->connRefs.begin(); + curr != router->connRefs.end(); ++curr) { if ((*curr)->routingType() != ConnType_Orthogonal) { @@ -1898,7 +1909,7 @@ static void simplifyOrthogonalRoutes(Router *router) } -static void buildOrthogonalNudgingOrderInfo(Router *router, +static void buildOrthogonalNudgingOrderInfo(Router *router, PtOrderMap& pointOrders) { // Simplify routes. @@ -1907,46 +1918,46 @@ static void buildOrthogonalNudgingOrderInfo(Router *router, int crossingsN = 0; // Do segment splitting. - for (ConnRefList::const_iterator curr = router->connRefs.begin(); - curr != router->connRefs.end(); ++curr) + for (ConnRefList::const_iterator curr = router->connRefs.begin(); + curr != router->connRefs.end(); ++curr) { if ((*curr)->routingType() != ConnType_Orthogonal) { continue; } ConnRef *conn = *curr; - - for (ConnRefList::const_iterator curr2 = router->connRefs.begin(); - curr2 != router->connRefs.end(); ++curr2) + + for (ConnRefList::const_iterator curr2 = router->connRefs.begin(); + curr2 != router->connRefs.end(); ++curr2) { if ((*curr2)->routingType() != ConnType_Orthogonal) { continue; } ConnRef *conn2 = *curr2; - + if (conn == conn2) { continue; } - + Avoid::Polygon& route = conn->displayRoute(); Avoid::Polygon& route2 = conn2->displayRoute(); splitBranchingSegments(route2, true, route); } } - for (ConnRefList::const_iterator curr = router->connRefs.begin(); - curr != router->connRefs.end(); ++curr) + for (ConnRefList::const_iterator curr = router->connRefs.begin(); + curr != router->connRefs.end(); ++curr) { if ((*curr)->routingType() != ConnType_Orthogonal) { continue; } ConnRef *conn = *curr; - - for (ConnRefList::const_iterator curr2 = curr; - curr2 != router->connRefs.end(); ++curr2) + + for (ConnRefList::const_iterator curr2 = curr; + curr2 != router->connRefs.end(); ++curr2) { if ((*curr2)->routingType() != ConnType_Orthogonal) { @@ -1958,7 +1969,7 @@ static void buildOrthogonalNudgingOrderInfo(Router *router, { continue; } - + Avoid::Polygon& route = conn->displayRoute(); Avoid::Polygon& route2 = conn2->displayRoute(); bool checkForBranchingSegments = false; @@ -1966,8 +1977,8 @@ static void buildOrthogonalNudgingOrderInfo(Router *router, for (size_t i = 1; i < route.size(); ++i) { const bool finalSegment = ((i + 1) == route.size()); - crossings += countRealCrossings(route2, true, route, i, - checkForBranchingSegments, finalSegment, NULL, + crossings += countRealCrossings(route2, true, route, i, + checkForBranchingSegments, finalSegment, NULL, &pointOrders, conn2, conn).first; } if (crossings > 0) @@ -1976,7 +1987,7 @@ static void buildOrthogonalNudgingOrderInfo(Router *router, } } } - + // Sort the point orders. PtOrderMap::iterator finish = pointOrders.end(); for (PtOrderMap::iterator it = pointOrders.begin(); it != finish; ++it) @@ -1992,7 +2003,7 @@ static void buildOrthogonalNudgingOrderInfo(Router *router, } -class CmpLineOrder +class CmpLineOrder { public: CmpLineOrder(PtOrderMap& ord, const size_t dim) @@ -2007,11 +2018,11 @@ class CmpLineOrder { *comparable = true; } - Point lhsLow = lhs.lowPoint(); - Point rhsLow = rhs.lowPoint(); + Point lhsLow = lhs.lowPoint(); + Point rhsLow = rhs.lowPoint(); #ifndef NDEBUG - const Point& lhsHigh = lhs.highPoint(); - const Point& rhsHigh = rhs.highPoint(); + const Point& lhsHigh = lhs.highPoint(); + const Point& rhsHigh = rhs.highPoint(); #endif size_t altDim = (dimension + 1) % 2; @@ -2022,9 +2033,9 @@ class CmpLineOrder { return lhsLow[dimension] < rhsLow[dimension]; } - - // If one of these is fixed, then determine order based on - // fixed segment, that is, order so the fixed segment doesn't + + // If one of these is fixed, then determine order based on + // fixed segment, that is, order so the fixed segment doesn't // block movement. bool oneIsFixed = false; const int lhsFixedOrder = lhs.fixedOrder(oneIsFixed); @@ -2034,8 +2045,8 @@ class CmpLineOrder return lhsFixedOrder < rhsFixedOrder; } - // C-bends that did not have a clear order with s-bends might - // not have a good ordering here, so compare their order in + // C-bends that did not have a clear order with s-bends might + // not have a good ordering here, so compare their order in // terms of C-bend direction and S-bends and use that if it // differs for the two segments. const int lhsOrder = lhs.order(); @@ -2056,7 +2067,7 @@ class CmpLineOrder { // A value for rhsPos or lhsPos mean the points are not directly // comparable, meaning they are at the same position but cannot - // overlap (they are just collinear. The relative order for + // overlap (they are just collinear. The relative order for // these segments is not important since we do not constrain // them against each other. //COLA_ASSERT(lhs.overlapsWith(rhs, dimension) == false); @@ -2076,13 +2087,13 @@ class CmpLineOrder }; -// We can use the normaal sort algorithm for lists since it is not possible -// to comapre all elements, but there will be an ordering defined between -// most of the elements. Hence we order these, using insertion sort, and -// the case of them not being able to be compared is handled by not setting +// We can use the normaal sort algorithm for lists since it is not possible +// to comapre all elements, but there will be an ordering defined between +// most of the elements. Hence we order these, using insertion sort, and +// the case of them not being able to be compared is handled by not setting // up any constraints between such segments when doing the nudging. // -static ShiftSegmentList linesort(ShiftSegmentList origList, +static ShiftSegmentList linesort(ShiftSegmentList origList, CmpLineOrder& comparison) { ShiftSegmentList resultList; @@ -2119,7 +2130,7 @@ static ShiftSegmentList linesort(ShiftSegmentList origList, typedef std::list<ShiftSegment *> ShiftSegmentPtrList; -static void nudgeOrthogonalRoutes(Router *router, size_t dimension, +static void nudgeOrthogonalRoutes(Router *router, size_t dimension, PtOrderMap& pointOrders, ShiftSegmentList& segmentList) { // Do the actual nudging. @@ -2160,7 +2171,7 @@ static void nudgeOrthogonalRoutes(Router *router, size_t dimension, } CmpLineOrder lineSortComp(pointOrders, dimension); currentRegion = linesort(currentRegion, lineSortComp); - + if (currentRegion.size() == 1) { // Save creating the solver instance if there is just one @@ -2188,7 +2199,7 @@ static void nudgeOrthogonalRoutes(Router *router, size_t dimension, currSegment != currentRegion.end(); ++currSegment) { Point& lowPt = currSegment->lowPoint(); - + // Create a solver variable for the position of this segment. int varID = freeID; double idealPos = lowPt[dimension]; @@ -2197,7 +2208,7 @@ static void nudgeOrthogonalRoutes(Router *router, size_t dimension, { COLA_ASSERT(currSegment->minSpaceLimit > -CHANNEL_MAX); COLA_ASSERT(currSegment->maxSpaceLimit < CHANNEL_MAX); - + // For s-bends, take the middle as ideal. idealPos = currSegment->minSpaceLimit + ((currSegment->maxSpaceLimit - @@ -2211,7 +2222,7 @@ static void nudgeOrthogonalRoutes(Router *router, size_t dimension, } else { - // Set a higher weight for c-bends to stop them sometimes + // Set a higher weight for c-bends to stop them sometimes // getting pushed out into channels by more-free connectors // to the "inner" side of them. weight = strongWeight; @@ -2234,10 +2245,10 @@ static void nudgeOrthogonalRoutes(Router *router, size_t dimension, if (currSegment->overlapsWith(*prevSeg, dimension) && (!(currSegment->fixed) || !(prevSeg->fixed))) { - // If there is a previous segment to the left that - // could overlap this in the shift direction, then + // If there is a previous segment to the left that + // could overlap this in the shift direction, then // constrain the two segments to be separated. - // Though don't add the constraint if both the + // Though don't add the constraint if both the // segments are fixed in place. cs.push_back(new Constraint(prevVar, vs[index], router->orthogonalNudgeDistance())); @@ -2251,21 +2262,21 @@ static void nudgeOrthogonalRoutes(Router *router, size_t dimension, if (!currSegment->fixed) { - // If this segment sees a channel boundary to its left, + // If this segment sees a channel boundary to its left, // then constrain its placement as such. if (currSegment->minSpaceLimit > -CHANNEL_MAX) { - vs.push_back(new Variable(fixedID, + vs.push_back(new Variable(fixedID, currSegment->minSpaceLimit, fixedWeight)); - cs.push_back(new Constraint(vs[vs.size() - 1], vs[index], + cs.push_back(new Constraint(vs[vs.size() - 1], vs[index], 0.0)); } - - // If this segment sees a channel boundary to its right, + + // If this segment sees a channel boundary to its right, // then constrain its placement as such. if (currSegment->maxSpaceLimit < CHANNEL_MAX) { - vs.push_back(new Variable(fixedID, + vs.push_back(new Variable(fixedID, currSegment->maxSpaceLimit, fixedWeight)); cs.push_back(new Constraint(vs[index], vs[vs.size() - 1], 0.0)); @@ -2281,7 +2292,7 @@ static void nudgeOrthogonalRoutes(Router *router, size_t dimension, IncSolver f(vs,cs); f.solve(); bool satisfied = true; - for (size_t i = 0; i < vs.size(); ++i) + for (size_t i = 0; i < vs.size(); ++i) { if (vs[i]->id == fixedID) { @@ -2323,7 +2334,7 @@ extern void improveOrthogonalRoutes(Router *router) { // Build nudging info. // XXX: We need to build the point orders separately in each - // dimension since things move. There is probably a more + // dimension since things move. There is probably a more // efficient way to do this. PtOrderMap pointOrders; buildOrthogonalNudgingOrderInfo(router, pointOrders); diff --git a/src/libavoid/router.cpp b/src/libavoid/router.cpp index 754c464b4..ab13a981b 100644 --- a/src/libavoid/router.cpp +++ b/src/libavoid/router.cpp @@ -12,12 +12,12 @@ * See the file LICENSE.LGPL distributed with the library. * * Licensees holding a valid commercial license may use this file in - * accordance with the commercial license agreement provided with the + * accordance with the commercial license agreement provided with the * library. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Author(s): Michael Wybrow <mjwybrow@users.sourceforge.net> */ @@ -73,7 +73,7 @@ class ActionInfo { } ShapeRef *shape(void) const { - COLA_ASSERT((type == ShapeMove) || (type == ShapeAdd) || + COLA_ASSERT((type == ShapeMove) || (type == ShapeAdd) || (type == ShapeRemove)); return (static_cast<ShapeRef *> (objPtr)); } @@ -189,8 +189,8 @@ void Router::modifyConnector(ConnRef *conn, const unsigned int type, const ConnEnd& connEnd) { ActionInfo modInfo(ConnChange, conn); - - ActionInfoList::iterator found = + + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), modInfo); if (found == actionList.end()) { @@ -212,8 +212,8 @@ void Router::modifyConnector(ConnRef *conn, const unsigned int type, void Router::modifyConnector(ConnRef *conn) { ActionInfo modInfo(ConnChange, conn); - - ActionInfoList::iterator found = + + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), modInfo); if (found == actionList.end()) { @@ -231,7 +231,7 @@ void Router::removeQueuedConnectorActions(ConnRef *conn) { ActionInfo modInfo(ConnChange, conn); - ActionInfoList::iterator found = + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), modInfo); if (found != actionList.end()) { @@ -245,14 +245,14 @@ void Router::addShape(ShapeRef *shape) // There shouldn't be remove events or move events for the same shape // already in the action list. // XXX: Possibly we could handle this by ordering them intelligently. - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeRemove, shape)) == actionList.end()); - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeMove, shape)) == actionList.end()); ActionInfo addInfo(ShapeAdd, shape); - - ActionInfoList::iterator found = + + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), addInfo); if (found == actionList.end()) { @@ -268,14 +268,14 @@ void Router::addShape(ShapeRef *shape) void Router::removeShape(ShapeRef *shape) { - // There shouldn't be add events events for the same shape already + // There shouldn't be add events events for the same shape already // in the action list. // XXX: Possibly we could handle this by ordering them intelligently. - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeAdd, shape)) == actionList.end()); // Delete any ShapeMove entries for this shape in the action list. - ActionInfoList::iterator found = find(actionList.begin(), + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), ActionInfo(ShapeMove, shape)); if (found != actionList.end()) { @@ -306,16 +306,16 @@ void Router::moveShape(ShapeRef *shape, const double xDiff, const double yDiff) } -void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, +void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, const bool first_move) { // There shouldn't be remove events or add events for the same shape // already in the action list. // XXX: Possibly we could handle this by ordering them intelligently. - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeRemove, shape)) == actionList.end()); - - if (find(actionList.begin(), actionList.end(), + + if (find(actionList.begin(), actionList.end(), ActionInfo(ShapeAdd, shape)) != actionList.end()) { // The Add is enough, no need for the Move action too. @@ -325,7 +325,7 @@ void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, ActionInfo moveInfo(ShapeMove, shape, newPoly, first_move); // Sanely cope with the case where the user requests moving the same // shape multiple times before rerouting connectors. - ActionInfoList::iterator found = + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), moveInfo); if (found != actionList.end()) @@ -339,7 +339,7 @@ void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, // leave the firstMove setting alone. found->newPoly = newPoly; } - else + else { actionList.push_back(moveInfo); } @@ -380,7 +380,7 @@ void Router::destroyOrthogonalVisGraph(void) void Router::regenerateStaticBuiltGraph(void) { - // Here we do talks involved in updating the static-built visibility + // Here we do talks involved in updating the static-built visibility // graph (if necessary) before we do any routing. if (_staticGraphInvalidated) { @@ -391,7 +391,7 @@ void Router::regenerateStaticBuiltGraph(void) timers.Register(tmOrthogGraph, timerStart); // Regenerate a new visibility graph. generateStaticOrthogonalVisGraph(this); - + timers.Stop(); } _staticGraphInvalidated = false; @@ -401,11 +401,11 @@ void Router::regenerateStaticBuiltGraph(void) bool Router::shapeInQueuedActionList(ShapeRef *shape) const { - bool foundAdd = find(actionList.begin(), actionList.end(), + bool foundAdd = find(actionList.begin(), actionList.end(), ActionInfo(ShapeAdd, shape)) != actionList.end(); - bool foundRem = find(actionList.begin(), actionList.end(), + bool foundRem = find(actionList.begin(), actionList.end(), ActionInfo(ShapeRemove, shape)) != actionList.end(); - bool foundMove = find(actionList.begin(), actionList.end(), + bool foundMove = find(actionList.begin(), actionList.end(), ActionInfo(ShapeMove, shape)) != actionList.end(); return (foundAdd || foundRem || foundMove); @@ -456,21 +456,21 @@ bool Router::processTransaction(void) // o Remove entries related to this shape's vertices shape->removeFromGraph(); - + if (SelectiveReroute && (!isMove || notPartialTime || first_move)) { markConnectors(shape); } adjustContainsWithDel(pid); - + // Ignore this shape for visibility. // XXX: We don't really need to do this if we're not using Partial // Feedback. Without this the blocked edges still route // around the shape until it leaves the connector. shape->makeInactive(); } - + if (seenShapeMovesOrDeletes && _polyLineRouting) { if (InvisibilityGrph) @@ -478,7 +478,7 @@ bool Router::processTransaction(void) for (curr = actionList.begin(); curr != finish; ++curr) { ActionInfo& actInf = *curr; - if (!((actInf.type == ShapeRemove) || + if (!((actInf.type == ShapeRemove) || (actInf.type == ShapeMove))) { // Not a move or remove action, so don't do anything. @@ -513,7 +513,7 @@ bool Router::processTransaction(void) // Restore this shape for visibility. shape->makeActive(); - + if (isMove) { shape->setNewPoly(newPoly); @@ -559,7 +559,7 @@ bool Router::processTransaction(void) } // Clear the actionList. actionList.clear(); - + _staticGraphInvalidated = true; rerouteAndCallbackConnectors(); @@ -570,7 +570,7 @@ bool Router::processTransaction(void) void Router::addCluster(ClusterRef *cluster) { cluster->makeActive(); - + unsigned int pid = cluster->id(); ReferencingPolygon& poly = cluster->polygon(); @@ -581,9 +581,9 @@ void Router::addCluster(ClusterRef *cluster) void Router::delCluster(ClusterRef *cluster) { cluster->makeInactive(); - + unsigned int pid = cluster->id(); - + adjustClustersWithDel(pid); } @@ -605,9 +605,9 @@ unsigned int Router::assignId(const unsigned int suggestedId) { // If the suggestedId is zero, then we assign the object the next // smallest unassigned ID, otherwise we trust the ID given is unique. - unsigned int assignedId = (suggestedId == 0) ? + unsigned int assignedId = (suggestedId == 0) ? (_largestAssignedId + 1) : suggestedId; - + // Have the router record if this ID is larger than the _largestAssignedId. _largestAssignedId = std::max(_largestAssignedId, assignedId); @@ -619,17 +619,17 @@ unsigned int Router::assignId(const unsigned int suggestedId) // Returns whether the given ID is unique among all objects known by the - // router. Outputs a warning if the ID is found ore than once. + // router. Outputs a warning if the ID is found ore than once. // It is expected this is only going to be called from assertions while // debugging, so efficiency is not an issue and we just iterate over all // objects. -bool Router::idIsUnique(const unsigned int id) const +bool Router::idIsUnique(const unsigned int id) const { unsigned int count = 0; // Examine shapes. - for (ShapeRefList::const_iterator i = shapeRefs.begin(); - i != shapeRefs.end(); ++i) + for (ShapeRefList::const_iterator i = shapeRefs.begin(); + i != shapeRefs.end(); ++i) { if ((*i)->id() == id) { @@ -638,8 +638,8 @@ bool Router::idIsUnique(const unsigned int id) const } // Examine connectors. - for (ConnRefList::const_iterator i = connRefs.begin(); - i != connRefs.end(); ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); + i != connRefs.end(); ++i) { if ((*i)->id() == id) { @@ -648,8 +648,8 @@ bool Router::idIsUnique(const unsigned int id) const } // Examine clusters. - for (ClusterRefList::const_iterator i = clusterRefs.begin(); - i != clusterRefs.end(); ++i) + for (ClusterRefList::const_iterator i = clusterRefs.begin(); + i != clusterRefs.end(); ++i) { if ((*i)->id() == id) { @@ -679,13 +679,13 @@ void Router::attachedConns(IntList &conns, const unsigned int shapeId, const unsigned int type) { ConnRefList::const_iterator fin = connRefs.end(); - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { - if ((type & runningTo) && ((*i)->_dstId == shapeId)) + if ((type & runningTo) && ((*i)->_dstId == shapeId)) { conns.push_back((*i)->_id); } - else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) + else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) { conns.push_back((*i)->_id); } @@ -699,9 +699,9 @@ void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, const unsigned int type) { ConnRefList::const_iterator fin = connRefs.end(); - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { - if ((type & runningTo) && ((*i)->_dstId == shapeId)) + if ((type & runningTo) && ((*i)->_dstId == shapeId)) { if ((*i)->_srcId != 0) { @@ -709,7 +709,7 @@ void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, shapes.push_back((*i)->_srcId); } } - else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) + else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) { if ((*i)->_dstId != 0) { @@ -721,19 +721,19 @@ void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, } - // It's intended this function is called after visibility changes - // resulting from shape movement have happened. It will alert + // It's intended this function is called after visibility changes + // resulting from shape movement have happened. It will alert // rerouted connectors (via a callback) that they need to be redrawn. void Router::rerouteAndCallbackConnectors(void) { std::set<ConnRef *> reroutedConns; ConnRefList::const_iterator fin = connRefs.end(); - - // Updating the orthogonal visibility graph if necessary. + + // Updating the orthogonal visibility graph if necessary. regenerateStaticBuiltGraph(); timers.Register(tmOrthogRoute, timerStart); - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { (*i)->_needs_repaint = false; bool rerouted = (*i)->generatePath(); @@ -751,7 +751,7 @@ void Router::rerouteAndCallbackConnectors(void) improveOrthogonalRoutes(this); // Alert connectors that they need redrawing. - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { (*i)->_needs_repaint = true; (*i)->performCallback(); @@ -770,18 +770,18 @@ void Router::improveCrossings(void) // No penalties, return. return; } - + // Find crossings and reroute connectors. _inCrossingPenaltyReroutingStage = true; ConnRefSet crossingConns; ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { Avoid::Polygon& iRoute = (*i)->routeRef(); ConnRefList::iterator j = i; - for (++j; j != fin; ++j) + for (++j; j != fin; ++j) { - if ((crossingConns.find(*i) != crossingConns.end()) && + if ((crossingConns.find(*i) != crossingConns.end()) && (crossingConns.find(*j) != crossingConns.end())) { // We already know both these have crossings. @@ -795,13 +795,13 @@ void Router::improveCrossings(void) { const bool finalSegment = ((jInd + 1) == jRoute.size()); CrossingsInfoPair crossingInfo = countRealCrossings( - iRoute, true, jRoute, jInd, false, + iRoute, true, jRoute, jInd, false, finalSegment, NULL, NULL, *i, *j); - - if ((shared_path_penalty > 0) && - (crossingInfo.second & CROSSING_SHARES_PATH) && - (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && - !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) + + if ((shared_path_penalty > 0) && + (crossingInfo.second & CROSSING_SHARES_PATH) && + (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && + !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) { // We are penalising fixedSharedPaths and there is a // fixedSharedPath. @@ -823,7 +823,7 @@ void Router::improveCrossings(void) } } - for (ConnRefSet::iterator i = crossingConns.begin(); + for (ConnRefSet::iterator i = crossingConns.begin(); i != crossingConns.end(); ++i) { ConnRef *conn = *i; @@ -831,7 +831,7 @@ void Router::improveCrossings(void) // XXX: Could we free these routes here for extra savings? // conn->freeRoutes(); } - for (ConnRefSet::iterator i = crossingConns.begin(); + for (ConnRefSet::iterator i = crossingConns.begin(); i != crossingConns.end(); ++i) { ConnRef *conn = *i; @@ -862,9 +862,9 @@ void Router::newBlockingShape(const Polygon& poly, int pid) bool blocked = false; bool countBorder = false; - bool ep_in_poly1 = !(eID1.isShape) ? + bool ep_in_poly1 = !(eID1.isShape) ? inPoly(poly, e1, countBorder) : false; - bool ep_in_poly2 = !(eID2.isShape) ? + bool ep_in_poly2 = !(eID2.isShape) ? inPoly(poly, e2, countBorder) : false; if (ep_in_poly1 || ep_in_poly2) { @@ -879,7 +879,7 @@ void Router::newBlockingShape(const Polygon& poly, int pid) size_t pt_n = (pt_i == (poly.size() - 1)) ? 0 : pt_i + 1; const Point& pi = poly.ps[pt_i]; const Point& pn = poly.ps[pt_n]; - if (segmentShapeIntersect(e1, e2, pi, pn, + if (segmentShapeIntersect(e1, e2, pi, pn, seenIntersectionAtEndpoint)) { blocked = true; @@ -983,7 +983,7 @@ void Router::generateContains(VertInf *pt) // Computer enclosing Clusters ClusterRefList::const_iterator clFinish = clusterRefs.end(); - for (ClusterRefList::const_iterator i = clusterRefs.begin(); + for (ClusterRefList::const_iterator i = clusterRefs.begin(); i != clFinish; ++i) { if (inPolyGen((*i)->polygon(), pt->point)) @@ -994,7 +994,7 @@ void Router::generateContains(VertInf *pt) } -void Router::adjustClustersWithAdd(const PolygonInterface& poly, +void Router::adjustClustersWithAdd(const PolygonInterface& poly, const int p_cluster) { for (VertInf *k = vertices.connsBegin(); k != vertices.shapesBegin(); @@ -1422,11 +1422,11 @@ static void reduceRange(double& val) bool Router::existsOrthogonalPathOverlap(void) { ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { Avoid::Polygon iRoute = (*i)->displayRoute(); ConnRefList::iterator j = i; - for (++j; j != fin; ++j) + for (++j; j != fin; ++j) { // Determine if this pair overlap Avoid::Polygon jRoute = (*j)->displayRoute(); @@ -1435,12 +1435,12 @@ bool Router::existsOrthogonalPathOverlap(void) { const bool finalSegment = ((jInd + 1) == jRoute.size()); CrossingsInfoPair crossingInfo = countRealCrossings( - iRoute, true, jRoute, jInd, true, + iRoute, true, jRoute, jInd, true, finalSegment, NULL, NULL, *i, *j); - - if ((crossingInfo.second & CROSSING_SHARES_PATH) && - (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && - !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) + + if ((crossingInfo.second & CROSSING_SHARES_PATH) && + (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && + !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) { // We looking for fixedSharedPaths and there is a // fixedSharedPath. @@ -1456,11 +1456,11 @@ bool Router::existsOrthogonalPathOverlap(void) bool Router::existsOrthogonalTouchingCorners(void) { ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { Avoid::Polygon iRoute = (*i)->displayRoute(); ConnRefList::iterator j = i; - for (++j; j != fin; ++j) + for (++j; j != fin; ++j) { // Determine if this pair overlap Avoid::Polygon jRoute = (*j)->displayRoute(); @@ -1469,10 +1469,10 @@ bool Router::existsOrthogonalTouchingCorners(void) { const bool finalSegment = ((jInd + 1) == jRoute.size()); CrossingsInfoPair crossingInfo = countRealCrossings( - iRoute, true, jRoute, jInd, true, + iRoute, true, jRoute, jInd, true, finalSegment, NULL, NULL, *i, *j); - - if (crossingInfo.second & CROSSING_TOUCHES) + + if (crossingInfo.second & CROSSING_TOUCHES) { return true; } @@ -1514,7 +1514,7 @@ void Router::outputInstanceToSVG(std::string instanceName) reduceRange(p.x); reduceRange(p.y); - + if (p.x > -LIMIT) { minX = std::min(minX, p.x); @@ -1550,8 +1550,8 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, " PolyLineRouting | OrthogonalRouting);\n"); for (size_t p = 0; p < lastPenaltyMarker; ++p) { - fprintf(fp, " router->setRoutingPenalty((PenaltyType)%lu, %g);\n", - p, _routingPenalties[p]); + fprintf(fp, " router->setRoutingPenalty((PenaltyType)%lu, %g);\n", + static_cast<long unsigned int>(p), _routingPenalties[p]); } fprintf(fp, " router->setOrthogonalNudgeDistance(%g);\n\n", orthogonalNudgeDistance()); @@ -1559,12 +1559,12 @@ void Router::outputInstanceToSVG(std::string instanceName) while (shRefIt != shapeRefs.end()) { ShapeRef *shRef = *shRefIt; - fprintf(fp, " Polygon poly%u(%lu);\n", - shRef->id(), shRef->polygon().size()); + fprintf(fp, " Polygon poly%u(%lu);\n", + shRef->id(), static_cast<long unsigned int>(shRef->polygon().size())); for (size_t i = 0; i < shRef->polygon().size(); ++i) { - fprintf(fp, " poly%u.ps[%lu] = Point(%g, %g);\n", - shRef->id(), i, shRef->polygon().at(i).x, + fprintf(fp, " poly%u.ps[%lu] = Point(%g, %g);\n", + shRef->id(), static_cast<long unsigned int>(i), shRef->polygon().at(i).x, shRef->polygon().at(i).y); } fprintf(fp, " ShapeRef *shapeRef%u = new ShapeRef(router, poly%u, " @@ -1594,7 +1594,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, " connRef%u->setDestEndpoint(dstPt%u);\n", connRef->id(), connRef->id()); } - fprintf(fp, " connRef%u->setRoutingType((ConnType)%u);\n\n", + fprintf(fp, " connRef%u->setRoutingType((ConnType)%u);\n\n", connRef->id(), connRef->routingType()); ++revConnRefIt; } @@ -1605,20 +1605,20 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "};\n"); fprintf(fp, "-->\n"); - + fprintf(fp, "<g inkscape:groupmode=\"layer\" " "inkscape:label=\"ShapesPoly\">\n"); shRefIt = shapeRefs.begin(); while (shRefIt != shapeRefs.end()) { ShapeRef *shRef = *shRefIt; - + fprintf(fp, "<path id=\"poly-%u\" style=\"stroke-width: 1px; " - "stroke: black; fill: blue; fill-opacity: 0.3;\" d=\"", + "stroke: black; fill: blue; fill-opacity: 0.3;\" d=\"", shRef->id()); for (size_t i = 0; i < shRef->polygon().size(); ++i) { - fprintf(fp, "%c %g,%g ", ((i == 0) ? 'M' : 'L'), + fprintf(fp, "%c %g,%g ", ((i == 0) ? 'M' : 'L'), shRef->polygon().at(i).x, shRef->polygon().at(i).y); } fprintf(fp, "Z\" />\n"); @@ -1635,7 +1635,7 @@ void Router::outputInstanceToSVG(std::string instanceName) ShapeRef *shRef = *shRefIt; double minX, minY, maxX, maxY; shRef->polygon().getBoundingRect(&minX, &minY, &maxX, &maxY); - + fprintf(fp, "<rect id=\"rect-%u\" x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" " "style=\"stroke-width: 1px; stroke: black; fill: blue; fill-opacity: 0.3;\" />\n", shRef->id(), minX, minY, maxX - minX, maxY - minY); @@ -1664,16 +1664,16 @@ void Router::outputInstanceToSVG(std::string instanceName) std::pair<Point, Point> ptpair = t->points(); Point p1 = ptpair.first; Point p2 = ptpair.second; - + reduceRange(p1.x); reduceRange(p1.y); reduceRange(p2.x); reduceRange(p2.y); - + fprintf(fp, "<path d=\"M %g,%g L %g,%g\" " - "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", + "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", p1.x, p1.y, p2.x, p2.y, - (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : "red"); } fprintf(fp, "</g>\n"); @@ -1694,16 +1694,16 @@ void Router::outputInstanceToSVG(std::string instanceName) std::pair<Point, Point> ptpair = t->points(); Point p1 = ptpair.first; Point p2 = ptpair.second; - + reduceRange(p1.x); reduceRange(p1.y); reduceRange(p2.x); reduceRange(p2.y); - + fprintf(fp, "<path d=\"M %g,%g L %g,%g\" " - "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", + "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", p1.x, p1.y, p2.x, p2.y, - (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : "red"); } fprintf(fp, "</g>\n"); @@ -1718,18 +1718,18 @@ void Router::outputInstanceToSVG(std::string instanceName) std::pair<Point, Point> ptpair = t->points(); Point p1 = ptpair.first; Point p2 = ptpair.second; - + reduceRange(p1.x); reduceRange(p1.y); reduceRange(p2.x); reduceRange(p2.y); - + std::pair<VertID, VertID> ids = t->ids(); fprintf(fp, "<path d=\"M %g,%g L %g,%g\" " - "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", + "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", p1.x, p1.y, p2.x, p2.y, - (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : "red"); } fprintf(fp, "</g>\n"); @@ -1742,7 +1742,7 @@ void Router::outputInstanceToSVG(std::string instanceName) while (connRefIt != connRefs.end()) { ConnRef *connRef = *connRefIt; - + PolyLine route = connRef->route(); if (!route.empty()) { @@ -1762,7 +1762,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "style=\"fill: none; stroke: black; " "stroke-width: 1px;\" />\n"); } - + ++connRefIt; } fprintf(fp, "</g>\n"); @@ -1775,7 +1775,7 @@ void Router::outputInstanceToSVG(std::string instanceName) while (connRefIt != connRefs.end()) { ConnRef *connRef = *connRefIt; - + PolyLine route = connRef->displayRoute().curvedPolyline(8); if (!route.empty()) { @@ -1785,7 +1785,7 @@ void Router::outputInstanceToSVG(std::string instanceName) { if (route.ts[i] == 'C') { - fprintf(fp, "%c %g,%g %g,%g %g,%g", route.ts[i], + fprintf(fp, "%c %g,%g %g,%g %g,%g", route.ts[i], route.ps[i].x, route.ps[i].y, route.ps[i+1].x, route.ps[i+1].y, route.ps[i+2].x, route.ps[i+2].y); @@ -1793,7 +1793,7 @@ void Router::outputInstanceToSVG(std::string instanceName) } else { - fprintf(fp, "%c %g,%g ", route.ts[i], + fprintf(fp, "%c %g,%g ", route.ts[i], route.ps[i].x, route.ps[i].y); } } @@ -1807,7 +1807,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "style=\"fill: none; stroke: black; " "stroke-width: 1px;\" />\n"); } - + ++connRefIt; } fprintf(fp, "</g>\n"); @@ -1820,7 +1820,7 @@ void Router::outputInstanceToSVG(std::string instanceName) while (connRefIt != connRefs.end()) { ConnRef *connRef = *connRefIt; - + PolyLine route = connRef->displayRoute(); if (!route.empty()) { @@ -1840,7 +1840,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "style=\"fill: none; stroke: black; " "stroke-width: 1px;\" />\n"); } - + ++connRefIt; } fprintf(fp, "</g>\n"); diff --git a/src/libavoid/vpsc.cpp b/src/libavoid/vpsc.cpp index c9a072375..19d360375 100644 --- a/src/libavoid/vpsc.cpp +++ b/src/libavoid/vpsc.cpp @@ -12,12 +12,12 @@ * See the file LICENSE.LGPL distributed with the library. * * Licensees holding a valid commercial license may use this file in - * accordance with the commercial license agreement provided with the + * accordance with the commercial license agreement provided with the * library. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Author(s): Tim Dwyer <Tim.Dwyer@csse.monash.edu.au> * @@ -52,11 +52,11 @@ namespace Avoid { static const double ZERO_UPPERBOUND=-1e-10; static const double LAGRANGIAN_TOLERANCE=-1e-4; -IncSolver::IncSolver(vector<Variable*> const &vs, vector<Constraint *> const &cs) - : m(cs.size()), - cs(cs), - n(vs.size()), - vs(vs) +IncSolver::IncSolver(vector<Variable*> const &vs, vector<Constraint *> const &cs) + : m(cs.size()), + cs(cs), + n(vs.size()), + vs(vs) { for(unsigned i=0;i<n;++i) { vs[i]->in.clear(); @@ -232,7 +232,7 @@ bool IncSolver::solve() { #endif } copyResult(); - return bs->size()!=n; + return bs->size()!=n; } /* * incremental version of satisfy that allows refinement after blocks are @@ -244,8 +244,8 @@ bool IncSolver::solve() { * * Note: there is a special case to handle when the most violated constraint * is between two variables in the same block. Then, we must split the block - * over an active constraint between the two variables. We choose the - * constraint with the most negative lagrangian multiplier. + * over an active constraint between the two variables. We choose the + * constraint with the most negative lagrangian multiplier. */ bool IncSolver::satisfy() { #ifdef LIBVPSC_LOGGING @@ -256,8 +256,8 @@ bool IncSolver::satisfy() { //long splitCtr = 0; Constraint* v = NULL; //CBuffer buffer(inactive); - while((v=mostViolated(inactive)) - &&(v->equality || v->slack() < ZERO_UPPERBOUND && !v->active)) + while((v = mostViolated(inactive)) + && (v->equality || ((v->slack() < ZERO_UPPERBOUND) && !v->active))) { COLA_ASSERT(!v->active); Block *lb = v->left->block, *rb = v->right->block; @@ -411,7 +411,7 @@ Constraint* IncSolver::mostViolated(Constraints &l) { Constraint *c=*i; double slack = c->slack(); if(c->equality || slack < minSlack) { - minSlack=slack; + minSlack=slack; v=c; deletePoint=i; if(c->equality) break; @@ -421,7 +421,8 @@ Constraint* IncSolver::mostViolated(Constraints &l) { // move the last element over the deletePoint and resize // downwards. There is always at least 1 element in the // vector because of search. - if(deletePoint != end && (minSlack < ZERO_UPPERBOUND && !v->active || v->equality)) { + // TODO check this logic and add parens: + if((deletePoint != end) && ((minSlack < ZERO_UPPERBOUND) && !v->active || v->equality)) { *deletePoint = l[l.size()-1]; l.resize(l.size()-1); } @@ -457,7 +458,7 @@ Blocks::~Blocks(void) } /* - * returns a list of variables with total ordering determined by the constraint + * returns a list of variables with total ordering determined by the constraint * DAG */ list<Variable*> *Blocks::totalOrder() { @@ -482,7 +483,7 @@ void Blocks::dfsVisit(Variable *v, list<Variable*> *order) { if(!c->right->visited) { dfsVisit(c->right, order); } - } + } #ifdef LIBVPSC_LOGGING ofstream f(LOGFILE,ios::app); f<<" order="<<*v<<endl; @@ -493,7 +494,7 @@ void Blocks::dfsVisit(Variable *v, list<Variable*> *order) { * Processes incoming constraints, most violated to least, merging with the * neighbouring (left) block until no more violated constraints are found */ -void Blocks::mergeLeft(Block *r) { +void Blocks::mergeLeft(Block *r) { #ifdef LIBVPSC_LOGGING ofstream f(LOGFILE,ios::app); f<<"mergeLeft called on "<<*r<<endl; @@ -506,7 +507,7 @@ void Blocks::mergeLeft(Block *r) { f<<"mergeLeft on constraint: "<<*c<<endl; #endif r->deleteMinInConstraint(); - Block *l = c->left->block; + Block *l = c->left->block; if (l->in==NULL) l->setUpInConstraints(); double dist = c->right->offset - c->left->offset - c->gap; if (r->vars->size() < l->vars->size()) { @@ -519,22 +520,22 @@ void Blocks::mergeLeft(Block *r) { r->timeStamp=blockTimeCtr; removeBlock(l); c=r->findMinInConstraint(); - } + } #ifdef LIBVPSC_LOGGING f<<"merged "<<*r<<endl; #endif -} +} /* * Symmetrical to mergeLeft */ -void Blocks::mergeRight(Block *l) { +void Blocks::mergeRight(Block *l) { #ifdef LIBVPSC_LOGGING ofstream f(LOGFILE,ios::app); f<<"mergeRight called on "<<*l<<endl; -#endif +#endif l->setUpOutConstraints(); Constraint *c = l->findMinOutConstraint(); - while (c != NULL && c->slack()<0) { + while (c != NULL && c->slack()<0) { #ifdef LIBVPSC_LOGGING f<<"mergeRight on constraint: "<<*c<<endl; #endif @@ -550,7 +551,7 @@ void Blocks::mergeRight(Block *l) { l->mergeOut(r); removeBlock(r); c=l->findMinOutConstraint(); - } + } #ifdef LIBVPSC_LOGGING f<<"merged "<<*l<<endl; #endif @@ -618,7 +619,7 @@ void PositionStats::addVariable(Variable* v) { /* #ifdef LIBVPSC_LOGGING ofstream f(LOGFILE,ios::app); - f << "adding v[" << v->id << "], blockscale=" << scale << ", despos=" + f << "adding v[" << v->id << "], blockscale=" << scale << ", despos=" << v->desiredPosition << ", ai=" << ai << ", bi=" << bi << ", AB=" << AB << ", AD=" << AD << ", A2=" << A2; #endif @@ -692,12 +693,12 @@ void Block::setUpConstraintHeap(Heap* &h,bool in) { for (Cit j=cs->begin();j!=cs->end();++j) { Constraint *c=*j; c->timeStamp=blockTimeCtr; - if (c->left->block != this && in || c->right->block != this && !in) { + if (((c->left->block != this) && in) || ((c->right->block != this) && !in)) { h->push(c); } } } -} +} Block* Block::merge(Block* b, Constraint* c) { #ifdef LIBVPSC_LOGGING ofstream f(LOGFILE,ios::app); @@ -772,7 +773,7 @@ void Block::mergeIn(Block *b) { f<<" merged heap: "<<*in<<endl; #endif } -void Block::mergeOut(Block *b) { +void Block::mergeOut(Block *b) { findMinOutConstraint(); b->findMinOutConstraint(); while (!b->out->empty()) @@ -904,21 +905,21 @@ double Block::compute_dfdv(Variable* const v, Variable* const u) { } // The top level v and r are variables between which we want to find the -// constraint with the smallest lm. +// constraint with the smallest lm. // Similarly, m is initially NULL and is only assigned a value if the next // variable to be visited is r or if a possible min constraint is returned from // a nested call (rather than NULL). // Then, the search for the m with minimum lm occurs as we return from -// the recursion (checking only constraints traversed left-to-right +// the recursion (checking only constraints traversed left-to-right // in order to avoid creating any new violations). // We also do not consider equality constraints as potential split points bool Block::split_path( - Variable* r, - Variable* const v, - Variable* const u, + Variable* r, + Variable* const v, + Variable* const u, Constraint* &m, bool desperation=false - ) + ) { for(Cit it(v->in.begin());it!=v->in.end();++it) { Constraint *c=*it; @@ -963,43 +964,43 @@ bool Block::split_path( } /* Block::Pair Block::compute_dfdv_between( - Variable* r, Variable* const v, Variable* const u, + Variable* r, Variable* const v, Variable* const u, const Direction dir = NONE, bool changedDirection = false) { double dfdv=v->weight*(v->position() - v->desiredPosition); Constraint *m=NULL; for(Cit it(v->in.begin());it!=v->in.end();++it) { Constraint *c=*it; if(canFollowLeft(c,u)) { - if(dir==RIGHT) { - changedDirection = true; + if(dir==RIGHT) { + changedDirection = true; } if(c->left==r) { r=NULL; - if(!c->equality) m=c; + if(!c->equality) m=c; } Pair p=compute_dfdv_between(r,c->left,v, LEFT,changedDirection); dfdv -= c->lm = -p.first; - if(r && p.second) + if(r && p.second) m = p.second; } } for(Cit it(v->out.begin());it!=v->out.end();++it) { Constraint *c=*it; if(canFollowRight(c,u)) { - if(dir==LEFT) { - changedDirection = true; + if(dir==LEFT) { + changedDirection = true; } if(c->right==r) { - r=NULL; - if(!c->equality) m=c; + r=NULL; + if(!c->equality) m=c; } Pair p=compute_dfdv_between(r,c->right,v, RIGHT,changedDirection); dfdv += c->lm = p.first; - if(r && p.second) - m = changedDirection && !c->equality && c->lm < p.second->lm - ? c + if(r && p.second) + m = changedDirection && !c->equality && c->lm < p.second->lm + ? c : p.second; } } @@ -1084,7 +1085,7 @@ Constraint *Block::findMinLMBetween(Variable* const lv, Variable* const rv) { return min_lm; } -// populates block b by traversing the active constraint tree adding variables as they're +// populates block b by traversing the active constraint tree adding variables as they're // visited. Starts from variable v and does not backtrack over variable u. void Block::populateSplitBlock(Block *b, Variable* v, Variable const* u) { b->addVariable(v); @@ -1093,7 +1094,7 @@ void Block::populateSplitBlock(Block *b, Variable* v, Variable const* u) { populateSplitBlock(b, (*c)->left, v); } for (Cit c=v->out.begin();c!=v->out.end();++c) { - if (canFollowRight(*c,u)) + if (canFollowRight(*c,u)) populateSplitBlock(b, (*c)->right, v); } } @@ -1225,7 +1226,7 @@ Constraint::Constraint(Variable *left, Variable *right, double gap, bool equalit //right->in.push_back(this); } Constraint::~Constraint() { - // see constructor: the following is just way too slow. + // see constructor: the following is just way too slow. // Better to create a // new DAG on demand than maintain the lists dynamically. //Constraints::iterator i; @@ -1238,10 +1239,10 @@ Constraint::~Constraint() { //} //right->in.erase(i); } -double Constraint::slack() const { +double Constraint::slack() const { return unsatisfiable ? DBL_MAX - : right->scale * right->position() - - gap - left->scale * left->position(); + : right->scale * right->position() + - gap - left->scale * left->position(); } std::ostream& operator <<(std::ostream &os, const Constraint &c) { @@ -1269,11 +1270,11 @@ std::ostream& operator <<(std::ostream &os, const Constraint &c) bool CompareConstraints::operator() ( Constraint *const &l, Constraint *const &r ) const { - double const sl = + double const sl = l->left->block->timeStamp > l->timeStamp ||l->left->block==l->right->block ?-DBL_MAX:l->slack(); - double const sr = + double const sr = r->left->block->timeStamp > r->timeStamp ||r->left->block==r->right->block ?-DBL_MAX:r->slack(); diff --git a/src/libcroco/cr-cascade.c b/src/libcroco/cr-cascade.c index f389fc746..7fef86c4a 100644 --- a/src/libcroco/cr-cascade.c +++ b/src/libcroco/cr-cascade.c @@ -70,6 +70,7 @@ cr_cascade_new (CRStyleSheet * a_author_sheet, PRIVATE (result) = (CRCascadePriv *)g_try_malloc (sizeof (CRCascadePriv)); if (!PRIVATE (result)) { + g_free(result); cr_utils_trace_info ("Out of memory"); return NULL; } diff --git a/src/libnr/Makefile_insert b/src/libnr/Makefile_insert index 5cd2717be..4b19028f9 100644 --- a/src/libnr/Makefile_insert +++ b/src/libnr/Makefile_insert @@ -5,7 +5,6 @@ libnr_mmx_sources = \ libnr/have_mmx.S \ libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S \ libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S \ - libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S \ libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S endif diff --git a/src/libnr/nr-compose-transform.cpp b/src/libnr/nr-compose-transform.cpp index afc8fd987..6e03faf2f 100644 --- a/src/libnr/nr-compose-transform.cpp +++ b/src/libnr/nr-compose-transform.cpp @@ -16,30 +16,25 @@ #include "nr-pixops.h" #include "nr-matrix.h" - -#ifdef WITH_MMX +/*#ifdef WITH_MMX #ifdef __cplusplus extern "C" { -#endif /* __cplusplus */ -/* fixme: */ -int nr_have_mmx (void); -void nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h, int rs, - const unsigned char *spx, int sw, int sh, int srs, - const long *FFd2s, unsigned int alpha); -void nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h, int rs, - const unsigned char *spx, int sw, int sh, int srs, - const long *FFd2s, const long *FF_S, unsigned int alpha, int dbits); +#endif // __cplusplus +/ * fixme: * / +/ *int nr_have_mmx (void); #define NR_PIXOPS_MMX (1 && nr_have_mmx ()) #ifdef __cplusplus } #endif //__cplusplus #endif +*/ /* fixme: Implement missing (Lauris) */ /* fixme: PREMUL colors before calculating average (Lauris) */ /* Fixed point precision */ #define FBITS 12 +#define FBITS_HP 18 // In some places we need a higher precision void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int sw, int sh, int srs, @@ -168,10 +163,10 @@ void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, in static void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int sw, int sh, int srs, - const long *FFd2s, unsigned int alpha) + const long long *FFd2s, unsigned int alpha) { - unsigned char *d0; - int FFsx0, FFsy0; + unsigned char *d0; + long long FFsx0, FFsy0; int x, y; d0 = px; @@ -180,15 +175,15 @@ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h for (y = 0; y < h; y++) { unsigned char *d; - long FFsx, FFsy; + long long FFsx, FFsy; d = d0; FFsx = FFsx0; FFsy = FFsy0; for (x = 0; x < w; x++) { long sx, sy; - sx = FFsx >> FBITS; + sx = long(FFsx >> FBITS_HP); if ((sx >= 0) && (sx < sw)) { - sy = FFsy >> FBITS; + sy = long(FFsy >> FBITS_HP); if ((sy >= 0) && (sy < sh)) { const unsigned char *s; unsigned int a; @@ -224,11 +219,11 @@ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h static void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int sw, int sh, int srs, - const long *FFd2s, const long *FF_S, unsigned int alpha, int dbits) + const long long *FFd2s, const long *FF_S, unsigned int alpha, int dbits) { int size; unsigned char *d0; - int FFsx0, FFsy0; + long long FFsx0, FFsy0; int x, y; size = (1 << dbits); @@ -242,7 +237,7 @@ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h for (y = 0; y < h; y++) { unsigned char *d; - long FFsx, FFsy; + long long FFsx, FFsy; d = d0; FFsx = FFsx0; FFsy = FFsy0; @@ -252,9 +247,9 @@ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h r = g = b = a = 0; for (i = 0; i < size; i++) { long sx, sy; - sx = (FFsx + FF_S[2 * i]) >> FBITS; + sx = (long (FFsx >> (FBITS_HP - FBITS)) + FF_S[2 * i]) >> FBITS; if ((sx >= 0) && (sx < sw)) { - sy = (FFsy + FF_S[2 * i + 1]) >> FBITS; + sy = (long (FFsy >> (FBITS_HP - FBITS)) + FF_S[2 * i + 1]) >> FBITS; if ((sy >= 0) && (sy < sh)) { const unsigned char *s; unsigned int ca; @@ -302,6 +297,7 @@ void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, in { int dbits; long FFd2s[6]; + long long FFd2s_HP[6]; // with higher precision int i; if (alpha == 0) return; @@ -310,17 +306,11 @@ void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, in for (i = 0; i < 6; i++) { FFd2s[i] = (long) (d2s[i] * (1 << FBITS) + 0.5); + FFd2s_HP[i] = (long long) (d2s[i] * (1 << FBITS_HP) + 0.5);; } if (dbits == 0) { -#ifdef WITH_MMX - if (NR_PIXOPS_MMX) { - /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ - nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s, alpha); - return; - } -#endif - nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s, alpha); + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s_HP, alpha); } else { int xsize, ysize; long FFs_x_x_S, FFs_x_y_S, FFs_y_x_S, FFs_y_y_S; @@ -344,14 +334,7 @@ void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, in } } -#ifdef WITH_MMX - if (NR_PIXOPS_MMX) { - /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ - nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s, FF_S, alpha, dbits); - return; - } -#endif - nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s, FF_S, alpha, dbits); + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s_HP, FF_S, alpha, dbits); } } diff --git a/src/libnr/nr-compose.cpp b/src/libnr/nr-compose.cpp index 3b99678e2..74f9d036b 100644 --- a/src/libnr/nr-compose.cpp +++ b/src/libnr/nr-compose.cpp @@ -773,6 +773,7 @@ nr_R8G8B8A8_P_EMPTY_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const un c[3] = a; /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP (px, w, h, rs, mpx, mrs, c); + // This mmx optimized code is approx. 2x faster than the non-optimized code below (Measured by Diederik van Lierop, 2009-12-17) return; } #endif diff --git a/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S b/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S deleted file mode 100644 index e30056af2..000000000 --- a/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S +++ /dev/null @@ -1,414 +0,0 @@ - .file "nr-compose-transform.c" - -# Ensure Inkscape is execshield protected - .section .note.GNU-stack - .previous - - .text - .align 2 -.globl nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 - .type nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0,@function - -/* - * This code is in public domain - * - */ - -nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0: - pushl %ebp - movl %esp, %ebp - pushl %ebx - subl $48, %esp - pushl %edi - pushl %esi - -/* Load %mm7 with [0 0 0 0] */ - movl $0, %eax - movd %eax, %mm7 - -/* Load %mm6 with [128 128 128 128] */ - movl $0x80808080, %eax - movd %eax, %mm6 - punpcklbw %mm7, %mm6 - -/* Load %mm5 with [255 255 255 255] */ - movl $0xffffffff, %eax - movd %eax, %mm5 - punpcklbw %mm7, %mm5 - -/* Load %mm0 with [a a a a] */ - movzbl 44(%ebp), %eax - movd %eax, %mm0 - punpcklwd %mm0, %mm0 - punpckldq %mm0, %mm0 - - movl 8(%ebp), %eax - movl %eax, -8(%ebp) - movl 40(%ebp), %eax - addl $16, %eax - movl (%eax), %eax - movl %eax, -12(%ebp) - movl 40(%ebp), %eax - addl $20, %eax - movl (%eax), %eax - movl %eax, -16(%ebp) - movl $0, -24(%ebp) -.L29: - movl -24(%ebp), %eax - cmpl 16(%ebp), %eax - jl .L32 - jmp .L28 -.L32: - movl -8(%ebp), %edi - - movl -12(%ebp), %eax - movl %eax, %esi - movl -16(%ebp), %eax - movl %eax, -36(%ebp) - - movl 12(%ebp), %ebx -.for_x_0: - - movl %esi, %ecx - cmpl $0, %ecx - js .clip_0 - sarl $12, %ecx - cmpl 28(%ebp), %ecx - jge .clip_0 - shll $2, %ecx - - movl -36(%ebp), %eax - cmpl $0, %eax - js .clip_0 - sarl $12, %eax - cmpl 32(%ebp), %eax - jge .clip_0 - imull 36(%ebp), %eax - - addl %ecx, %eax - addl 24(%ebp), %eax - -/* Fg -> %mm1 */ - movl (%eax), %eax - testl $0xff000000, %eax - jz .clip_0 - movd %eax, %mm1 - punpcklbw %mm7, %mm1 - -/* [a a a 255] -> %mm3 */ - shrl $24, %eax - movl $0x10101, %edx - mull %edx - orl $0xff000000, %eax - movd %eax, %mm3 - punpcklbw %mm7, %mm3 - -/* [Fg * a] -> mm1 */ - pmullw %mm3, %mm1 - paddw %mm6, %mm1 - movq %mm1, %mm4 - psrlw $8, %mm4 - paddw %mm4, %mm1 - psrlw $8, %mm1 - -/* Multiply by alpha */ - pmullw %mm0, %mm1 - paddw %mm6, %mm1 - movq %mm1, %mm4 - psrlw $8, %mm4 - paddw %mm4, %mm1 - psrlw $8, %mm1 - -/* [255 - FgA] -> mm2 */ - movq %mm1, %mm2 - punpckhwd %mm2, %mm2 - punpckhdq %mm2, %mm2 - pxor %mm5, %mm2 - -/* Bg -> mm3 */ - movd (%edi), %mm3 - punpcklbw %mm7, %mm3 - -/* Fg + ((255 - FgA) * Bg) / 255 */ - - pmullw %mm2, %mm3 - paddw %mm6, %mm3 - movq %mm3, %mm4 - psrlw $8, %mm4 - paddw %mm4, %mm3 - psrlw $8, %mm3 - paddw %mm1, %mm3 - -/* Store pixel */ - packuswb %mm3, %mm3 - movd %mm3, (%edi) - -.clip_0: -.L37: - movl 40(%ebp), %ecx - movl (%ecx), %edx - addl %edx, %esi - movl 4(%ecx), %edx - addl %edx, -36(%ebp) - - addl $4, %edi - - decl %ebx - jnz .for_x_0 - -.L34: - movl 8(%ecx), %edx - addl %edx, -12(%ebp) - movl 12(%ecx), %edx - addl %edx, -16(%ebp) - - movl 20(%ebp), %edx - leal -8(%ebp), %eax - addl %edx, (%eax) - leal -24(%ebp), %eax - incl (%eax) - jmp .L29 -.L28: - emms - popl %esi - popl %edi - addl $48, %esp - popl %ebx - popl %ebp - ret -.Lfe2: - .size nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0,.Lfe2-nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 - -/* - * - * dbits 52(%ebp) - * alpha 48(%ebp) - * FF_S 44(%ebp) - * - * d -32(%ebp) -> %edi - * i -60(%ebp) -> %esi - * sx -64(%ebp) -> %ebx - * sy -68(%ebp) - * s -72(%ebp) - * - * %mm0 a a a a - * %mm1 FgA - * %mm2 SumFgA - * %mm3 a a a 255 - * %mm4 -*/ - - .align 2 -.globl nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n - .type nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n,@function -nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n: - pushl %ebp - movl %esp, %ebp - pushl %ebx - subl $72, %esp - pushl %edi - pushl %esi - -/* Load %mm7 with [0 0 0 0] */ - movl $0, %eax - movd %eax, %mm7 - -/* Load %mm6 with [128 128 128 128] */ - movl $0x80808080, %eax - movd %eax, %mm6 - punpcklbw %mm7, %mm6 - -/* Load %mm5 with [255 255 255 255] */ - movl $0xffffffff, %eax - movd %eax, %mm5 - punpcklbw %mm7, %mm5 - -/* Load %mm0 with [a a a a] */ - movzbl 48(%ebp), %eax - movd %eax, %mm0 - punpcklwd %mm0, %mm0 - punpckldq %mm0, %mm0 - - movl $1, %eax - movzbl 52(%ebp), %ecx - sall %cl, %eax - movl %eax, -8(%ebp) - movl 8(%ebp), %eax - movl %eax, -12(%ebp) - movl 40(%ebp), %eax - addl $16, %eax - movl (%eax), %eax - movl %eax, -16(%ebp) - movl 40(%ebp), %eax - addl $20, %eax - movl (%eax), %eax - movl %eax, -20(%ebp) - movl $0, -28(%ebp) -.L44: - movl -28(%ebp), %eax - cmpl 16(%ebp), %eax - jl .L47 - jmp .exit_n -.L47: - movl -12(%ebp), %eax - movl %eax, -32(%ebp) - movl -16(%ebp), %eax - movl %eax, -36(%ebp) - movl -20(%ebp), %eax - movl %eax, -40(%ebp) - movl $0, -24(%ebp) -.L48: - movl -24(%ebp), %eax - cmpl 12(%ebp), %eax - jl .L51 - jmp .L49 -.L51: - -/* Zero accumulator */ - movq %mm7, %mm2 - -/* Set i to dptr (size - 1) */ - movl -8(%ebp), %esi - sub $1, %esi - shll $3, %esi - - movl 44(%ebp), %edi - movl -36(%ebp), %ecx - -.for_i_n: - movl (%edi,%esi), %ebx - addl %ecx, %ebx -/* Test negative before shift */ - cmpl $0, %ebx - js .next_i_n - sarl $12, %ebx - cmpl 28(%ebp), %ebx - jge .next_i_n -/* We multiply sx by 4 here */ - shll $2, %ebx - - movl 4(%edi,%esi), %eax - addl -40(%ebp), %eax -/* Test negative before shift */ - cmpl $0, %eax - js .next_i_n - sarl $12, %eax - cmpl 32(%ebp), %eax - jge .next_i_n -/* We multiply sy by srs here */ - imull 36(%ebp), %eax - - addl %ebx, %eax - addl 24(%ebp), %eax - -/* Fg -> %mm1 */ - movl (%eax), %eax - testl $0xff000000, %eax - jz .next_i_n - movd %eax, %mm1 - punpcklbw %mm7, %mm1 - -/* [a a a 255] -> %mm3 */ - shrl $24, %eax - movl $0x10101, %edx - mull %edx - orl $0xff000000, %eax - movd %eax, %mm3 - punpcklbw %mm7, %mm3 - -/* [Fg * a] -> mm1 */ - pmullw %mm3, %mm1 - paddw %mm6, %mm1 - movq %mm1, %mm4 - psrlw $8, %mm4 - paddw %mm4, %mm1 - psrlw $8, %mm1 - -/* Add to accumulator */ - paddw %mm1, %mm2 - -.next_i_n: - subl $8, %esi - jnb .for_i_n - -/* Divide components by sample size */ - movd 52(%ebp), %mm3 - psrlw %mm3, %mm2 - -/* Multiply by alpha */ - pmullw %mm0, %mm2 - paddw %mm6, %mm2 - movq %mm2, %mm4 - psrlw $8, %mm4 - paddw %mm4, %mm2 - psrlw $8, %mm2 - -/* [255 - FgA] -> mm1 */ - movq %mm2, %mm1 - punpckhwd %mm1, %mm1 - punpckhdq %mm1, %mm1 - pxor %mm5, %mm1 - - movl -32(%ebp), %edi -/* Bg -> mm3 */ - movd (%edi), %mm3 - punpcklbw %mm7, %mm3 - -/* Fg + ((255 - FgA) * Bg) / 255 */ - - pmullw %mm1, %mm3 - paddw %mm6, %mm3 - movq %mm3, %mm4 - psrlw $8, %mm4 - paddw %mm4, %mm3 - psrlw $8, %mm3 - paddw %mm2, %mm3 - -/* Store pixel */ - packuswb %mm3, %mm3 - movd %mm3, (%edi) - -.L58: - movl 40(%ebp), %eax - movl (%eax), %edx - leal -36(%ebp), %eax - addl %edx, (%eax) - movl 40(%ebp), %eax - addl $4, %eax - movl (%eax), %edx - leal -40(%ebp), %eax - addl %edx, (%eax) - leal -32(%ebp), %eax - addl $4, (%eax) - leal -24(%ebp), %eax - incl (%eax) - jmp .L48 -.L49: - movl 40(%ebp), %eax - addl $8, %eax - movl (%eax), %edx - leal -16(%ebp), %eax - addl %edx, (%eax) - movl 40(%ebp), %eax - addl $12, %eax - movl (%eax), %edx - leal -20(%ebp), %eax - addl %edx, (%eax) - movl 20(%ebp), %edx - leal -12(%ebp), %eax - addl %edx, (%eax) - leal -28(%ebp), %eax - incl (%eax) - jmp .L44 - -.exit_n: - emms - popl %esi - popl %edi - addl $72, %esp - popl %ebx - popl %ebp - ret -.Lfe3: - .size nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n,.Lfe3-nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n - .ident "GCC: (GNU) 3.2" diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index fec9316b9..1f85ee5ca 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -26,6 +26,10 @@ /* Freetype2 */ # include <pango/pangoft2.h> +#include <ext/hash_map> + + +typedef __gnu_cxx::hash_map<PangoFontDescription*, font_instance*, font_descr_hash, font_descr_equal> FaceMapType; // need to avoid using the size field size_t font_descr_hash::operator()( PangoFontDescription *const &x) const { @@ -299,20 +303,25 @@ font_factory *font_factory::Default(void) return lUsine; } -font_factory::font_factory(void) -{ - fontSize = 512; - nbEnt = 0; - maxEnt = 32; - ents = (font_entry*)g_malloc(maxEnt*sizeof(font_entry)); +font_factory::font_factory(void) : + nbEnt(0), + maxEnt(32), + ents(static_cast<font_entry*>(g_malloc(maxEnt*sizeof(font_entry)))), #ifdef USE_PANGO_WIN32 - hScreenDC = pango_win32_get_dc(); - fontServer = pango_win32_font_map_for_display(); - fontContext = pango_win32_get_context(); - pangoFontCache = pango_win32_font_map_get_font_cache(fontServer); + fontServer(pango_win32_font_map_for_display()), + fontContext(pango_win32_get_context()), + pangoFontCache(pango_win32_font_map_get_font_cache(fontServer)), + hScreenDC(pango_win32_get_dc()), +#else + fontServer(pango_ft2_font_map_new()), + fontContext(0), +#endif + fontSize(512), + loadedPtr(new FaceMapType()) +{ +#ifdef USE_PANGO_WIN32 #else - fontServer = pango_ft2_font_map_new(); pango_ft2_font_map_set_resolution((PangoFT2FontMap*)fontServer, 72, 72); fontContext = pango_ft2_font_map_create_context((PangoFT2FontMap*)fontServer); pango_ft2_font_map_set_default_substitute((PangoFT2FontMap*)fontServer,FactorySubstituteFunc,this,NULL); @@ -321,6 +330,11 @@ font_factory::font_factory(void) font_factory::~font_factory(void) { + if (loadedPtr) { + FaceMapType* tmp = static_cast<FaceMapType*>(loadedPtr); + loadedPtr = 0; + } + for (int i = 0;i < nbEnt;i++) ents[i].f->Unref(); if ( ents ) g_free(ents); @@ -793,6 +807,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) font_instance *res = NULL; + FaceMapType& loadedFaces = *static_cast<FaceMapType*>(loadedPtr); if ( loadedFaces.find(descr) == loadedFaces.end() ) { // not yet loaded PangoFont *nFace = NULL; @@ -849,8 +864,9 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) res->Ref(); AddInCache(res); } - if(res) - res->InitTheFace(); + if (res) { + res->InitTheFace(); + } return res; } @@ -924,15 +940,18 @@ font_instance *font_factory::Face(char const *family, NRTypePosDef apos) void font_factory::UnrefFace(font_instance *who) { - if ( who == NULL ) return; - if ( loadedFaces.find(who->descr) == loadedFaces.end() ) { - // not found - char *tc = pango_font_description_to_string(who->descr); - g_warning("unrefFace %p=%s: failed\n",who,tc); - g_free(tc); - } else { - loadedFaces.erase(loadedFaces.find(who->descr)); - // printf("unrefFace %p: success\n",who); + if ( who ) { + FaceMapType& loadedFaces = *static_cast<FaceMapType*>(loadedPtr); + + if ( loadedFaces.find(who->descr) == loadedFaces.end() ) { + // not found + char *tc = pango_font_description_to_string(who->descr); + g_warning("unrefFace %p=%s: failed\n",who,tc); + g_free(tc); + } else { + loadedFaces.erase(loadedFaces.find(who->descr)); + // printf("unrefFace %p: success\n",who); + } } } diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 9f4b31a2e..8d85bcf3e 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -11,7 +11,6 @@ #include <functional> #include <algorithm> -#include <ext/hash_map> #ifdef HAVE_CONFIG_H # include <config.h> @@ -84,31 +83,29 @@ public: double fontSize; /**< The huge fontsize used as workaround for hinting. * Different between freetype and win32. */ - __gnu_cxx::hash_map<PangoFontDescription*, font_instance*, font_descr_hash, font_descr_equal> loadedFaces; - font_factory(); virtual ~font_factory(); /// Returns the default font_factory. static font_factory* Default(); - + /// Constructs a pango string for use with the fontStringMap (see below) Glib::ustring ConstructFontSpecification(PangoFontDescription *font); Glib::ustring ConstructFontSpecification(font_instance *font); - + /// Returns strings to be used in the UI for family and face (or "style" as the column is labeled) Glib::ustring GetUIFamilyString(PangoFontDescription const *fontDescr); Glib::ustring GetUIStyleString(PangoFontDescription const *fontDescr); - + /// Modifiers for the font specification (returns new font specification) Glib::ustring ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily); Glib::ustring FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn); Glib::ustring FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn); - + // Gathers all strings needed for UI while storing pango information in // fontInstanceMap and fontStringMap void GetUIFamiliesAndStyles(FamilyToStylesMap *map); - + /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information font_instance* FaceFromStyle(SPStyle const *style); @@ -129,17 +126,19 @@ public: // internal void AddInCache(font_instance *who); - + private: + void* loadedPtr; + // These two maps are used for translating between what's in the UI and a pango // font description. This is necessary because Pango cannot always // reproduce these structures from the names it gave us in the first place. - + // Key: A string produced by font_factory::ConstructFontSpecification // Value: The associated PangoFontDescription typedef std::map<Glib::ustring, PangoFontDescription *> PangoStringToDescrMap; PangoStringToDescrMap fontInstanceMap; - + // Key: Family name in UI + Style name in UI // Value: The associated string that should be produced with font_factory::ConstructFontSpecification typedef std::map<Glib::ustring, Glib::ustring> UIStringToPangoStringMap; diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index e1413b46e..f34a230c1 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -29,6 +29,22 @@ # include FT_TRUETYPE_TABLES_H # include <pango/pangoft2.h> +#include <ext/hash_map> + + +// the various raster_font in use at a given time are held in a hash_map whose indices are the +// styles, hence the 2 following 'classes' +struct font_style_hash : public std::unary_function<font_style, size_t> { + size_t operator()(font_style const &x) const; +}; + +struct font_style_equal : public std::binary_function<font_style, font_style, bool> { + bool operator()(font_style const &a, font_style const &b); +}; + + +typedef __gnu_cxx::hash_map<font_style, raster_font*, font_style_hash, font_style_equal> StyleMap; + size_t font_style_hash::operator()(const font_style &x) const { @@ -155,36 +171,61 @@ static int ft2_cubic_to(FREETYPE_VECTOR *control1, FREETYPE_VECTOR *control2, FR * */ -font_instance::font_instance(void) +font_instance::font_instance(void) : + pFont(0), + descr(0), + refCount(0), + daddy(0), + nbGlyph(0), + maxGlyph(0), + glyphs(0), + loadedPtr(new StyleMap()), + theFace(0) { - //printf("font instance born\n"); - descr=NULL; - pFont=NULL; - refCount=0; - daddy=NULL; - nbGlyph=maxGlyph=0; - glyphs=NULL; - theFace=NULL; + //printf("font instance born\n"); } font_instance::~font_instance(void) { - if ( daddy ) daddy->UnrefFace(this); - //printf("font instance death\n"); - if ( pFont ) g_object_unref(pFont); - pFont=NULL; - if ( descr ) pango_font_description_free(descr); - descr=NULL; - // if ( theFace ) FT_Done_Face(theFace); // owned by pFont. don't touch - theFace=NULL; - - for (int i=0;i<nbGlyph;i++) { - if ( glyphs[i].outline ) delete glyphs[i].outline; - if ( glyphs[i].pathvector ) delete glyphs[i].pathvector; - } - if ( glyphs ) free(glyphs); - nbGlyph=maxGlyph=0; - glyphs=NULL; + if ( loadedPtr ) { + StyleMap* tmp = static_cast<StyleMap*>(loadedPtr); + delete tmp; + loadedPtr = 0; + } + + if ( daddy ) { + daddy->UnrefFace(this); + daddy = 0; + } + + //printf("font instance death\n"); + if ( pFont ) { + g_object_unref(pFont); + pFont = 0; + } + + if ( descr ) { + pango_font_description_free(descr); + descr = 0; + } + + // if ( theFace ) FT_Done_Face(theFace); // owned by pFont. don't touch + theFace = 0; + + for (int i=0;i<nbGlyph;i++) { + if ( glyphs[i].outline ) { + delete glyphs[i].outline; + } + if ( glyphs[i].pathvector ) { + delete glyphs[i].pathvector; + } + } + if ( glyphs ) { + free(glyphs); + glyphs = 0; + } + nbGlyph = 0; + maxGlyph = 0; } void font_instance::Ref(void) @@ -728,7 +769,8 @@ raster_font* font_instance::RasterFont(const font_style &inStyle) nStyle.dashes=(double*)malloc(nStyle.nbDash*sizeof(double)); memcpy(nStyle.dashes,savDashes,nStyle.nbDash*sizeof(double)); } - if ( loadedStyles.find(nStyle) == loadedStyles.end() ) { + StyleMap& loadedStyles = *static_cast<StyleMap*>(loadedPtr); + if ( loadedStyles.find(nStyle) == loadedStyles.end() ) { raster_font *nR = new raster_font(nStyle); nR->Ref(); nR->daddy=this; @@ -746,15 +788,17 @@ raster_font* font_instance::RasterFont(const font_style &inStyle) void font_instance::RemoveRasterFont(raster_font* who) { - if ( who == NULL ) return; - if ( loadedStyles.find(who->style) == loadedStyles.end() ) { - //g_print("RemoveRasterFont failed \n"); - // not found - } else { - loadedStyles.erase(loadedStyles.find(who->style)); - //g_print("RemoveRasterFont\n"); - Unref(); - } + if ( who ) { + StyleMap& loadedStyles = *static_cast<StyleMap*>(loadedPtr); + if ( loadedStyles.find(who->style) == loadedStyles.end() ) { + //g_print("RemoveRasterFont failed \n"); + // not found + } else { + loadedStyles.erase(loadedStyles.find(who->style)); + //g_print("RemoveRasterFont\n"); + Unref(); + } + } } diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 2ee0051a4..33371ab10 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -16,8 +16,11 @@ #include "style.h" #include "svg/svg-length.h" #include "sp-object.h" +#include "sp-string.h" #include "FontFactory.h" +#include "text-editing.h" // for inputTruncated() + namespace Inkscape { namespace Text { @@ -321,5 +324,71 @@ Layout::InputStreamTextSource::~InputStreamTextSource() sp_style_unref(style); } +bool +Layout::inputTruncated() const +{ + if (!inputExists()) + return false; + + // Find out the SPObject to which the last visible character corresponds: + Layout::iterator last = end(); + if (last == begin()) { + // FIXME: this returns a wrong "not truncated" when a flowtext is entirely + // truncated, so there are no visible characters. But how can I find out the + // originator SPObject without having anything to do getSourceOfCharacter + // from? + return false; + } + last.prevCharacter(); + void *source; + Glib::ustring::iterator offset; + getSourceOfCharacter(last, &source, &offset); + SPObject *obj = SP_OBJECT(source); + + // if that is SPString, see if it has further characters beyond the last visible + if (obj && SP_IS_STRING(obj)) { + Glib::ustring::iterator offset_next = offset; + offset_next ++; + if (offset_next != SP_STRING(obj)->string.end()) { + // truncated: source SPString has next char + return true; + } + } + + // otherwise, see if the SPObject at end() or any of its text-tree ancestors + // (excluding top-level SPText or SPFlowText) have a text-tree next sibling with + // visible text + if (obj) { + for (SPObject *ascend = obj; + ascend && (is_part_of_text_subtree (ascend) && !is_top_level_text_object(ascend)); + ascend = SP_OBJECT_PARENT(ascend)) { + if (SP_OBJECT_NEXT(ascend)) { + SPObject *next = SP_OBJECT_NEXT(ascend); + if (next && is_part_of_text_subtree(next) && has_visible_text(next)) { + // truncated: source text object has next text sibling + return true; + } + } + } + } + + // the above works for flowed text, but not for text on path. + // so now, we also check if the last of the _characters, if coming from a TEXT_SOURCE, + // has in_glyph different from -1 + unsigned last_char = _characters.size() - 1; + unsigned span_index = _characters[last_char].in_span; + Glib::ustring::const_iterator iter_char = _spans[span_index].input_stream_first_character; + + if (_input_stream[_spans[span_index].in_input_stream_item]->Type() == TEXT_SOURCE) { + if (_characters[last_char].in_glyph == -1) { + //truncated: last char has no glyph + return true; + } + } + + // not truncated + return false; +} + }//namespace Text }//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 0fc061bfc..f4e8e4031 100644 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -221,6 +221,31 @@ Geom::Point Layout::characterAnchorPoint(iterator const &it) const } } +boost::optional<Geom::Point> Layout::baselineAnchorPoint() const +{ + iterator pos = this->begin(); + Geom::Point left_pt = this->characterAnchorPoint(pos); + pos.thisEndOfLine(); + Geom::Point right_pt = this->characterAnchorPoint(pos); + Geom::Point mid_pt = (left_pt + right_pt)/2; + + switch (this->paragraphAlignment(pos)) { + case LEFT: + case FULL: + return left_pt; + break; + case CENTER: + return mid_pt; + break; + case RIGHT: + return right_pt; + break; + default: + return boost::optional<Geom::Point>(); + break; + } +} + Geom::Point Layout::chunkAnchorPoint(iterator const &it) const { unsigned chunk_index; @@ -705,7 +730,7 @@ bool Layout::iterator::nextLineCursor(int n) unsigned line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line; if (line_index == _parent_layout->_lines.size() - 1) return false; // nowhere to go - else + else n = MIN (n, static_cast<int>(_parent_layout->_lines.size() - 1 - line_index)); if (_parent_layout->_lines[line_index + n].in_shape != _parent_layout->_lines[line_index].in_shape) { // switching between shapes: adjust the stored x to compensate @@ -728,7 +753,7 @@ bool Layout::iterator::prevLineCursor(int n) line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line; if (line_index == 0) return false; // nowhere to go - else + else n = MIN (n, static_cast<int>(line_index)); if (_parent_layout->_lines[line_index - n].in_shape != _parent_layout->_lines[line_index].in_shape) { // switching between shapes: adjust the stored x to compensate diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 19680b140..05b5103fc 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -212,6 +212,8 @@ public: bool inputExists() const {return !_input_stream.empty();} + bool inputTruncated() const; + /** adds a new piece of text to the end of the current list of text to be processed. This method can only add text of a consistent style. To add lots of different styles, call it lots of times. @@ -480,6 +482,10 @@ public: /** For latin text, the left side of the character, on the baseline */ Geom::Point characterAnchorPoint(iterator const &it) const; + /** For left aligned text, the leftmost end of the baseline + For rightmost text, the rightmost... you probably got it by now ;-)*/ + boost::optional<Geom::Point> baselineAnchorPoint() const; + /** This is that value to apply to the x,y attributes of tspan role=line elements, and hence it takes alignment into account. */ Geom::Point chunkAnchorPoint(iterator const &it) const; diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index 4209a20af..521c9a424 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -1,7 +1,6 @@ #ifndef SEEN_LIBNRTYPE_FONT_INSTANCE_H #define SEEN_LIBNRTYPE_FONT_INSTANCE_H -#include <ext/hash_map> #include <map> #include <pango/pango-types.h> #include <pango/pango-font.h> @@ -16,33 +15,21 @@ #include <2geom/d2.h> // the font_instance are the template of several raster_font; they provide metrics and outlines -// that are drawn by the raster_font, so the raster_font needs info relative to the way the +// that are drawn by the raster_font, so the raster_font needs info relative to the way the // font need to be drawn. note that fontsize is a scale factor in the transform matrix // of the style -// the various raster_font in use at a given time are held in a hash_map whose indices are the -// styles, hence the 2 following 'classes' -struct font_style_hash : public std::unary_function<font_style, size_t> { - size_t operator()(font_style const &x) const; -}; - -struct font_style_equal : public std::binary_function<font_style, font_style, bool> { - bool operator()(font_style const &a, font_style const &b); -}; - class font_instance { public: - // hashmap to get the raster_font for a given style - __gnu_cxx::hash_map<font_style, raster_font*, font_style_hash, font_style_equal> loadedStyles; - // the real source of the font + // the real source of the font PangoFont* pFont; - // depending on the rendering backend, different temporary data + // depending on the rendering backend, different temporary data - // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance - // resides in the font_factory loadedFaces hash_map + // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance + // resides in the font_factory loadedFaces hash_map PangoFontDescription* descr; - // refcount + // refcount int refCount; - // font_factory owning this font_instance + // font_factory owning this font_instance font_factory* daddy; // common glyph definitions for all the rasterfonts @@ -58,38 +45,38 @@ public: bool IsOutlineFont(void); // utility void InstallFace(PangoFont* iFace); // utility; should reset the pFont field if loading failed - // in case the PangoFont is a bitmap font, for example. that way, the calling function - // will be able to check the validity of the font before installing it in loadedFaces + // in case the PangoFont is a bitmap font, for example. that way, the calling function + // will be able to check the validity of the font before installing it in loadedFaces void InitTheFace(); int MapUnicodeChar(gunichar c); // calls the relevant unicode->glyph index function void LoadGlyph(int glyph_id); // the main backend-dependent function - // loads the given glyph's info - - // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply - // by the fontsize to get the real sizes + // loads the given glyph's info + + // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply + // by the fontsize to get the real sizes Path* Outline(int glyph_id, Path *copyInto=NULL); - // queries the outline of the glyph (in livarot Path form), and copies it into copyInto instead - // of allocating a new Path if copyInto != NULL + // queries the outline of the glyph (in livarot Path form), and copies it into copyInto instead + // of allocating a new Path if copyInto != NULL Geom::PathVector* PathVector(int glyph_id); // returns the 2geom-type pathvector for this glyph. no refcounting needed, it's deallocated when the font_instance dies double Advance(int glyph_id, bool vertical); - // nominal advance of the font. + // nominal advance of the font. bool FontMetrics(double &ascent, double &descent, double &leading); bool FontSlope(double &run, double &rise); // for generating slanted cursors for oblique fonts Geom::OptRect BBox(int glyph_id); - // creates a rasterfont for the given style + // creates a rasterfont for the given style raster_font* RasterFont(Geom::Matrix const &trs, double stroke_width, bool vertical = false, JoinType stroke_join = join_straight, ButtType stroke_cap = butt_straight, float miter_limit = 4.0); - // the dashes array in iStyle is copied + // the dashes array in iStyle is copied raster_font* RasterFont(font_style const &iStyle); - // private use: tells the font_instance that the raster_font 'who' has died + // private use: tells the font_instance that the raster_font 'who' has died void RemoveRasterFont(raster_font *who); - // attribute queries + // attribute queries unsigned Name(gchar *str, unsigned size); unsigned PSName(gchar *str, unsigned size); unsigned Family(gchar *str, unsigned size); @@ -98,10 +85,13 @@ public: private: void FreeTheFace(); + // hashmap to get the raster_font for a given style + void* loadedPtr; // Pointer to a hash_map. Moved into .cpp to not expose use of __gnu_cxx extension. + #ifdef USE_PANGO_WIN32 HFONT theFace; #else - FT_Face theFace; + FT_Face theFace; // it's a pointer in fact; no worries to ref/unref it, pango does its magic // as long as pFont is valid, theFace is too #endif diff --git a/src/libvpsc/pairingheap/.dirstamp b/src/libvpsc/pairingheap/.dirstamp deleted file mode 100644 index e69de29bb..000000000 --- a/src/libvpsc/pairingheap/.dirstamp +++ /dev/null diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp index 5d5a77280..31fa07515 100644 --- a/src/line-snapper.cpp +++ b/src/line-snapper.cpp @@ -25,7 +25,7 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &/*f*/, + long source_num, Geom::OptRect const &/*bbox_to_snap*/, std::vector<SPItem const *> const */*it*/, std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const @@ -49,13 +49,13 @@ void Inkscape::LineSnapper::freeSnap(SnappedConstraints &sc, Geom::Coord const dist = Geom::L2(p_proj - p); //Store any line that's within snapping range if (dist < getSnapperTolerance()) { - _addSnappedLine(sc, p_proj, dist, source_type, i->first, i->second); + _addSnappedLine(sc, p_proj, dist, source_type, source_num, i->first, i->second); // For any line that's within range, we will also look at it's "point on line" p1. For guides // this point coincides with its origin; for grids this is of no use, but we cannot // discern between grids and guides here Geom::Coord const dist_p1 = Geom::L2(p1 - p); if (dist_p1 < getSnapperTolerance()) { - _addSnappedLinesOrigin(sc, p1, dist_p1, source_type); + _addSnappedLinesOrigin(sc, p1, dist_p1, source_type, source_num); // Only relevant for guides; grids don't have an origin per line // Therefore _addSnappedLinesOrigin() will only be implemented for guides } @@ -69,7 +69,7 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &/*f*/, + long source_num, Geom::OptRect const &/*bbox_to_snap*/, ConstraintLine const &c, std::vector<SPItem const *> const */*it*/) const @@ -112,13 +112,13 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc, // This snappoint is therefore fully constrained, so there's no need // to look for additional intersections; just return the snapped point // and forget about the line - _addSnappedPoint(sc, t, dist, source_type); + _addSnappedPoint(sc, t, dist, source_type, source_num); // For any line that's within range, we will also look at it's "point on line" p1. For guides // this point coincides with its origin; for grids this is of no use, but we cannot // discern between grids and guides here Geom::Coord const dist_p1 = Geom::L2(p1 - p); if (dist_p1 < getSnapperTolerance()) { - _addSnappedLinesOrigin(sc, p1, dist_p1, source_type); + _addSnappedLinesOrigin(sc, p1, dist_p1, source_type, source_num); // Only relevant for guides; grids don't have an origin per line // Therefore _addSnappedLinesOrigin() will only be implemented for guides } @@ -130,7 +130,7 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc, // Will only be overridden in the guide-snapper class, because grid lines don't have an origin; the // grid-snapper classes will use this default empty method -void Inkscape::LineSnapper::_addSnappedLinesOrigin(SnappedConstraints &/*sc*/, Geom::Point const /*origin*/, Geom::Coord const /*snapped_distance*/, SnapSourceType const &/*source_type*/) const +void Inkscape::LineSnapper::_addSnappedLinesOrigin(SnappedConstraints &/*sc*/, Geom::Point const /*origin*/, Geom::Coord const /*snapped_distance*/, SnapSourceType const &/*source_type*/, long /*source_num*/) const { } diff --git a/src/line-snapper.h b/src/line-snapper.h index 4ad08a99f..af36b8330 100644 --- a/src/line-snapper.h +++ b/src/line-snapper.h @@ -28,7 +28,7 @@ public: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &first_point, + long source_num, Geom::OptRect const &bbox_to_snap, std::vector<SPItem const *> const *it, std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const; @@ -37,7 +37,7 @@ public: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &first_point, + long source_num, Geom::OptRect const &bbox_to_snap, ConstraintLine const &c, std::vector<SPItem const *> const *it) const; @@ -54,12 +54,12 @@ private: */ virtual LineList _getSnapLines(Geom::Point const &p) const = 0; - virtual void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, Geom::Point const point_on_line) const = 0; + virtual void _addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, Geom::Point const point_on_line) const = 0; // Will only be implemented for guide lines, because grid lines don't have an origin - virtual void _addSnappedLinesOrigin(SnappedConstraints &sc, Geom::Point const origin, Geom::Coord const snapped_distance, SnapSourceType const &source) const; + virtual void _addSnappedLinesOrigin(SnappedConstraints &sc, Geom::Point const origin, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const; - virtual void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const = 0; + virtual void _addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num) const = 0; }; } diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp index 93ab60fc5..af933eae6 100644 --- a/src/live_effects/lpe-extrude.cpp +++ b/src/live_effects/lpe-extrude.cpp @@ -73,6 +73,7 @@ LPEExtrude::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2 return pwd2_out; } + default: case 1: { Piecewise<D2<SBasis> > pwd2_out; bool closed_path = are_near(pwd2_in.firstValue(), pwd2_in.lastValue()); diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 091a4d9ae..3d18318c5 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -58,7 +58,7 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : Persp3D *persp = persp3d_document_first_persp(inkscape_active_document()); - Proj::TransfMat3x4 pmat = persp->tmat; + Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; pmat.copy_tmat(tmat); } diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp index 3cbac5829..50a3bfb6c 100644 --- a/src/live_effects/lpe-recursiveskeleton.cpp +++ b/src/live_effects/lpe-recursiveskeleton.cpp @@ -1,6 +1,6 @@ #define INKSCAPE_LPE_RECURSIVESKELETON_CPP /** \file - * @brief + * @brief * * Inspired by Hofstadter's 'Goedel Escher Bach', chapter V. */ @@ -52,7 +52,6 @@ LPERecursiveSkeleton::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > co std::vector<Piecewise<D2<SBasis> > > pre_output; double prop_scale = 1.0; - double fuse_tolerance = 0; D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(pwd2_in); Piecewise<SBasis> x0 = false /*vertical_pattern.get_value()*/ ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]); @@ -95,9 +94,10 @@ LPERecursiveSkeleton::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > co double scaling = 1; scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); - + + // TODO investigate why pattWidth is not being used: double pattWidth = pattBndsX->extent() * scaling; - + if (scaling != 1.0) { x*=scaling; } diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp index bcfd0f373..228857ebf 100644 --- a/src/live_effects/lpe-rough-hatches.cpp +++ b/src/live_effects/lpe-rough-hatches.cpp @@ -94,7 +94,7 @@ public: LevelsCrossings(std::vector<std::vector<double> > const ×, Piecewise<D2<SBasis> > const &f, Piecewise<SBasis> const &dx){ - + for (unsigned i=0; i<times.size(); i++){ LevelCrossings lcs; for (unsigned j=0; j<times[i].size(); j++){ @@ -158,7 +158,7 @@ public: } } //set indexes to point to the next point in the "snake walk" - //follow_level's meaning: + //follow_level's meaning: // 0=yes upward // 1=no, last move was upward, // 2=yes downward @@ -181,7 +181,7 @@ public: direction += 1; return; } - double t = (*this)[level][idx].t; + //double t = (*this)[level][idx].t; double sign = ((*this)[level][idx].sign ? 1 : -1); //---double next_t = t; //level += 1; @@ -288,13 +288,13 @@ LPERoughHatches::~LPERoughHatches() } -Geom::Piecewise<Geom::D2<Geom::SBasis> > +Geom::Piecewise<Geom::D2<Geom::SBasis> > LPERoughHatches::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in){ //std::cout<<"doEffect_pwd2:\n"; Piecewise<D2<SBasis> > result; - + Piecewise<D2<SBasis> > transformed_pwd2_in = pwd2_in; Point start = pwd2_in.segs.front().at0(); Point end = pwd2_in.segs.back().at1(); @@ -324,11 +324,11 @@ LPERoughHatches::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & Matrix mat(-hatches_dir[Y], hatches_dir[X], hatches_dir[X], hatches_dir[Y],0,0); transformed_pwd2_in = transformed_pwd2_in * mat; transformed_org *= mat; - + std::vector<std::vector<Point> > snakePoints; snakePoints = linearSnake(transformed_pwd2_in, transformed_org); if ( snakePoints.size() > 0 ){ - Piecewise<D2<SBasis> >smthSnake = smoothSnake(snakePoints); + Piecewise<D2<SBasis> >smthSnake = smoothSnake(snakePoints); smthSnake = smthSnake*mat.inverse(); if (do_bend.get_value()){ smthSnake = smthSnake*bend_mat; @@ -354,7 +354,7 @@ LPERoughHatches::generateLevels(Interval const &domain, double x_org){ while (x < domain.max()){ result.push_back(x); double rdm = 1; - if (dist_rdm.get_value() != 0) + if (dist_rdm.get_value() != 0) rdm = 1.+ double((2*dist_rdm - dist_rdm.get_value()))/100.; x+= step*rdm; step*=scale;//(1.+double(growth)); @@ -366,7 +366,7 @@ LPERoughHatches::generateLevels(Interval const &domain, double x_org){ //------------------------------------------------------- // Walk through the intersections to create linear hatches //------------------------------------------------------- -std::vector<std::vector<Point> > +std::vector<std::vector<Point> > LPERoughHatches::linearSnake(Piecewise<D2<SBasis> > const &f, Point const &org){ //std::cout<<"linearSnake:\n"; @@ -401,14 +401,14 @@ LPERoughHatches::linearSnake(Piecewise<D2<SBasis> > const &f, Point const &org){ unsigned i,j; lscs.findFirstUnused(i,j); - + std::vector<Point> result_component; int n = int((range->min()-org[X])/hatch_dist); - - while ( i < lscs.size() ){ + + while ( i < lscs.size() ){ int dir = 0; //switch orientation of first segment according to starting point. - if (i % 2 == n%2 && j < lscs[i].size()-1 && !lscs[i][j].used){ + if ((i % 2 == n % 2) && ((j + 1) < lscs[i].size()) && !lscs[i][j].used){ j += 1; dir = 2; } @@ -428,7 +428,7 @@ LPERoughHatches::linearSnake(Piecewise<D2<SBasis> > const &f, Point const &org){ //------------------------------------------------------- // Smooth the linear hatches according to params... //------------------------------------------------------- -Piecewise<D2<SBasis> > +Piecewise<D2<SBasis> > LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake){ Piecewise<D2<SBasis> > result; @@ -444,7 +444,7 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake Geom::Path res_comp_top(last_pt); Geom::Path res_comp_bot(last_pt); unsigned i=1; - //bool is_top = true;//Inversion here; due to downward y? + //bool is_top = true;//Inversion here; due to downward y? bool is_top = ( linearSnake[comp][0][Y] < linearSnake[comp][1][Y] ); while( i+1<linearSnake[comp].size() ){ @@ -454,18 +454,18 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake double scale_in = (is_top ? scale_tf : scale_bf ); double scale_out = (is_top ? scale_tb : scale_bb ); if (is_top){ - if (top_edge_variation.get_value() != 0) + if (top_edge_variation.get_value() != 0) new_pt[Y] += double(top_edge_variation)-top_edge_variation.get_value()/2.; - if (top_tgt_variation.get_value() != 0) + if (top_tgt_variation.get_value() != 0) new_pt[X] += double(top_tgt_variation)-top_tgt_variation.get_value()/2.; if (top_smth_variation.get_value() != 0) { scale_in*=(100.-double(top_smth_variation))/100.; scale_out*=(100.-double(top_smth_variation))/100.; } }else{ - if (bot_edge_variation.get_value() != 0) + if (bot_edge_variation.get_value() != 0) new_pt[Y] += double(bot_edge_variation)-bot_edge_variation.get_value()/2.; - if (bot_tgt_variation.get_value() != 0) + if (bot_tgt_variation.get_value() != 0) new_pt[X] += double(bot_tgt_variation)-bot_tgt_variation.get_value()/2.; if (bot_smth_variation.get_value() != 0) { scale_in*=(100.-double(bot_smth_variation))/100.; @@ -474,7 +474,7 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake } Point new_hdle_in = new_pt + (pt0-pt1) * (scale_in /2.); Point new_hdle_out = new_pt - (pt0-pt1) * (scale_out/2.); - + if ( fat_output.get_value() ){ //double scaled_width = double((is_top ? stroke_width_top : stroke_width_bot))/(pt1[X]-pt0[X]); double scaled_width = 1./(pt1[X]-pt0[X]); @@ -494,7 +494,7 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake //TODO: find a good way to handle limit cases (small smthness, large stroke). //if (inside_hdle_in[X] > inside[X]) inside_hdle_in = inside; //if (inside_hdle_out[X] < inside[X]) inside_hdle_out = inside; - + if (is_top){ res_comp_top.appendNew<CubicBezier>(last_top_hdle,new_hdle_in,new_pt); res_comp_bot.appendNew<CubicBezier>(last_bot_hdle,inside_hdle_in,inside); @@ -509,7 +509,7 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake }else{ res_comp.appendNew<CubicBezier>(last_hdle,new_hdle_in,new_pt); } - + last_hdle = new_hdle_out; i+=2; is_top = !is_top; @@ -525,7 +525,7 @@ LPERoughHatches::smoothSnake(std::vector<std::vector<Point> > const &linearSnake if ( fat_output.get_value() ){ res_comp = res_comp_bot; res_comp.append(res_comp_top.reverse(),Geom::Path::STITCH_DISCONTINUOUS); - } + } result.concat(res_comp.toPwSb()); } } diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index 80970fd8a..35c9ea695 100644 --- a/src/live_effects/lpe-ruler.cpp +++ b/src/live_effects/lpe-ruler.cpp @@ -40,8 +40,8 @@ static const Util::EnumDataConverter<BorderMarkType> BorderMarkTypeConverter(Bor LPERuler::LPERuler(LivePathEffectObject *lpeobject) : Effect(lpeobject), - unit(_("Unit"), _("Unit"), "unit", &wr, this), mark_distance(_("Mark distance"), _("Distance between successive ruler marks"), "mark_distance", &wr, this, 20.0), + unit(_("Unit"), _("Unit"), "unit", &wr, this), mark_length(_("Major length"), _("Length of major ruler marks"), "mark_length", &wr, this, 14.0), minor_mark_length(_("Minor length"), _("Length of minor ruler marks"), "minor_mark_length", &wr, this, 7.0), major_mark_steps(_("Major steps"), _("Draw a major mark every ... steps"), "major_mark_steps", &wr, this, 5), diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index a8ea15744..57d583ba6 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -32,9 +32,9 @@ Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip, param_wr(wr), param_label(label), oncanvas_editable(false), + widget_is_visible(true), param_tooltip(tip), - param_effect(effect), - widget_is_visible(true) + param_effect(effect) { } diff --git a/src/main.cpp b/src/main.cpp index f96d99e11..75e882e99 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -566,8 +566,12 @@ main(int argc, char **argv) // TODO these should use xxxW() calls explicitly and convert UTF-16 <--> UTF-8 SetCurrentDirectory(homedir.c_str()); _win32_set_inkscape_env(homedir); - RegistryTool rt; - rt.setPathInfo(); + // Don't touch the registry (works fine without it) for Inkscape Portable + gchar const *val = g_getenv("INKSCAPE_PORTABLE_PROFILE_DIR"); + if (!val) { + RegistryTool rt; + rt.setPathInfo(); + } #endif // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) diff --git a/src/marker-test.h b/src/marker-test.h new file mode 100644 index 000000000..5b84dcc66 --- /dev/null +++ b/src/marker-test.h @@ -0,0 +1,39 @@ +/** @file + * @brief Unit tests for SVG marker handling + */ +/* Authors: + * Johan Engelen <goejendaagh@zonnet.nl> + * + * This file is released into the public domain. + */ + +#include <cxxtest/TestSuite.h> + +#include "sp-marker-loc.h" + +class MarkerTest : public CxxTest::TestSuite +{ +public: + + void testMarkerLoc() + { + // code depends on these *exact* values, so check them here. + TS_ASSERT_EQUALS(SP_MARKER_LOC, 0); + TS_ASSERT_EQUALS(SP_MARKER_LOC_START, 1); + TS_ASSERT_EQUALS(SP_MARKER_LOC_MID, 2); + TS_ASSERT_EQUALS(SP_MARKER_LOC_END, 3); + TS_ASSERT_EQUALS(SP_MARKER_LOC_QTY, 4); + } + +}; + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index d7a18f211..aeb6500bf 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -40,8 +40,7 @@ static char const menus_skeleton[] = " <verb verb-id=\"DialogMetadata\" />\n" " <verb verb-id=\"DialogPreferences\" />\n" " <verb verb-id=\"DialogInput\" />\n" -// TODO look at some dynamic option for changing the menu tree: -//" <verb verb-id=\"DialogInput2\" />\n" +" <verb verb-id=\"DialogInput2\" />\n" " <separator/>\n" " <verb verb-id=\"FileClose\" />\n" " <verb verb-id=\"FileQuit\" />\n" @@ -110,6 +109,8 @@ static char const menus_skeleton[] = " <verb verb-id=\"ViewModeNormal\" radio=\"yes\" default=\"yes\"/>\n" " <verb verb-id=\"ViewModeNoFilters\" radio=\"yes\"/>\n" " <verb verb-id=\"ViewModeOutline\" radio=\"yes\"/>\n" +" <verb verb-id=\"ViewModePrintColorsPreview\" radio=\"yes\"/>\n" +" <verb verb-id=\"DialogPrintColorsPreview\" />\n" " </submenu>\n" " <separator/>\n" " <verb verb-id=\"ToggleGrid\" />\n" diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 22d438c1e..88c260782 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -67,9 +67,9 @@ Inkscape::ObjectSnapper::~ObjectSnapper() */ Geom::Coord Inkscape::ObjectSnapper::getSnapperTolerance() const { - SPDesktop const *dt = _snapmanager->getDesktop(); - double const zoom = dt ? dt->current_zoom() : 1; - return _snapmanager->snapprefs.getObjectTolerance() / zoom; + SPDesktop const *dt = _snapmanager->getDesktop(); + double const zoom = dt ? dt->current_zoom() : 1; + return _snapmanager->snapprefs.getObjectTolerance() / zoom; } bool Inkscape::ObjectSnapper::getSnapperAlwaysSnap() const @@ -81,7 +81,6 @@ bool Inkscape::ObjectSnapper::getSnapperAlwaysSnap() const * Find all items within snapping range. * \param parent Pointer to the document's root, or to a clipped path or mask object * \param it List of items to ignore - * \param first_point If true then this point is the first one from a whole bunch of points * \param bbox_to_snap Bounding box hulling the whole bunch of points, all from the same selection and having the same transformation * \param DimensionToSnap Snap in X, Y, or both directions. */ @@ -173,7 +172,7 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType const &t, - bool const &first_point) const + bool const &first_point) const { // Now, let's first collect all points to snap to. If we have a whole bunch of points to snap, // e.g. when translating an item using the selector tool, then we will only do this for the @@ -212,47 +211,47 @@ void Inkscape::ObjectSnapper::_collectNodes(Inkscape::SnapPreferences::PointType g_return_if_fail(root_item); //Collect all nodes so we can snap to them - if (p_is_a_node || !(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_node) || p_is_a_guide) { - // Note: there are two ways in which intersections are considered: - // Method 1: Intersections are calculated for each shape individually, for both the - // snap source and snap target (see sp_shape_snappoints) - // Method 2: Intersections are calculated for each curve or line that we've snapped to, i.e. only for - // the target (see the intersect() method in the SnappedCurve and SnappedLine classes) - // Some differences: - // - Method 1 doesn't find intersections within a set of multiple objects - // - Method 2 only works for targets - // When considering intersections as snap targets: - // - Method 1 only works when snapping to nodes, whereas - // - Method 2 only works when snapping to paths - // - There will be performance differences too! - // If both methods are being used simultaneously, then this might lead to duplicate targets! - - // Well, here we will be looking for snap TARGETS. Both methods can therefore be used. - // When snapping to paths, we will get a collection of snapped lines and snapped curves. findBestSnap() will - // go hunting for intersections (but only when asked to in the prefs of course). In that case we can just - // temporarily block the intersections in sp_item_snappoints, we don't need duplicates. If we're not snapping to - // paths though but only to item nodes then we should still look for the intersections in sp_item_snappoints() - bool old_pref = _snapmanager->snapprefs.getSnapIntersectionCS(); - if (_snapmanager->snapprefs.getSnapToItemPath()) { - _snapmanager->snapprefs.setSnapIntersectionCS(false); - } - - sp_item_snappoints(root_item, true, *_points_to_snap_to, &_snapmanager->snapprefs); - - if (_snapmanager->snapprefs.getSnapToItemPath()) { - _snapmanager->snapprefs.setSnapIntersectionCS(old_pref); - } - } + if (p_is_a_node || !(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_node) || p_is_a_guide) { + // Note: there are two ways in which intersections are considered: + // Method 1: Intersections are calculated for each shape individually, for both the + // snap source and snap target (see sp_shape_snappoints) + // Method 2: Intersections are calculated for each curve or line that we've snapped to, i.e. only for + // the target (see the intersect() method in the SnappedCurve and SnappedLine classes) + // Some differences: + // - Method 1 doesn't find intersections within a set of multiple objects + // - Method 2 only works for targets + // When considering intersections as snap targets: + // - Method 1 only works when snapping to nodes, whereas + // - Method 2 only works when snapping to paths + // - There will be performance differences too! + // If both methods are being used simultaneously, then this might lead to duplicate targets! + + // Well, here we will be looking for snap TARGETS. Both methods can therefore be used. + // When snapping to paths, we will get a collection of snapped lines and snapped curves. findBestSnap() will + // go hunting for intersections (but only when asked to in the prefs of course). In that case we can just + // temporarily block the intersections in sp_item_snappoints, we don't need duplicates. If we're not snapping to + // paths though but only to item nodes then we should still look for the intersections in sp_item_snappoints() + bool old_pref = _snapmanager->snapprefs.getSnapIntersectionCS(); + if (_snapmanager->snapprefs.getSnapToItemPath()) { + _snapmanager->snapprefs.setSnapIntersectionCS(false); + } + + sp_item_snappoints(root_item, true, *_points_to_snap_to, &_snapmanager->snapprefs); + + if (_snapmanager->snapprefs.getSnapToItemPath()) { + _snapmanager->snapprefs.setSnapIntersectionCS(old_pref); + } + } //Collect the bounding box's corners so we can snap to them - if (p_is_a_bbox || !(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_bbox) || p_is_a_guide) { - // 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) { - Geom::OptRect b = sp_item_bbox_desktop(root_item, bbox_type); - getBBoxPoints(b, _points_to_snap_to, true, _snapmanager->snapprefs.getSnapToBBoxNode(), _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints(), _snapmanager->snapprefs.getSnapBBoxMidpoints()); - } - } + if (p_is_a_bbox || !(_snapmanager->snapprefs.getStrictSnapping() && !p_is_a_bbox) || p_is_a_guide) { + // 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) { + Geom::OptRect b = sp_item_bbox_desktop(root_item, bbox_type); + getBBoxPoints(b, _points_to_snap_to, true, _snapmanager->snapprefs.getSnapToBBoxNode(), _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints(), _snapmanager->snapprefs.getSnapBBoxMidpoints()); + } + } } } } @@ -261,12 +260,12 @@ void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &first_point, + long source_num, std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const { // Iterate through all nodes, find out which one is the closest to p, and snap to it! - _collectNodes(t, first_point); + _collectNodes(t, source_num == 0); if (unselected_nodes != NULL) { _points_to_snap_to->insert(_points_to_snap_to->end(), unselected_nodes->begin(), unselected_nodes->end()); @@ -278,7 +277,7 @@ void Inkscape::ObjectSnapper::_snapNodes(SnappedConstraints &sc, for (std::vector<std::pair<Geom::Point, int> >::const_iterator k = _points_to_snap_to->begin(); k != _points_to_snap_to->end(); k++) { Geom::Coord dist = Geom::L2((*k).first - p); if (dist < getSnapperTolerance() && dist < s.getSnapDistance()) { - s = SnappedPoint((*k).first, source_type, static_cast<Inkscape::SnapTargetType>((*k).second), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true); + s = SnappedPoint((*k).first, source_type, source_num, static_cast<Inkscape::SnapTargetType>((*k).second), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true); success = true; } } @@ -298,10 +297,10 @@ void Inkscape::ObjectSnapper::_snapTranslatingGuideToNodes(SnappedConstraints &s // Although we won't snap to paths here (which would give us under constrained snaps) we can still snap to intersections of paths. if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) { - _collectPaths(t, true); - _snapPaths(sc, t, p, SNAPSOURCE_GUIDE, true, NULL, NULL); - // The paths themselves should be discarded in findBestSnap(), as we should only snap to their intersections - } + _collectPaths(t, true); + _snapPaths(sc, t, p, SNAPSOURCE_GUIDE, 0, NULL, NULL); + // The paths themselves should be discarded in findBestSnap(), as we should only snap to their intersections + } SnappedPoint s; @@ -313,7 +312,7 @@ void Inkscape::ObjectSnapper::_snapTranslatingGuideToNodes(SnappedConstraints &s Geom::Coord dist = Geom::L2((*k).first - p_proj); // distance from node to the guide Geom::Coord dist2 = Geom::L2(p - p_proj); // distance from projection of node on the guide, to the mouse location if ((dist < tol && dist2 < tol) || getSnapperAlwaysSnap()) { - s = SnappedPoint((*k).first, SNAPSOURCE_GUIDE, static_cast<Inkscape::SnapTargetType>((*k).second), dist, tol, getSnapperAlwaysSnap(), true); + s = SnappedPoint((*k).first, SNAPSOURCE_GUIDE, 0, static_cast<Inkscape::SnapTargetType>((*k).second), dist, tol, getSnapperAlwaysSnap(), true); sc.points.push_back(s); } } @@ -428,11 +427,11 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &first_point, + long source_num, std::vector<std::pair<Geom::Point, int> > *unselected_nodes, SPPath const *selected_path) const { - _collectPaths(t, first_point); + _collectPaths(t, source_num == 0); // Now we can finally do the real snapping, using the paths collected above g_assert(_snapmanager->getDesktop() != NULL); @@ -440,7 +439,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, bool const node_tool_active = _snapmanager->snapprefs.getSnapToItemPath() && selected_path != NULL; - if (first_point) { + if (source_num == 0) { /* findCandidates() is used for snapping to both paths and nodes. It ignores the path that is * currently being edited, because that path requires special care: when snapping to nodes * only the unselected nodes of that path should be considered, and these will be passed on separately. @@ -503,7 +502,7 @@ void Inkscape::ObjectSnapper::_snapPaths(SnappedConstraints &sc, if (!being_edited || (c1 && c2)) { Geom::Coord const dist = Geom::distance(sp_doc, p_doc); if (dist < getSnapperTolerance()) { - sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, source_type, it_p->second)); + sc.curves.push_back(Inkscape::SnappedCurve(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), false, curve, source_type, source_num, it_p->second)); } } } @@ -535,11 +534,11 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const source_type, - bool const &first_point, + long source_num, ConstraintLine const &c) const { - _collectPaths(t, first_point); + _collectPaths(t, source_num == 0); // Now we can finally do the real snapping, using the paths collected above @@ -577,7 +576,7 @@ void Inkscape::ObjectSnapper::_snapPathsConstrained(SnappedConstraints &sc, // When it's within snapping range, then return it // (within snapping range == between p_min_on_cl and p_max_on_cl == 0 < ta < 1) Geom::Coord dist = Geom::L2(_snapmanager->getDesktop()->dt2doc(p_proj_on_cl) - p_inters); - SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), source_type, k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true); + SnappedPoint s(_snapmanager->getDesktop()->doc2dt(p_inters), source_type, source_num, k->second, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), true); sc.points.push_back(s); } } @@ -591,7 +590,7 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &first_point, + long source_num, Geom::OptRect const &bbox_to_snap, std::vector<SPItem const *> const *it, std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const @@ -601,17 +600,17 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc, } /* Get a list of all the SPItems that we will try to snap to */ - if (first_point) { + if (source_num == 0) { Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(p, p); - _findCandidates(sp_document_root(_snapmanager->getDocument()), it, first_point, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity()); + _findCandidates(sp_document_root(_snapmanager->getDocument()), it, source_num == 0, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity()); } if (_snapmanager->snapprefs.getSnapToItemNode() || _snapmanager->snapprefs.getSnapSmoothNodes() - || _snapmanager->snapprefs.getSnapToBBoxNode() || _snapmanager->snapprefs.getSnapToPageBorder() - || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints() - || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints() - || _snapmanager->snapprefs.getIncludeItemCenter()) { - _snapNodes(sc, t, p, source_type, first_point, unselected_nodes); + || _snapmanager->snapprefs.getSnapToBBoxNode() || _snapmanager->snapprefs.getSnapToPageBorder() + || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints() + || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints() + || _snapmanager->snapprefs.getIncludeItemCenter()) { + _snapNodes(sc, t, p, source_type, source_num, unselected_nodes); } if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) { @@ -625,13 +624,13 @@ void Inkscape::ObjectSnapper::freeSnap(SnappedConstraints &sc, SPPath *path = NULL; if (it != NULL) { if (it->size() == 1 && SP_IS_PATH(*it->begin())) { - path = SP_PATH(*it->begin()); + path = SP_PATH(*it->begin()); } // else: *it->begin() might be a SPGroup, e.g. when editing a LPE of text that has been converted to a group of paths // as reported in bug #356743. In that case we can just ignore it, i.e. not snap to this item } - _snapPaths(sc, t, p, source_type, first_point, unselected_nodes, path); + _snapPaths(sc, t, p, source_type, source_num, unselected_nodes, path); } else { - _snapPaths(sc, t, p, source_type, first_point, NULL, NULL); + _snapPaths(sc, t, p, source_type, source_num, NULL, NULL); } } } @@ -640,7 +639,7 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, SnapSourceType const &source_type, - bool const &first_point, + long source_num, Geom::OptRect const &bbox_to_snap, ConstraintLine const &c, std::vector<SPItem const *> const *it) const @@ -650,9 +649,9 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc, } /* Get a list of all the SPItems that we will try to snap to */ - if (first_point) { + if (source_num == 0) { Geom::Rect const local_bbox_to_snap = bbox_to_snap ? *bbox_to_snap : Geom::Rect(p, p); - _findCandidates(sp_document_root(_snapmanager->getDocument()), it, first_point, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity()); + _findCandidates(sp_document_root(_snapmanager->getDocument()), it, source_num == 0, local_bbox_to_snap, TRANSL_SNAP_XY, false, Geom::identity()); } // A constrained snap, is a snap in only one degree of freedom (specified by the constraint line). @@ -665,7 +664,7 @@ void Inkscape::ObjectSnapper::constrainedSnap( SnappedConstraints &sc, // so we will more or less snap to them anyhow. if (_snapmanager->snapprefs.getSnapToItemPath() || _snapmanager->snapprefs.getSnapToBBoxPath() || _snapmanager->snapprefs.getSnapToPageBorder()) { - _snapPathsConstrained(sc, t, p, source_type, first_point, c); + _snapPathsConstrained(sc, t, p, source_type, 0, c); } } @@ -723,13 +722,13 @@ void Inkscape::ObjectSnapper::guideConstrainedSnap(SnappedConstraints &sc, bool Inkscape::ObjectSnapper::ThisSnapperMightSnap() const { bool snap_to_something = _snapmanager->snapprefs.getSnapToItemPath() - || _snapmanager->snapprefs.getSnapToItemNode() - || _snapmanager->snapprefs.getSnapToBBoxPath() - || _snapmanager->snapprefs.getSnapToBBoxNode() - || _snapmanager->snapprefs.getSnapToPageBorder() - || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints() - || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints() - || _snapmanager->snapprefs.getIncludeItemCenter(); + || _snapmanager->snapprefs.getSnapToItemNode() + || _snapmanager->snapprefs.getSnapToBBoxPath() + || _snapmanager->snapprefs.getSnapToBBoxNode() + || _snapmanager->snapprefs.getSnapToPageBorder() + || _snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints() + || _snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints() + || _snapmanager->snapprefs.getIncludeItemCenter(); return (_snap_enabled && _snapmanager->snapprefs.getSnapModeBBoxOrNodes() && snap_to_something); } @@ -737,12 +736,12 @@ bool Inkscape::ObjectSnapper::ThisSnapperMightSnap() const bool Inkscape::ObjectSnapper::GuidesMightSnap() const // almost the same as ThisSnapperMightSnap above, but only looking at points (and not paths) { bool snap_to_something = _snapmanager->snapprefs.getSnapToItemNode() - || _snapmanager->snapprefs.getSnapToPageBorder() - || (_snapmanager->snapprefs.getSnapModeBBox() && _snapmanager->snapprefs.getSnapToBBoxNode()) - || (_snapmanager->snapprefs.getSnapModeBBox() && (_snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints())) - || (_snapmanager->snapprefs.getSnapModeNode() && (_snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints())) - || (_snapmanager->snapprefs.getSnapModeNode() && _snapmanager->snapprefs.getIncludeItemCenter()) - || (_snapmanager->snapprefs.getSnapModeNode() && (_snapmanager->snapprefs.getSnapToItemPath() && _snapmanager->snapprefs.getSnapIntersectionCS())); + || _snapmanager->snapprefs.getSnapToPageBorder() + || (_snapmanager->snapprefs.getSnapModeBBox() && _snapmanager->snapprefs.getSnapToBBoxNode()) + || (_snapmanager->snapprefs.getSnapModeBBox() && (_snapmanager->snapprefs.getSnapBBoxEdgeMidpoints() || _snapmanager->snapprefs.getSnapBBoxMidpoints())) + || (_snapmanager->snapprefs.getSnapModeNode() && (_snapmanager->snapprefs.getSnapLineMidpoints() || _snapmanager->snapprefs.getSnapObjectMidpoints())) + || (_snapmanager->snapprefs.getSnapModeNode() && _snapmanager->snapprefs.getIncludeItemCenter()) + || (_snapmanager->snapprefs.getSnapModeNode() && (_snapmanager->snapprefs.getSnapToItemPath() && _snapmanager->snapprefs.getSnapIntersectionCS())); return (_snap_enabled && _snapmanager->snapprefs.getSnapModeGuide() && snap_to_something); } @@ -784,21 +783,21 @@ void Inkscape::ObjectSnapper::_getBorderNodes(std::vector<std::pair<Geom::Point, void Inkscape::getBBoxPoints(Geom::OptRect const bbox, std::vector<std::pair<Geom::Point, int> > *points, bool const isTarget, bool const includeCorners, bool const includeLineMidpoints, bool const includeObjectMidpoints) { - if (bbox) { - // collect the corners of the bounding box - for ( unsigned k = 0 ; k < 4 ; k++ ) { - if (includeCorners) { - points->push_back(std::make_pair((bbox->corner(k)), isTarget ? int(Inkscape::SNAPTARGET_BBOX_CORNER) : int(Inkscape::SNAPSOURCE_BBOX_CORNER))); - } - // optionally, collect the midpoints of the bounding box's edges too - if (includeLineMidpoints) { - points->push_back(std::make_pair((bbox->corner(k) + bbox->corner((k+1) % 4))/2, isTarget ? int(Inkscape::SNAPTARGET_BBOX_EDGE_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_EDGE_MIDPOINT))); - } - } - if (includeObjectMidpoints) { - points->push_back(std::make_pair(bbox->midpoint(), isTarget ? int(Inkscape::SNAPTARGET_BBOX_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_MIDPOINT))); - } - } + if (bbox) { + // collect the corners of the bounding box + for ( unsigned k = 0 ; k < 4 ; k++ ) { + if (includeCorners) { + points->push_back(std::make_pair((bbox->corner(k)), isTarget ? int(Inkscape::SNAPTARGET_BBOX_CORNER) : int(Inkscape::SNAPSOURCE_BBOX_CORNER))); + } + // optionally, collect the midpoints of the bounding box's edges too + if (includeLineMidpoints) { + points->push_back(std::make_pair((bbox->corner(k) + bbox->corner((k+1) % 4))/2, isTarget ? int(Inkscape::SNAPTARGET_BBOX_EDGE_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_EDGE_MIDPOINT))); + } + } + if (includeObjectMidpoints) { + points->push_back(std::make_pair(bbox->midpoint(), isTarget ? int(Inkscape::SNAPTARGET_BBOX_MIDPOINT) : int(Inkscape::SNAPSOURCE_BBOX_MIDPOINT))); + } + } } /* diff --git a/src/object-snapper.h b/src/object-snapper.h index baa60a096..2fcafb79a 100644 --- a/src/object-snapper.h +++ b/src/object-snapper.h @@ -46,47 +46,47 @@ class ObjectSnapper : public Snapper { public: - ObjectSnapper(SnapManager *sm, Geom::Coord const d); + ObjectSnapper(SnapManager *sm, Geom::Coord const d); ~ObjectSnapper(); - enum DimensionToSnap { - GUIDE_TRANSL_SNAP_X, // For snapping a vertical guide (normal in the X-direction) to objects, - GUIDE_TRANSL_SNAP_Y, // For snapping a horizontal guide (normal in the Y-direction) to objects - ANGLED_GUIDE_TRANSL_SNAP, // For snapping an angled guide, while translating it accross the desktop - TRANSL_SNAP_XY}; // All other cases; for snapping to objects, other than guides - - void guideFreeSnap(SnappedConstraints &sc, - Geom::Point const &p, - Geom::Point const &guide_normal) const; - - void guideConstrainedSnap(SnappedConstraints &sc, - Geom::Point const &p, - Geom::Point const &guide_normal, - ConstraintLine const &c) const; - - bool ThisSnapperMightSnap() const; - bool GuidesMightSnap() const; - - Geom::Coord getSnapperTolerance() const; //returns the tolerance of the snapper in screen pixels (i.e. independent of zoom) - bool getSnapperAlwaysSnap() const; //if true, then the snapper will always snap, regardless of its tolerance - - void freeSnap(SnappedConstraints &sc, - Inkscape::SnapPreferences::PointType const &t, - Geom::Point const &p, - SnapSourceType const &source_type, - bool const &first_point, - Geom::OptRect const &bbox_to_snap, - std::vector<SPItem const *> const *it, - std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const; - - void constrainedSnap(SnappedConstraints &sc, - Inkscape::SnapPreferences::PointType const &t, - Geom::Point const &p, - SnapSourceType const &source_type, - bool const &first_point, - Geom::OptRect const &bbox_to_snap, - ConstraintLine const &c, - std::vector<SPItem const *> const *it) const; + enum DimensionToSnap { + GUIDE_TRANSL_SNAP_X, // For snapping a vertical guide (normal in the X-direction) to objects, + GUIDE_TRANSL_SNAP_Y, // For snapping a horizontal guide (normal in the Y-direction) to objects + ANGLED_GUIDE_TRANSL_SNAP, // For snapping an angled guide, while translating it accross the desktop + TRANSL_SNAP_XY}; // All other cases; for snapping to objects, other than guides + + void guideFreeSnap(SnappedConstraints &sc, + Geom::Point const &p, + Geom::Point const &guide_normal) const; + + void guideConstrainedSnap(SnappedConstraints &sc, + Geom::Point const &p, + Geom::Point const &guide_normal, + ConstraintLine const &c) const; + + bool ThisSnapperMightSnap() const; + bool GuidesMightSnap() const; + + Geom::Coord getSnapperTolerance() const; //returns the tolerance of the snapper in screen pixels (i.e. independent of zoom) + bool getSnapperAlwaysSnap() const; //if true, then the snapper will always snap, regardless of its tolerance + + void freeSnap(SnappedConstraints &sc, + Inkscape::SnapPreferences::PointType const &t, + Geom::Point const &p, + SnapSourceType const &source_type, + long source_num, + Geom::OptRect const &bbox_to_snap, + std::vector<SPItem const *> const *it, + std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const; + + void constrainedSnap(SnappedConstraints &sc, + Inkscape::SnapPreferences::PointType const &t, + Geom::Point const &p, + SnapSourceType const &source_type, + long source_num, + Geom::OptRect const &bbox_to_snap, + ConstraintLine const &c, + std::vector<SPItem const *> const *it) const; private: //store some lists of candidates, points and paths, so we don't have to rebuild them for each point we want to snap @@ -106,7 +106,7 @@ private: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, // in desktop coordinates SnapSourceType const &source_type, - bool const &first_point, + long source_num, std::vector<std::pair<Geom::Point, int> > *unselected_nodes) const; // in desktop coordinates void _snapTranslatingGuideToNodes(SnappedConstraints &sc, @@ -119,9 +119,9 @@ private: void _snapPaths(SnappedConstraints &sc, Inkscape::SnapPreferences::PointType const &t, - Geom::Point const &p, // in desktop coordinates + Geom::Point const &p, // in desktop coordinates SnapSourceType const &source_type, - bool const &first_point, + long source_num, std::vector<std::pair<Geom::Point, int> > *unselected_nodes, // in desktop coordinates SPPath const *selected_path) const; @@ -129,7 +129,7 @@ private: Inkscape::SnapPreferences::PointType const &t, Geom::Point const &p, // in desktop coordinates SnapSourceType const source_type, - bool const &first_point, + long source_num, ConstraintLine const &c) const; bool isUnselectedNode(Geom::Point const &point, std::vector<std::pair<Geom::Point, int> > const *unselected_nodes) const; diff --git a/src/persp3d-reference.h b/src/persp3d-reference.h index 43b0e82b1..7c2ce31bf 100644 --- a/src/persp3d-reference.h +++ b/src/persp3d-reference.h @@ -12,9 +12,9 @@ #include "uri-references.h" #include <sigc++/sigc++.h> +#include "persp3d.h" class SPObject; -class Persp3D; namespace Inkscape { namespace XML { @@ -28,7 +28,7 @@ public: ~Persp3DReference(); Persp3D *getObject() const { - return (Persp3D *)URIReference::getObject(); + return SP_PERSP3D(URIReference::getObject()); } SPObject *owner; diff --git a/src/persp3d.cpp b/src/persp3d.cpp index 916e9f25f..6a697ec9b 100644 --- a/src/persp3d.cpp +++ b/src/persp3d.cpp @@ -24,7 +24,7 @@ #include <glibmm/i18n.h> static void persp3d_class_init(Persp3DClass *klass); -static void persp3d_init(Persp3D *stop); +static void persp3d_init(Persp3D *persp); static void persp3d_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); static void persp3d_release(SPObject *object); @@ -34,10 +34,22 @@ static Inkscape::XML::Node *persp3d_write(SPObject *object, Inkscape::XML::Docum static void persp3d_on_repr_attr_changed (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive, void * data); +static void persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image); +static gchar * persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis); + static SPObjectClass *persp3d_parent_class; static int global_counter = 0; +/* Constructor/destructor for the internal class */ + +Persp3DImpl::Persp3DImpl() { + tmat = Proj::TransfMat3x4 (); + document = NULL; + + my_counter = global_counter++; +} + /** * Registers Persp3d class and returns its type. */ @@ -91,13 +103,7 @@ static void persp3d_class_init(Persp3DClass *klass) static void persp3d_init(Persp3D *persp) { - persp->tmat = Proj::TransfMat3x4 (); - - persp->boxes_transformed = new std::map<SPBox3D *, bool>; - persp->boxes_transformed->clear(); - persp->document = NULL; - - persp->my_counter = global_counter++; + persp->perspective_impl = new Persp3DImpl(); } /** @@ -124,8 +130,8 @@ static void persp3d_build(SPObject *object, SPDocument *document, Inkscape::XML: * Virtual release of Persp3D members before destruction. */ static void persp3d_release(SPObject *object) { - Persp3D *persp = SP_PERSP3D (object); - delete persp->boxes_transformed; + Persp3D *persp = SP_PERSP3D(object); + delete persp->perspective_impl; SP_OBJECT_REPR(object)->removeListenerByData(object); } @@ -138,34 +144,34 @@ static void persp3d_release(SPObject *object) { static void persp3d_set(SPObject *object, unsigned key, gchar const *value) { - Persp3D *persp = SP_PERSP3D (object); + Persp3DImpl *persp_impl = SP_PERSP3D(object)->perspective_impl; switch (key) { case SP_ATTR_INKSCAPE_PERSP3D_VP_X: { if (value) { Proj::Pt2 new_image (value); - persp3d_update_with_point (persp, Proj::X, new_image); + persp3d_update_with_point (persp_impl, Proj::X, new_image); } break; } case SP_ATTR_INKSCAPE_PERSP3D_VP_Y: { if (value) { Proj::Pt2 new_image (value); - persp3d_update_with_point (persp, Proj::Y, new_image); + persp3d_update_with_point (persp_impl, Proj::Y, new_image); break; } } case SP_ATTR_INKSCAPE_PERSP3D_VP_Z: { if (value) { Proj::Pt2 new_image (value); - persp3d_update_with_point (persp, Proj::Z, new_image); + persp3d_update_with_point (persp_impl, Proj::Z, new_image); break; } } case SP_ATTR_INKSCAPE_PERSP3D_ORIGIN: { if (value) { Proj::Pt2 new_image (value); - persp3d_update_with_point (persp, Proj::W, new_image); + persp3d_update_with_point (persp_impl, Proj::W, new_image); break; } } @@ -201,36 +207,40 @@ persp3d_update(SPObject *object, SPCtx *ctx, guint flags) } Persp3D * -persp3d_create_xml_element (SPDocument *document, Persp3D *dup) {// if dup is given, copy the attributes over +persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup) {// if dup is given, copy the attributes over SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document); Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document); Inkscape::XML::Node *repr; - if (dup) { - repr = SP_OBJECT_REPR(dup)->duplicate (xml_doc); - } else { - /* if no perspective is given, create a default one */ - repr = xml_doc->createElement("inkscape:perspective"); - repr->setAttribute("sodipodi:type", "inkscape:persp3d"); - Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, sp_document_height(document)/2, 1.0); - Proj::Pt2 proj_vp_y = Proj::Pt2 ( 0.0,1000.0, 0.0); - Proj::Pt2 proj_vp_z = Proj::Pt2 (sp_document_width(document), sp_document_height(document)/2, 1.0); - Proj::Pt2 proj_origin = Proj::Pt2 (sp_document_width(document)/2, sp_document_height(document)/3, 1.0); + /* if no perspective is given, create a default one */ + repr = xml_doc->createElement("inkscape:perspective"); + repr->setAttribute("sodipodi:type", "inkscape:persp3d"); - gchar *str = NULL; - str = proj_vp_x.coord_string(); - repr->setAttribute("inkscape:vp_x", str); - g_free (str); - str = proj_vp_y.coord_string(); - repr->setAttribute("inkscape:vp_y", str); - g_free (str); - str = proj_vp_z.coord_string(); - repr->setAttribute("inkscape:vp_z", str); - g_free (str); - str = proj_origin.coord_string(); - repr->setAttribute("inkscape:persp3d-origin", str); - g_free (str); - } + Proj::Pt2 proj_vp_x = Proj::Pt2 (0.0, sp_document_height(document)/2, 1.0); + Proj::Pt2 proj_vp_y = Proj::Pt2 (0.0, 1000.0, 0.0); + Proj::Pt2 proj_vp_z = Proj::Pt2 (sp_document_width(document), sp_document_height(document)/2, 1.0); + Proj::Pt2 proj_origin = Proj::Pt2 (sp_document_width(document)/2, sp_document_height(document)/3, 1.0); + + if (dup) { + proj_vp_x = dup->tmat.column (Proj::X); + proj_vp_y = dup->tmat.column (Proj::Y); + proj_vp_z = dup->tmat.column (Proj::Z); + proj_origin = dup->tmat.column (Proj::W); + } + + gchar *str = NULL; + str = proj_vp_x.coord_string(); + repr->setAttribute("inkscape:vp_x", str); + g_free (str); + str = proj_vp_y.coord_string(); + repr->setAttribute("inkscape:vp_y", str); + g_free (str); + str = proj_vp_z.coord_string(); + repr->setAttribute("inkscape:vp_z", str); + g_free (str); + str = proj_origin.coord_string(); + repr->setAttribute("inkscape:persp3d-origin", str); + g_free (str); /* Append the new persp3d to defs */ SP_OBJECT_REPR(defs)->addChild(repr, NULL); @@ -258,7 +268,7 @@ persp3d_document_first_persp (SPDocument *document) { static Inkscape::XML::Node * persp3d_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - Persp3D *persp = SP_PERSP3D(object); + Persp3DImpl *persp_impl = SP_PERSP3D(object)->perspective_impl; if ((flags & SP_OBJECT_WRITE_BUILD & SP_OBJECT_WRITE_EXT) && !repr) { // this is where we end up when saving as plain SVG (also in other circumstances?); @@ -268,16 +278,16 @@ persp3d_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML: if (flags & SP_OBJECT_WRITE_EXT) { gchar *str = NULL; // FIXME: Should this be freed each time we set an attribute or only in the end or at all? - str = persp3d_pt_to_str (persp, Proj::X); + str = persp3d_pt_to_str (persp_impl, Proj::X); repr->setAttribute("inkscape:vp_x", str); - str = persp3d_pt_to_str (persp, Proj::Y); + str = persp3d_pt_to_str (persp_impl, Proj::Y); repr->setAttribute("inkscape:vp_y", str); - str = persp3d_pt_to_str (persp, Proj::Z); + str = persp3d_pt_to_str (persp_impl, Proj::Z); repr->setAttribute("inkscape:vp_z", str); - str = persp3d_pt_to_str (persp, Proj::W); + str = persp3d_pt_to_str (persp_impl, Proj::W); repr->setAttribute("inkscape:persp3d-origin", str); } @@ -289,7 +299,7 @@ persp3d_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML: /* convenience wrapper around persp3d_get_finite_dir() and persp3d_get_infinite_dir() */ Geom::Point persp3d_get_PL_dir_from_pt (Persp3D *persp, Geom::Point const &pt, Proj::Axis axis) { - if (persp3d_VP_is_finite(persp, axis)) { + if (persp3d_VP_is_finite(persp->perspective_impl, axis)) { return persp3d_get_finite_dir(persp, pt, axis); } else { return persp3d_get_infinite_dir(persp, axis); @@ -314,17 +324,17 @@ persp3d_get_infinite_dir (Persp3D *persp, Proj::Axis axis) { double persp3d_get_infinite_angle (Persp3D *persp, Proj::Axis axis) { - return persp->tmat.get_infinite_angle(axis); + return persp->perspective_impl->tmat.get_infinite_angle(axis); } bool -persp3d_VP_is_finite (Persp3D *persp, Proj::Axis axis) { - return persp->tmat.has_finite_image(axis); +persp3d_VP_is_finite (Persp3DImpl *persp_impl, Proj::Axis axis) { + return persp_impl->tmat.has_finite_image(axis); } void persp3d_toggle_VP (Persp3D *persp, Proj::Axis axis, bool set_undo) { - persp->tmat.toggle_finite(axis); + persp->perspective_impl->tmat.toggle_finite(axis); // FIXME: Remove this repr update and rely on vp_drag_sel_modified() to do this for us // On the other hand, vp_drag_sel_modified() would update all boxes; // here we can confine ourselves to the boxes of this particular perspective. @@ -348,7 +358,7 @@ persp3d_toggle_VPs (std::list<Persp3D *> p, Proj::Axis axis) { void persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state) { - if (persp3d_VP_is_finite(persp, axis) != (state == Proj::VP_FINITE)) { + if (persp3d_VP_is_finite(persp->perspective_impl, axis) != (state == Proj::VP_FINITE)) { persp3d_toggle_VP(persp, axis); } } @@ -356,62 +366,67 @@ persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state) { void persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_pressed) { // angle is in degrees // FIXME: Most of this functionality should be moved to trans_mat_3x4.(h|cpp) - if (persp->tmat.has_finite_image(axis)) { + if (persp->perspective_impl->tmat.has_finite_image(axis)) { // don't rotate anything for finite VPs return; } - Proj::Pt2 v_dir_proj (persp->tmat.column(axis)); + Proj::Pt2 v_dir_proj (persp->perspective_impl->tmat.column(axis)); Geom::Point v_dir (v_dir_proj[0], v_dir_proj[1]); double a = Geom::atan2 (v_dir) * 180/M_PI; a += alt_pressed ? 0.5 * ((angle > 0 ) - (angle < 0)) : angle; // the r.h.s. yields +/-0.5 or angle - persp->tmat.set_infinite_direction (axis, a); + persp->perspective_impl->tmat.set_infinite_direction (axis, a); persp3d_update_box_reprs (persp); SP_OBJECT(persp)->updateRepr(SP_OBJECT_WRITE_EXT); } void -persp3d_update_with_point (Persp3D *persp, Proj::Axis const axis, Proj::Pt2 const &new_image) { - persp->tmat.set_image_pt (axis, new_image); +persp3d_update_with_point (Persp3DImpl *persp_impl, Proj::Axis const axis, Proj::Pt2 const &new_image) { + persp_impl->tmat.set_image_pt (axis, new_image); } void persp3d_apply_affine_transformation (Persp3D *persp, Geom::Matrix const &xform) { - persp->tmat *= xform; + persp->perspective_impl->tmat *= xform; persp3d_update_box_reprs(persp); SP_OBJECT(persp)->updateRepr(SP_OBJECT_WRITE_EXT); } gchar * -persp3d_pt_to_str (Persp3D *persp, Proj::Axis const axis) +persp3d_pt_to_str (Persp3DImpl *persp_impl, Proj::Axis const axis) { - return persp->tmat.pt_to_str(axis); + return persp_impl->tmat.pt_to_str(axis); } void persp3d_add_box (Persp3D *persp, SPBox3D *box) { + Persp3DImpl *persp_impl = persp->perspective_impl; + if (!box) { return; } - if (std::find (persp->boxes.begin(), persp->boxes.end(), box) != persp->boxes.end()) { + if (std::find (persp_impl->boxes.begin(), persp_impl->boxes.end(), box) != persp_impl->boxes.end()) { return; } - persp->boxes.push_back(box); + persp_impl->boxes.push_back(box); } void persp3d_remove_box (Persp3D *persp, SPBox3D *box) { - std::vector<SPBox3D *>::iterator i = std::find (persp->boxes.begin(), persp->boxes.end(), box); - if (i != persp->boxes.end()) { - persp->boxes.erase(i); - } + Persp3DImpl *persp_impl = persp->perspective_impl; + + std::vector<SPBox3D *>::iterator i = std::find (persp_impl->boxes.begin(), persp_impl->boxes.end(), box); + if (i != persp_impl->boxes.end()) + persp_impl->boxes.erase(i); } bool persp3d_has_box (Persp3D *persp, SPBox3D *box) { + Persp3DImpl *persp_impl = persp->perspective_impl; + // FIXME: For some reason, std::find() does not seem to compare pointers "correctly" (or do we need to // provide a proper comparison function?), so we manually traverse the list. - for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) { + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { if ((*i) == box) { return true; } @@ -420,86 +435,27 @@ persp3d_has_box (Persp3D *persp, SPBox3D *box) { } void -persp3d_add_box_transform (Persp3D *persp, SPBox3D *box) { - std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->find(box); - if (i != persp->boxes_transformed->end() && (*i).second == true) { - g_print ("Warning! In %s (%d): trying to add transform status for box %d twice when it's already listed as true.\n", SP_OBJECT_REPR(persp)->attribute("id"), persp->my_counter, box->my_counter); - return; - } - - (*persp->boxes_transformed)[box] = false; -} - -void -persp3d_remove_box_transform (Persp3D *persp, SPBox3D *box) { - persp->boxes_transformed->erase(box); -} +persp3d_update_box_displays (Persp3D *persp) { + Persp3DImpl *persp_impl = persp->perspective_impl; -void -persp3d_set_box_transformed (Persp3D *persp, SPBox3D *box, bool transformed) { - if (persp->boxes_transformed->find(box) == persp->boxes_transformed->end()) { - g_print ("Warning! In %s (%d): trying to set transform status for box %d, but it is not listed in the perspective!! Aborting.\n", - SP_OBJECT_REPR(persp)->attribute("id"), persp->my_counter, - box->my_counter); + if (persp_impl->boxes.empty()) return; - } - - (*persp->boxes_transformed)[box] = transformed; -} - -bool -persp3d_was_transformed (Persp3D *persp) { - if (persp->boxes_transformed->size() == 1) { - /* either the transform has not been applied to the single box associated to this perspective yet - or the transform was already reset; in both cases we need to return false because upcoming - transforms need to be applied */ - (*persp->boxes_transformed->begin()).second = false; // make sure the box is marked as untransformed (in case more boxes are added later) - return false; - } - - for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin(); - i != persp->boxes_transformed->end(); ++i) { - if ((*i).second == true) { - // at least one of the boxes in the perspective has already been transformed; - return true; - } - } - return false; // all boxes in the perspective are still untransformed; a pending transformation should be applied -} - -bool -persp3d_all_transformed(Persp3D *persp) { - for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin(); - i != persp->boxes_transformed->end(); ++i) { - if ((*i).second == false) { - return false; - } - } - return true; -} - -void -persp3d_unset_transforms(Persp3D *persp) { - for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin(); - i != persp->boxes_transformed->end(); ++i) { - (*i).second = false; + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { + box3d_position_set(*i); } } void -persp3d_update_box_displays (Persp3D *persp) { - if (persp->boxes.empty()) +persp3d_update_box_reprs (Persp3D *persp) { + if (!persp) { + // Hmm, is it an error if this happens? return; - for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) { - box3d_position_set(*i); } -} + Persp3DImpl *persp_impl = persp->perspective_impl; -void -persp3d_update_box_reprs (Persp3D *persp) { - if (persp->boxes.empty()) + if (persp_impl->boxes.empty()) return; - for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) { + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { SP_OBJECT(*i)->updateRepr(SP_OBJECT_WRITE_EXT); box3d_set_z_orders(*i); } @@ -507,9 +463,11 @@ persp3d_update_box_reprs (Persp3D *persp) { void persp3d_update_z_orders (Persp3D *persp) { - if (persp->boxes.empty()) + Persp3DImpl *persp_impl = persp->perspective_impl; + + if (persp_impl->boxes.empty()) return; - for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) { + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { box3d_set_z_orders(*i); } } @@ -519,8 +477,10 @@ persp3d_update_z_orders (Persp3D *persp) { // obsolete. We should do this. std::list<SPBox3D *> persp3d_list_of_boxes(Persp3D *persp) { + Persp3DImpl *persp_impl = persp->perspective_impl; + std::list<SPBox3D *> bx_lst; - for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) { + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { bx_lst.push_back(*i); } return bx_lst; @@ -529,7 +489,7 @@ persp3d_list_of_boxes(Persp3D *persp) { bool persp3d_perspectives_coincide(const Persp3D *lhs, const Persp3D *rhs) { - return lhs->tmat == rhs->tmat; + return lhs->perspective_impl->tmat == rhs->perspective_impl->tmat; } void @@ -566,10 +526,12 @@ persp3d_on_repr_attr_changed ( Inkscape::XML::Node * /*repr*/, /* checks whether all boxes linked to this perspective are currently selected */ bool -persp3d_has_all_boxes_in_selection (Persp3D *persp) { - std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList(); +persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection) { + Persp3DImpl *persp_impl = persp->perspective_impl; + + std::list<SPBox3D *> selboxes = selection->box3DList(); - for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) { + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { if (std::find(selboxes.begin(), selboxes.end(), *i) == selboxes.end()) { // we have an unselected box in the perspective return false; @@ -578,62 +540,12 @@ persp3d_has_all_boxes_in_selection (Persp3D *persp) { return true; } -/** - * For each perspective having a box in \a selection, determine all its unselected boxes. - */ -// TODO: Check where we can use pass-by-reference (or so) instead of recreating all the lists afresh. -std::map<Persp3D *, std::list<SPBox3D *> > -persp3d_unselected_boxes(Inkscape::Selection *selection) { - std::list<Persp3D *> plist = selection->perspList(); - std::map<Persp3D *, std::list<SPBox3D *> > punsel; - - std::list<Persp3D *>::iterator i; - std::vector<SPBox3D *>::iterator j; - // for all perspectives in the list ... - for (i = plist.begin(); i != plist.end(); ++i) { - Persp3D *persp = *i; - // ... and each box associated to it ... - for (j = persp->boxes.begin(); j != persp->boxes.end(); ++j) { - SPBox3D *box = *j; - // ... check whether it is unselected, and if so add it to the list - if (persp->boxes_transformed->find(box) == persp->boxes_transformed->end()) { - punsel[persp].push_back(box); - } - } - } - return punsel; -} - -/** - * Split all perspectives with a box in \a selection by moving their unselected boxes to newly - * created perspectives. - */ -void -persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection) { - std::map<Persp3D *, std::list<SPBox3D *> > punsel = persp3d_unselected_boxes(selection); - - std::map<Persp3D *, std::list<SPBox3D *> >::iterator i; - std::list<SPBox3D *>::iterator j; - // for all perspectives in the list ... - for (i = punsel.begin(); i != punsel.end(); ++i) { - Persp3D *persp = (*i).first; - // ... if the perspective has unselected boxes ... - if (!(*i).second.empty()) { - // create a new perspective and move these boxes over - Persp3D * new_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp); - for (j = (*i).second.begin(); j != (*i).second.end(); ++j) { - SPBox3D *box = *j; - box3d_switch_perspectives(box, persp, new_persp); - } - } - } -} - /* some debugging stuff follows */ void persp3d_print_debugging_info (Persp3D *persp) { - g_print ("=== Info for Persp3D %d ===\n", persp->my_counter); + Persp3DImpl *persp_impl = persp->perspective_impl; + g_print ("=== Info for Persp3D %d ===\n", persp_impl->my_counter); gchar * cstr; for (int i = 0; i < 4; ++i) { cstr = persp3d_get_VP(persp, Proj::axes[i]).coord_string(); @@ -645,8 +557,8 @@ persp3d_print_debugging_info (Persp3D *persp) { g_free(cstr); g_print (" Boxes: "); - for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) { - g_print ("%d (%d) ", (*i)->my_counter, box3d_get_perspective(*i)->my_counter); + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { + g_print ("%d (%d) ", (*i)->my_counter, box3d_get_perspective(*i)->perspective_impl->my_counter); } g_print ("\n"); g_print ("========================\n"); @@ -674,16 +586,23 @@ persp3d_print_all_selected() { for (std::list<Persp3D *>::iterator j = sel_persps.begin(); j != sel_persps.end(); ++j) { Persp3D *persp = SP_PERSP3D(*j); - g_print (" %s (%d): ", SP_OBJECT_REPR(persp)->attribute("id"), persp->my_counter); - for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed->begin(); - i != persp->boxes_transformed->end(); ++i) { - g_print ("<%d,%d> ", (*i).first->my_counter, (*i).second); + Persp3DImpl *persp_impl = persp->perspective_impl; + g_print (" %s (%d): ", SP_OBJECT_REPR(persp)->attribute("id"), persp->perspective_impl->my_counter); + for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); + i != persp_impl->boxes.end(); ++i) { + g_print ("%d ", (*i)->my_counter); } g_print ("\n"); } g_print ("======================================\n\n"); } +void print_current_persp3d(gchar *func_name, Persp3D *persp) { + g_print ("%s: current_persp3d is now %s\n", + func_name, + persp ? SP_OBJECT_REPR(persp)->attribute("id") : "NULL"); +} + /* Local Variables: mode:c++ diff --git a/src/persp3d.h b/src/persp3d.h index 79bec0232..62cc586ef 100644 --- a/src/persp3d.h +++ b/src/persp3d.h @@ -29,16 +29,25 @@ class SPBox3D; class Box3DContext; -struct Persp3D : public SPObject { +class Persp3DImpl { +public: + Persp3DImpl(); + +//private: Proj::TransfMat3x4 tmat; // Also write the list of boxes into the xml repr and vice versa link boxes to their persp3d? std::vector<SPBox3D *> boxes; - std::map<SPBox3D *, bool>* boxes_transformed; // TODO: eventually we should merge this with 'boxes' - SPDocument *document; // should this rather be the SPDesktop? + SPDocument *document; // for debugging only int my_counter; + +// friend class Persp3D; +}; + +struct Persp3D : public SPObject { + Persp3DImpl *perspective_impl; }; struct Persp3DClass { @@ -54,52 +63,43 @@ inline Persp3D * persp3d_get_from_repr (Inkscape::XML::Node *repr) { return SP_PERSP3D(SP_ACTIVE_DOCUMENT->getObjectByRepr(repr)); } inline Proj::Pt2 persp3d_get_VP (Persp3D *persp, Proj::Axis axis) { - return persp->tmat.column(axis); + return persp->perspective_impl->tmat.column(axis); } Geom::Point persp3d_get_PL_dir_from_pt (Persp3D *persp, Geom::Point const &pt, Proj::Axis axis); // convenience wrapper around the following two Geom::Point persp3d_get_finite_dir (Persp3D *persp, Geom::Point const &pt, Proj::Axis axis); Geom::Point persp3d_get_infinite_dir (Persp3D *persp, Proj::Axis axis); double persp3d_get_infinite_angle (Persp3D *persp, Proj::Axis axis); -bool persp3d_VP_is_finite (Persp3D *persp, Proj::Axis axis); +bool persp3d_VP_is_finite (Persp3DImpl *persp_impl, Proj::Axis axis); void persp3d_toggle_VP (Persp3D *persp, Proj::Axis axis, bool set_undo = true); void persp3d_toggle_VPs (std::list<Persp3D *>, Proj::Axis axis); void persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state); void persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_pressed); // angle is in degrees -void persp3d_update_with_point (Persp3D *persp, Proj::Axis const axis, Proj::Pt2 const &new_image); void persp3d_apply_affine_transformation (Persp3D *persp, Geom::Matrix const &xform); -gchar * persp3d_pt_to_str (Persp3D *persp, Proj::Axis const axis); void persp3d_add_box (Persp3D *persp, SPBox3D *box); void persp3d_remove_box (Persp3D *persp, SPBox3D *box); bool persp3d_has_box (Persp3D *persp, SPBox3D *box); -void persp3d_add_box_transform (Persp3D *persp, SPBox3D *box); -void persp3d_remove_box_transform (Persp3D *persp, SPBox3D *box); -void persp3d_set_box_transformed (Persp3D *persp, SPBox3D *box, bool transformed = true); -bool persp3d_was_transformed (Persp3D *persp); -bool persp3d_all_transformed(Persp3D *persp); -void persp3d_unset_transforms(Persp3D *persp); - void persp3d_update_box_displays (Persp3D *persp); void persp3d_update_box_reprs (Persp3D *persp); void persp3d_update_z_orders (Persp3D *persp); -inline unsigned int persp3d_num_boxes (Persp3D *persp) { return persp->boxes.size(); } +inline unsigned int persp3d_num_boxes (Persp3D *persp) { return persp->perspective_impl->boxes.size(); } std::list<SPBox3D *> persp3d_list_of_boxes(Persp3D *persp); bool persp3d_perspectives_coincide(const Persp3D *lhs, const Persp3D *rhs); void persp3d_absorb(Persp3D *persp1, Persp3D *persp2); -Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3D *dup = NULL); +Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup = NULL); Persp3D * persp3d_document_first_persp (SPDocument *document); -bool persp3d_has_all_boxes_in_selection (Persp3D *persp); -std::map<Persp3D *, std::list<SPBox3D *> > persp3d_unselected_boxes(Inkscape::Selection *selection); -void persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection); +bool persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection); void persp3d_print_debugging_info (Persp3D *persp); void persp3d_print_debugging_info_all(SPDocument *doc); void persp3d_print_all_selected(); +void print_current_persp3d(gchar *func_name, Persp3D *persp); + #endif /* __PERSP3D_H__ */ /* diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 70d1140ba..4e5291baf 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -340,6 +340,7 @@ static char const preferences_skeleton[] = " </group>\n" " <group id=\"workarounds\"\n" " colorsontop=\"0\"/>\n" +" <group id=\"threading\" numthreads=\"1\"/>\n" " </group>\n" "\n" " <group id=\"extensions\">" diff --git a/src/print.cpp b/src/print.cpp index 044dffe34..ed9b8d19c 100644 --- a/src/print.cpp +++ b/src/print.cpp @@ -130,6 +130,7 @@ sp_print_document(Gtk::Window& parentWindow, SPDocument *doc) SPItem *base = SP_ITEM(sp_document_root(doc)); NRArena *arena = NRArena::create(); unsigned int dkey = sp_item_display_key_new(1); + // TODO investigate why we are grabbing root and then ignoring it. NRArenaItem *root = sp_item_invoke_show(base, arena, dkey, SP_ITEM_SHOW_DISPLAY); // Run print dialog diff --git a/src/selcue.cpp b/src/selcue.cpp index 714daaa7e..8756524dd 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -181,18 +181,20 @@ void Inkscape::SelCue::_newTextBaselines() if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline Inkscape::Text::Layout const *layout = te_get_layout(item); if (layout != NULL && layout->outputExists()) { - Geom::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item); - baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL, - "mode", SP_CTRL_MODE_XOR, - "size", 4.0, - "filled", 0, - "stroked", 1, - "stroke_color", 0x000000ff, - NULL); - - sp_canvas_item_show(baseline_point); - SP_CTRL(baseline_point)->moveto(a); - sp_canvas_item_move_to_z(baseline_point, 0); + boost::optional<Geom::Point> pt = layout->baselineAnchorPoint(); + if (pt) { + baseline_point = sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRL, + "mode", SP_CTRL_MODE_XOR, + "size", 4.0, + "filled", 0, + "stroked", 1, + "stroke_color", 0x000000ff, + NULL); + + sp_canvas_item_show(baseline_point); + SP_CTRL(baseline_point)->moveto((*pt) * sp_item_i2d_affine(item)); + sp_canvas_item_move_to_z(baseline_point, 0); + } } } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index e55bba2a5..31e899d8a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -76,6 +76,7 @@ #include "helper/units.h" #include "sp-item.h" #include "box3d.h" +#include "persp3d.h" #include "unit-constants.h" #include "xml/simple-document.h" #include "sp-filter-reference.h" @@ -1171,7 +1172,6 @@ selection_contains_both_clone_and_original(Inkscape::Selection *selection) return clone_with_original; } - /** Apply matrix to the selection. \a set_i2d is normally true, which means objects are in the original transform, synced with their reprs, and need to jump to the new transform in one go. A value of set_i2d==false is only used by seltrans when it's dragging objects live (not outlines); in @@ -1183,6 +1183,29 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons if (selection->isEmpty()) return; + // For each perspective with a box in selection, check whether all boxes are selected and + // unlink all non-selected boxes. + Persp3D *persp; + Persp3D *transf_persp; + std::list<Persp3D *> plist = selection->perspList(); + for (std::list<Persp3D *>::iterator i = plist.begin(); i != plist.end(); ++i) { + persp = (Persp3D *) (*i); + + if (!persp3d_has_all_boxes_in_selection (persp, selection)) { + std::list<SPBox3D *> selboxes = selection->box3DList(persp); + + // create a new perspective as a copy of the current one and link the selected boxes to it + transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp->perspective_impl); + + for (std::list<SPBox3D *>::iterator b = selboxes.begin(); b != selboxes.end(); ++b) + box3d_switch_perspectives(*b, persp, transf_persp); + } else { + transf_persp = persp; + } + + persp3d_apply_affine_transformation(transf_persp, affine); + } + for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { SPItem *item = SP_ITEM(l->data); diff --git a/src/selection.cpp b/src/selection.cpp index 4d92a18df..828a96968 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -162,24 +162,12 @@ void Selection::add(SPObject *obj, bool persist_selection_context/* = false */) _emitChanged(persist_selection_context); } -void Selection::add_box_perspective(SPBox3D *box) { - Persp3D *persp = box3d_get_perspective(box); - std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp); - if (p != _persps.end()) { - (*p).second++; - } else { - _persps[persp] = 1; - } -} - void Selection::add_3D_boxes_recursively(SPObject *obj) { std::list<SPBox3D *> boxes = box3d_extract_boxes(obj); for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) { SPBox3D *box = *i; - box3d_add_to_selection(box); _3dboxes.push_back(box); - add_box_perspective(box); } } @@ -220,33 +208,17 @@ void Selection::remove(SPObject *obj) { _emitChanged(); } -void Selection::remove_box_perspective(SPBox3D *box) { - Persp3D *persp = box3d_get_perspective(box); - std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp); - if (p == _persps.end()) { - g_print ("Warning! Trying to remove unselected perspective from selection!\n"); - return; - } - if ((*p).second > 1) { - _persps[persp]--; - } else { - _persps.erase(p); - } -} - void Selection::remove_3D_boxes_recursively(SPObject *obj) { std::list<SPBox3D *> boxes = box3d_extract_boxes(obj); for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) { SPBox3D *box = *i; - box3d_remove_from_selection(box); std::list<SPBox3D *>::iterator b = std::find(_3dboxes.begin(), _3dboxes.end(), box); if (b == _3dboxes.end()) { g_print ("Warning! Trying to remove unselected box from selection.\n"); return; } _3dboxes.erase(b); - remove_box_perspective(box); } } @@ -344,14 +316,27 @@ GSList const *Selection::reprList() { std::list<Persp3D *> const Selection::perspList() { std::list<Persp3D *> pl; - for (std::map<Persp3D *, unsigned int>::iterator p = _persps.begin(); p != _persps.end(); ++p) { - pl.push_back((*p).first); + for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) { + Persp3D *persp = box3d_get_perspective(*i); + if (std::find(pl.begin(), pl.end(), persp) == pl.end()) + pl.push_back(persp); } return pl; } -std::list<SPBox3D *> const Selection::box3DList() { - return _3dboxes; +std::list<SPBox3D *> const Selection::box3DList(Persp3D *persp) { + std::list<SPBox3D *> boxes; + if (persp) { + SPBox3D *box; + for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) { + box = *i; + if (persp == box3d_get_perspective(box)) + boxes.push_back(box); + } + } else { + boxes = _3dboxes; + } + return boxes; } SPObject *Selection::single() { diff --git a/src/selection.h b/src/selection.h index ecb1ef45e..5e035fb60 100644 --- a/src/selection.h +++ b/src/selection.h @@ -229,11 +229,14 @@ public: /// method for that GSList const *reprList(); - /* list of all perspectives which have a 3D box in the current selection + /** @brief Returns a list of all perspectives which have a 3D box in the current selection (these may also be nested in groups) */ std::list<Persp3D *> const perspList(); - std::list<SPBox3D *> const box3DList(); + /** @brief Returns a list of all 3D boxes in the current selection which are associated to @c + persp. If @c pers is @c NULL, return all selected boxes. + */ + std::list<SPBox3D *> const box3DList(Persp3D *persp = NULL); /** @brief Returns the number of layers in which there are selected objects */ guint numberOfLayers(); @@ -351,7 +354,6 @@ private: void remove_box_perspective(SPBox3D *box); void remove_3D_boxes_recursively(SPObject *obj); - std::map<Persp3D *, unsigned int> _persps; std::list<SPBox3D *> _3dboxes; GC::soft_ptr<SPDesktop> _desktop; diff --git a/src/snap.cpp b/src/snap.cpp index 545607889..2e38e4f14 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -164,18 +164,18 @@ bool SnapManager::gridSnapperMightSnap() const * \param point_type Category of points to which the source point belongs: node, guide or bounding box * \param p Current position of the snap source; will be overwritten by the position of the snap target if snapping has occurred * \param source_type Detailed description of the source type, will be used by the snap indicator - * \param first_point If true then this point is the first one from a set of points, all from the same selection and having the same transformation + * \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero * \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation */ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type, Geom::Point &p, Inkscape::SnapSourceType const source_type, - bool first_point, + long source_num, Geom::OptRect const &bbox_to_snap) const { //TODO: PointType and source_type are somewhat redundant; can't we get rid of the point_type parameter? - Inkscape::SnappedPoint const s = freeSnap(point_type, p, source_type, first_point, bbox_to_snap); + Inkscape::SnappedPoint const s = freeSnap(point_type, p, source_type, source_num, bbox_to_snap); s.getPoint(p); } @@ -194,7 +194,7 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point * \param point_type Category of points to which the source point belongs: node, guide or bounding box * \param p Current position of the snap source * \param source_type Detailed description of the source type, will be used by the snap indicator - * \param first_point If true then this point is the first one from a set of points, all from the same selection and having the same transformation + * \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero * \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation * \return An instance of the SnappedPoint class, which holds data on the snap source, snap target, and various metrics */ @@ -203,11 +203,11 @@ void SnapManager::freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointType point_type, Geom::Point const &p, Inkscape::SnapSourceType const &source_type, - bool first_point, + long source_num, Geom::OptRect const &bbox_to_snap) const { - if (!someSnapperMightSnap()) { - return Inkscape::SnappedPoint(p, source_type, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); + if (!someSnapperMightSnap()) { + return Inkscape::SnappedPoint(p, source_type, 0, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); } std::vector<SPItem const *> *items_to_ignore; @@ -224,7 +224,7 @@ Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::SnapPreferences::PointTyp SnapperList const snappers = getSnappers(); for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { - (*i)->freeSnap(sc, point_type, p, source_type, first_point, bbox_to_snap, items_to_ignore, _unselected_nodes); + (*i)->freeSnap(sc, point_type, p, source_type, source_num, bbox_to_snap, items_to_ignore, _unselected_nodes); } if (_item_to_ignore) { @@ -280,7 +280,7 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const Geom::Point const t_offset = t + grid->origin; SnappedConstraints sc; // Only the first three parameters are being used for grid snappers - snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, Inkscape::SNAPSOURCE_UNDEFINED, TRUE, Geom::OptRect(), NULL, NULL); + snapper->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_NODE, t_offset, Inkscape::SNAPSOURCE_UNDEFINED, 0, Geom::OptRect(), NULL, NULL); // Find the best snap for this grid, including intersections of the grid-lines Inkscape::SnappedPoint s = findBestSnap(t_offset, Inkscape::SNAPSOURCE_UNDEFINED, sc, false); if (s.getSnapped() && (s.getSnapDistance() < nearest_distance)) { @@ -323,7 +323,7 @@ Geom::Point SnapManager::multipleOfGridPitch(Geom::Point const &t) const * \param p Current position of the snap source; will be overwritten by the position of the snap target if snapping has occurred * \param source_type Detailed description of the source type, will be used by the snap indicator * \param constraint The direction or line along which snapping must occur - * \param first_point If true then this point is the first one from a set of points, all from the same selection and having the same transformation + * \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero * \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation */ @@ -331,10 +331,10 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp Geom::Point &p, Inkscape::SnapSourceType const source_type, Inkscape::Snapper::ConstraintLine const &constraint, - bool first_point, + long source_num, Geom::OptRect const &bbox_to_snap) const { - Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, source_type, constraint, first_point, bbox_to_snap); + Inkscape::SnappedPoint const s = constrainedSnap(point_type, p, source_type, constraint, source_num, bbox_to_snap); s.getPoint(p); } @@ -353,7 +353,7 @@ void SnapManager::constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointTyp * \param p Current position of the snap source * \param source_type Detailed description of the source type, will be used by the snap indicator * \param constraint The direction or line along which snapping must occur - * \param first_point If true then this point is the first one from a set of points, all from the same selection and having the same transformation + * \param source_num Sequence number of the source point within the set of points that is to be snapped. Starting at zero * \param bbox_to_snap Bounding box hulling the set of points, all from the same selection and having the same transformation */ @@ -361,11 +361,11 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P Geom::Point const &p, Inkscape::SnapSourceType const &source_type, Inkscape::Snapper::ConstraintLine const &constraint, - bool first_point, + long source_num, Geom::OptRect const &bbox_to_snap) const { if (!someSnapperMightSnap()) { - return Inkscape::SnappedPoint(p, source_type, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); + return Inkscape::SnappedPoint(p, source_type, 0, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); } std::vector<SPItem const *> *items_to_ignore; @@ -386,7 +386,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapPreferences::P SnappedConstraints sc; SnapperList const snappers = getSnappers(); for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { - (*i)->constrainedSnap(sc, point_type, pp, source_type, first_point, bbox_to_snap, constraint, items_to_ignore); + (*i)->constrainedSnap(sc, point_type, pp, source_type, source_num, bbox_to_snap, constraint, items_to_ignore); } if (_item_to_ignore) { @@ -420,7 +420,7 @@ void SnapManager::guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal, Inkscape::SnapSourceType source_type = Inkscape::SNAPSOURCE_GUIDE_ORIGIN; if (drag_type == SP_DRAG_ROTATE) { - source_type = Inkscape::SNAPSOURCE_GUIDE; + source_type = Inkscape::SNAPSOURCE_GUIDE; } // Snap to nodes @@ -432,9 +432,9 @@ void SnapManager::guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal, // Snap to guides & grid lines SnapperList snappers = getGridSnappers(); snappers.push_back(&guide); - for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { - (*i)->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, source_type, true, Geom::OptRect(), NULL, NULL); - } + for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { + (*i)->freeSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, source_type, 0, Geom::OptRect(), NULL, NULL); + } // Snap to intersections of curves, but not to the curves themselves! (see _snapTranslatingGuideToNodes in object-snapper.cpp) Inkscape::SnappedPoint const s = findBestSnap(p, source_type, sc, false, true); @@ -458,7 +458,7 @@ void SnapManager::guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal, void SnapManager::guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) const { - if (!snapprefs.getSnapEnabledGlobally() || snapprefs.getSnapPostponedGlobally()) { + if (!snapprefs.getSnapEnabledGlobally() || snapprefs.getSnapPostponedGlobally()) { return; } @@ -472,15 +472,15 @@ void SnapManager::guideConstrainedSnap(Geom::Point &p, SPGuide const &guideline) SnappedConstraints sc; Inkscape::Snapper::ConstraintLine cl(guideline.point_on_line, Geom::rot90(guideline.normal_to_line)); if (object.ThisSnapperMightSnap()) { - object.constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, source_type, true, Geom::OptRect(), cl, NULL); + object.constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, source_type, 0, Geom::OptRect(), cl, NULL); } // Snap to guides & grid lines - SnapperList snappers = getGridSnappers(); - snappers.push_back(&guide); - for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { - (*i)->constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, source_type, true, Geom::OptRect(), cl, NULL); - } + SnapperList snappers = getGridSnappers(); + snappers.push_back(&guide); + for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { + (*i)->constrainedSnap(sc, Inkscape::SnapPreferences::SNAPPOINT_GUIDE, p, source_type, 0, Geom::OptRect(), cl, NULL); + } Inkscape::SnappedPoint const s = findBestSnap(p, source_type, sc, false); s.getPoint(p); @@ -566,6 +566,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( g_assert(best_snapped_point.getAtIntersection() == false); std::vector<std::pair<Geom::Point, int> >::const_iterator j = transformed_points.begin(); + long source_num = 0; // std::cout << std::endl; for (std::vector<std::pair<Geom::Point, int> >::const_iterator i = points.begin(); i != points.end(); i++) { @@ -593,7 +594,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( if (transformation_type == SCALE && !uniform) { g_warning("Non-uniform constrained scaling is not supported!"); } - snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, i == points.begin(), bbox); + snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, source_num, bbox); } else { bool const c1 = fabs(b[Geom::X]) < 1e-6; bool const c2 = fabs(b[Geom::Y]) < 1e-6; @@ -602,9 +603,9 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( // 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).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, i == points.begin(), bbox); + snapped_point = constrainedSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), dedicated_constraint, source_num, bbox); } else { - snapped_point = freeSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), i == points.begin(), bbox); + snapped_point = freeSnap(type, (*j).first, static_cast<Inkscape::SnapSourceType>((*j).second), source_num, bbox); } } // std::cout << "dist = " << snapped_point.getSnapDistance() << std::endl; @@ -715,6 +716,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( } j++; + source_num++; } Geom::Coord best_metric; @@ -917,10 +919,10 @@ Inkscape::SnappedPoint SnapManager::constrainedSnapSkew(Inkscape::SnapPreference */ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, - Inkscape::SnapSourceType const source_type, - SnappedConstraints &sc, - bool constrained, - bool noCurves) const + Inkscape::SnapSourceType const source_type, + SnappedConstraints &sc, + bool constrained, + bool noCurves) const { /* @@ -943,10 +945,10 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, // search for the closest snapped curve if (!noCurves) { - Inkscape::SnappedCurve closestCurve; - if (getClosestCurve(sc.curves, closestCurve)) { - sp_list.push_back(Inkscape::SnappedPoint(closestCurve)); - } + Inkscape::SnappedCurve closestCurve; + if (getClosestCurve(sc.curves, closestCurve)) { + sp_list.push_back(Inkscape::SnappedPoint(closestCurve)); + } } if (snapprefs.getSnapIntersectionCS()) { @@ -1005,7 +1007,7 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(Geom::Point const &p, } // now let's see which snapped point gets a thumbs up - Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); + Inkscape::SnappedPoint bestSnappedPoint = Inkscape::SnappedPoint(p, Inkscape::SNAPSOURCE_UNDEFINED, 0, Inkscape::SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false); // 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 diff --git a/src/snap.h b/src/snap.h index e621bdb60..a3e463092 100644 --- a/src/snap.h +++ b/src/snap.h @@ -52,14 +52,14 @@ class SPNamedView; class SnapManager { public: - enum Transformation { + enum Transformation { TRANSLATION, SCALE, STRETCH, SKEW }; - SnapManager(SPNamedView const *v); + SnapManager(SPNamedView const *v); typedef std::list<const Inkscape::Snapper*> SnapperList; @@ -67,30 +67,30 @@ public: bool gridSnapperMightSnap() const; void setup(SPDesktop const *desktop, - bool snapindicator = true, - SPItem const *item_to_ignore = NULL, - std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL, - SPGuide *guide_to_ignore = NULL); + bool snapindicator = true, + SPItem const *item_to_ignore = NULL, + std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL, + SPGuide *guide_to_ignore = NULL); void setup(SPDesktop const *desktop, - bool snapindicator, - std::vector<SPItem const *> &items_to_ignore, - std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL, - SPGuide *guide_to_ignore = NULL); + bool snapindicator, + std::vector<SPItem const *> &items_to_ignore, + std::vector<std::pair<Geom::Point, int> > *unselected_nodes = NULL, + SPGuide *guide_to_ignore = NULL); // freeSnapReturnByRef() is preferred over freeSnap(), because it only returns a // point if snapping has occurred (by overwriting p); otherwise p is untouched void freeSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type, - Geom::Point &p, - Inkscape::SnapSourceType const source_type, - bool first_point = true, - Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; + Geom::Point &p, + Inkscape::SnapSourceType const source_type, + long source_num = 0, + Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; Inkscape::SnappedPoint freeSnap(Inkscape::SnapPreferences::PointType point_type, - Geom::Point const &p, - Inkscape::SnapSourceType const &source_type, - bool first_point = true, + Geom::Point const &p, + Inkscape::SnapSourceType const &source_type, + long source_num = 0, Geom::OptRect const &bbox_to_snap = Geom::OptRect() ) const; Geom::Point multipleOfGridPitch(Geom::Point const &t) const; @@ -98,17 +98,17 @@ public: // constrainedSnapReturnByRef() is preferred over constrainedSnap(), because it only returns a // point, by overwriting p, if snapping has occurred; otherwise p is untouched void constrainedSnapReturnByRef(Inkscape::SnapPreferences::PointType point_type, - Geom::Point &p, - Inkscape::SnapSourceType const source_type, - Inkscape::Snapper::ConstraintLine const &constraint, - bool first_point = true, - Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; + Geom::Point &p, + Inkscape::SnapSourceType const source_type, + Inkscape::Snapper::ConstraintLine const &constraint, + long source_num = 0, + Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; Inkscape::SnappedPoint constrainedSnap(Inkscape::SnapPreferences::PointType point_type, - Geom::Point const &p, - Inkscape::SnapSourceType const &source_type, - Inkscape::Snapper::ConstraintLine const &constraint, - bool first_point = true, + Geom::Point const &p, + Inkscape::SnapSourceType const &source_type, + Inkscape::Snapper::ConstraintLine const &constraint, + long source_num = 0, Geom::OptRect const &bbox_to_snap = Geom::OptRect()) const; void guideFreeSnap(Geom::Point &p, Geom::Point const &guide_normal, SPGuideDragType drag_type) const; diff --git a/src/snapped-curve.cpp b/src/snapped-curve.cpp index 4da2d4c7d..334038638 100644 --- a/src/snapped-curve.cpp +++ b/src/snapped-curve.cpp @@ -12,7 +12,7 @@ #include <2geom/crossing.h> #include <2geom/path-intersection.h> -Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, SnapTargetType target) +Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, long source_num, SnapTargetType target) { _distance = snapped_distance; _tolerance = std::max(snapped_tolerance, 1.0); @@ -25,6 +25,7 @@ Inkscape::SnappedCurve::SnappedCurve(Geom::Point const &snapped_point, Geom::Coo _at_intersection = false; _fully_constrained = fully_constrained; _source = source; + _source_num = source_num; _target = target; } @@ -41,6 +42,7 @@ Inkscape::SnappedCurve::SnappedCurve() _at_intersection = false; _fully_constrained = false; _source = SNAPSOURCE_UNDEFINED; + _source_num = 0; _target = SNAPTARGET_UNDEFINED; } @@ -83,12 +85,12 @@ Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &cur // TODO: Investigate whether it is possible to use document coordinates everywhere // in the snapper code. Only the mouse position should be in desktop coordinates, I guess. // All paths are already in document coords and we are certainly not going to change THAT. - return SnappedPoint(best_p, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryDist, primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true, + return SnappedPoint(best_p, Inkscape::SNAPSOURCE_UNDEFINED, primaryC->getSourceNum(), Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryDist, primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, true, secondaryDist, secondaryC->getTolerance(), secondaryC->getAlwaysSnap()); } // No intersection - return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false); + return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, 0, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false); } // search for the closest snapped line diff --git a/src/snapped-curve.h b/src/snapped-curve.h index 0a1fe2431..4eea6e734 100644 --- a/src/snapped-curve.h +++ b/src/snapped-curve.h @@ -24,7 +24,7 @@ class SnappedCurve : public SnappedPoint { public: SnappedCurve(); - SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, SnapTargetType target); + SnappedCurve(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, Geom::Coord const &snapped_tolerance, bool const &always_snap, bool const &fully_constrained, Geom::Curve const *curve, SnapSourceType source, long source_num, SnapTargetType target); ~SnappedCurve(); Inkscape::SnappedPoint intersect(SnappedCurve const &curve, Geom::Point const &p, Geom::Matrix dt2doc) const; //intersect with another SnappedCurve diff --git a/src/snapped-line.cpp b/src/snapped-line.cpp index 3ebbeaf70..9dde22a4e 100644 --- a/src/snapped-line.cpp +++ b/src/snapped-line.cpp @@ -11,12 +11,13 @@ #include "snapped-line.h" #include <2geom/line.h> -Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line) +Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line) : _start_point_of_line(start_point_of_line), _end_point_of_line(end_point_of_line) { _point = snapped_point; _source = source; - _target = target; + _source_num = source_num; + _target = target; _distance = snapped_distance; _tolerance = std::max(snapped_tolerance, 1.0); _always_snap = always_snap; @@ -32,7 +33,8 @@ Inkscape::SnappedLineSegment::SnappedLineSegment() _end_point_of_line = Geom::Point(0,0); _point = Geom::Point(0,0); _source = SNAPSOURCE_UNDEFINED; - _target = SNAPTARGET_UNDEFINED; + _source_num = 0; + _target = SNAPTARGET_UNDEFINED; _distance = NR_HUGE; _tolerance = 1; _always_snap = false; @@ -50,19 +52,19 @@ Inkscape::SnappedLineSegment::~SnappedLineSegment() Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegment const &line) const { Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default - try - { - inters = Geom::intersection(getLineSegment(), line.getLineSegment()); - } - catch (Geom::InfiniteSolutions e) - { - // We're probably dealing with parallel lines, so they don't really cross - inters = Geom::OptCrossing(); - } + try + { + inters = Geom::intersection(getLineSegment(), line.getLineSegment()); + } + catch (Geom::InfiniteSolutions e) + { + // We're probably dealing with parallel lines, so they don't really cross + inters = Geom::OptCrossing(); + } if (inters) { Geom::Point inters_pt = getLineSegment().pointAt((*inters).ta); - /* If a snapper has been told to "always snap", then this one should be preferred + /* If a snapper has been told to "always snap", then this one should be preferred * over the other, if that other one has not been told so. (The preferred snapper * will be labeled "primary" below) */ @@ -78,22 +80,23 @@ Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegmen Inkscape::SnappedLineSegment const *secondarySLS = use_this_as_primary ? &line : this; Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(inters_pt - this->getPoint()) : Geom::L2(inters_pt - line.getPoint()); Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(inters_pt - line.getPoint()) : Geom::L2(inters_pt - this->getPoint()); - return SnappedPoint(inters_pt, SNAPSOURCE_UNDEFINED, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true, + return SnappedPoint(inters_pt, SNAPSOURCE_UNDEFINED, primarySLS->getSourceNum(), SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true, secondaryDist, secondarySLS->getTolerance(), secondarySLS->getAlwaysSnap()); } // No intersection - return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false); + return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, 0, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false); }; -Inkscape::SnappedLine::SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line) +Inkscape::SnappedLine::SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line) : _normal_to_line(normal_to_line), _point_on_line(point_on_line) { - _source = source; - _target = target; - _distance = snapped_distance; + _source = source; + _source_num = source_num; + _target = target; + _distance = snapped_distance; _tolerance = std::max(snapped_tolerance, 1.0); _always_snap = always_snap; _second_distance = NR_HUGE; @@ -108,7 +111,8 @@ Inkscape::SnappedLine::SnappedLine() _normal_to_line = Geom::Point(0,0); _point_on_line = Geom::Point(0,0); _source = SNAPSOURCE_UNDEFINED; - _target = SNAPTARGET_UNDEFINED; + _source_num = 0; + _target = SNAPTARGET_UNDEFINED; _distance = NR_HUGE; _tolerance = 1; _always_snap = false; @@ -130,19 +134,19 @@ Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line) // The point of intersection should be considered for snapping, but might be outside the snapping range Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default - try - { - inters = Geom::intersection(getLine(), line.getLine()); - } - catch (Geom::InfiniteSolutions e) - { - // We're probably dealing with parallel lines, so they don't really cross - inters = Geom::OptCrossing(); - } + try + { + inters = Geom::intersection(getLine(), line.getLine()); + } + catch (Geom::InfiniteSolutions e) + { + // We're probably dealing with parallel lines, so they don't really cross + inters = Geom::OptCrossing(); + } if (inters) { - Geom::Point inters_pt = getLine().pointAt((*inters).ta); - /* If a snapper has been told to "always snap", then this one should be preferred + Geom::Point inters_pt = getLine().pointAt((*inters).ta); + /* If a snapper has been told to "always snap", then this one should be preferred * over the other, if that other one has not been told so. (The preferred snapper * will be labelled "primary" below) */ @@ -157,14 +161,14 @@ Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line) Inkscape::SnappedLine const *secondarySL = use_this_as_primary ? &line : this; Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(inters_pt - this->getPoint()) : Geom::L2(inters_pt - line.getPoint()); Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(inters_pt - line.getPoint()) : Geom::L2(inters_pt - this->getPoint()); - return SnappedPoint(inters_pt, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true, + return SnappedPoint(inters_pt, Inkscape::SNAPSOURCE_UNDEFINED, primarySL->getSourceNum(), Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true, secondaryDist, secondarySL->getTolerance(), secondarySL->getAlwaysSnap()); // The type of the snap target is yet undefined, as we cannot tell whether // we're snapping to grid or the guide lines; must be set by on a higher level } // No intersection - return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false); + return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, 0, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false); } // search for the closest snapped line segment diff --git a/src/snapped-line.h b/src/snapped-line.h index 3dec432e7..b95e7a7df 100644 --- a/src/snapped-line.h +++ b/src/snapped-line.h @@ -23,7 +23,7 @@ class SnappedLineSegment : public SnappedPoint { public: SnappedLineSegment(); - SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance,bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line); + SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &snapped_tolerance,bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line); ~SnappedLineSegment(); Inkscape::SnappedPoint intersect(SnappedLineSegment const &line) const; //intersect with another SnappedLineSegment Geom::LineSegment getLineSegment() const {return Geom::LineSegment(_start_point_of_line, _end_point_of_line);} @@ -39,7 +39,7 @@ class SnappedLine : public SnappedPoint { public: SnappedLine(); - SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line); + SnappedLine(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &normal_to_line, Geom::Point const &point_on_line); ~SnappedLine(); Inkscape::SnappedPoint intersect(SnappedLine const &line) const; //intersect with another SnappedLine // This line is described by this equation: diff --git a/src/snapped-point.cpp b/src/snapped-point.cpp index 2d028c6d7..102e761b9 100644 --- a/src/snapped-point.cpp +++ b/src/snapped-point.cpp @@ -14,8 +14,8 @@ #include "preferences.h" // overloaded constructor -Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained) - : _point(p), _source(source), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a) +Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained) + : _point(p), _source(source), _source_num(source_num), _target(target), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a) { // tolerance should never be smaller than 1 px, as it is used for normalization in isOtherSnapBetter. We don't want a division by zero. _at_intersection = false; @@ -27,8 +27,8 @@ Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const _pointer_distance = NR_HUGE; } -Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2) - : _point(p), _source(source), _target(target), _at_intersection(at_intersection), _fully_constrained(fully_constrained), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a), +Inkscape::SnappedPoint::SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2) + : _point(p), _source(source), _source_num(source_num), _target(target), _at_intersection(at_intersection), _fully_constrained(fully_constrained), _distance(d), _tolerance(std::max(t,1.0)), _always_snap(a), _second_distance(d2), _second_tolerance(std::max(t2,1.0)), _second_always_snap(a2) { // tolerance should never be smaller than 1 px, as it is used for normalization in @@ -41,6 +41,7 @@ Inkscape::SnappedPoint::SnappedPoint() { _point = Geom::Point(0,0); _source = SNAPSOURCE_UNDEFINED, + _source_num = 0, _target = SNAPTARGET_UNDEFINED, _at_intersection = false; _fully_constrained = false; @@ -73,7 +74,7 @@ bool getClosestSP(std::list<Inkscape::SnappedPoint> &list, Inkscape::SnappedPoin bool success = false; for (std::list<Inkscape::SnappedPoint>::const_iterator i = list.begin(); i != list.end(); i++) { - if ((i == list.begin()) || (*i).getSnapDistance() < result.getSnapDistance()) { + if ((i == list.begin()) || (*i).getSnapDistance() < result.getSnapDistance()) { result = *i; success = true; } @@ -93,9 +94,9 @@ bool Inkscape::SnappedPoint::isOtherSnapBetter(Inkscape::SnappedPoint const &oth // (both the snap distance and the pointer distance are measured in document pixels, not in screen pixels) if (weighted) { - Geom::Coord const dist_pointer_other = other_one.getPointerDistance(); - Geom::Coord const dist_pointer_this = getPointerDistance(); - // Weight factor: controls which node should be preferred for snapping, which is either + Geom::Coord const dist_pointer_other = other_one.getPointerDistance(); + Geom::Coord const dist_pointer_this = getPointerDistance(); + // Weight factor: controls which node should be preferred for snapping, which is either // the node with the closest snap (w = 0), or the node closest to the mousepointer (w = 1) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double w = prefs->getDoubleLimited("/options/snapweight/value", 0.5, 0, 1); @@ -103,21 +104,21 @@ bool Inkscape::SnappedPoint::isOtherSnapBetter(Inkscape::SnappedPoint const &oth w = 1; } if (w > 0) { - if (!(w == 1 && dist_pointer_this == dist_pointer_other)) { - // When accounting for the distance to the mouse pointer, then at least one of the snapped points should - // have that distance set. If not, then this is a bug. Either "weighted" must be set to false, or the - // mouse pointer distance must be set. - g_assert(dist_pointer_this != NR_HUGE || dist_pointer_other != NR_HUGE); - // The snap distance will always be smaller than the tolerance set for the snapper. The pointer distance can - // however be very large. To compare these in a fair way, we will have to normalize these metrics first - // The closest pointer distance will be normalized to 1.0; the other one will be > 1.0 - // The snap distance will be normalized to 1.0 if it's equal to the snapper tolerance - double const norm_p = std::min(dist_pointer_this, dist_pointer_other); - double const norm_t_other = std::min(50.0, other_one.getTolerance()); - double const norm_t_this = std::min(50.0, getTolerance()); - dist_other = w * dist_pointer_other / norm_p + (1-w) * dist_other / norm_t_other; - dist_this = w * dist_pointer_this / norm_p + (1-w) * dist_this / norm_t_this; - } + if (!(w == 1 && dist_pointer_this == dist_pointer_other)) { + // When accounting for the distance to the mouse pointer, then at least one of the snapped points should + // have that distance set. If not, then this is a bug. Either "weighted" must be set to false, or the + // mouse pointer distance must be set. + g_assert(dist_pointer_this != NR_HUGE || dist_pointer_other != NR_HUGE); + // The snap distance will always be smaller than the tolerance set for the snapper. The pointer distance can + // however be very large. To compare these in a fair way, we will have to normalize these metrics first + // The closest pointer distance will be normalized to 1.0; the other one will be > 1.0 + // The snap distance will be normalized to 1.0 if it's equal to the snapper tolerance + double const norm_p = std::min(dist_pointer_this, dist_pointer_other); + double const norm_t_other = std::min(50.0, other_one.getTolerance()); + double const norm_t_this = std::min(50.0, getTolerance()); + dist_other = w * dist_pointer_other / norm_p + (1-w) * dist_other / norm_t_other; + dist_this = w * dist_pointer_this / norm_p + (1-w) * dist_this / norm_t_this; + } } } diff --git a/src/snapped-point.h b/src/snapped-point.h index 70d16b0be..70d353a73 100644 --- a/src/snapped-point.h +++ b/src/snapped-point.h @@ -78,8 +78,8 @@ class SnappedPoint public: SnappedPoint(); - SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2); - SnappedPoint(Geom::Point const &p, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained); + SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &at_intersection, bool const &fully_constrained, Geom::Coord const &d2, Geom::Coord const &t2, bool const &a2); + SnappedPoint(Geom::Point const &p, SnapSourceType const &source, long source_num, SnapTargetType const &target, Geom::Coord const &d, Geom::Coord const &t, bool const &a, bool const &fully_constrained); ~SnappedPoint(); Geom::Coord getSnapDistance() const {return _distance;} @@ -115,13 +115,15 @@ public: void setTarget(SnapTargetType const target) {_target = target;} SnapTargetType getTarget() const {return _target;} void setSource(SnapSourceType const source) {_source = source;} - SnapSourceType getSource() const {return _source;} + SnapSourceType getSource() const {return _source;} + long getSourceNum() const {return _source_num;} bool isOtherSnapBetter(SnappedPoint const &other_one, bool weighted) const; /*void dump() const { std::cout << "_point = " << _point << std::endl; std::cout << "_source = " << _source << std::endl; + std::cout << "_source_num = " << _source_num << std::endl; std::cout << "_target = " << _target << std::endl; std::cout << "_at_intersection = " << _at_intersection << std::endl; std::cout << "_fully_constrained = " << _fully_constrained << std::endl; @@ -138,6 +140,7 @@ public: protected: Geom::Point _point; // Location of the snapped point SnapSourceType _source; // Describes what snapped + long _source_num; // Sequence number of the source point that snapped, if that point is part of a set of points. (starting at zero) SnapTargetType _target; // Describes to what we've snapped to bool _at_intersection; // If true, the snapped point is at an intersection bool _fully_constrained; // When snapping for example to a node, then the snap will be "fully constrained". @@ -153,7 +156,7 @@ protected: bool _always_snap; /* If the snapped point is at an intersection of e.g. two lines, then this is - the distance to the fartest line */ + the distance to the farthest line */ Geom::Coord _second_distance; /* The snapping tolerance in screen pixels (depends on zoom)*/ Geom::Coord _second_tolerance; diff --git a/src/snapper.h b/src/snapper.h index 110b3d36a..dcc0fbb81 100644 --- a/src/snapper.h +++ b/src/snapper.h @@ -39,9 +39,9 @@ namespace Inkscape class Snapper { public: - Snapper() {} - Snapper(SnapManager *sm, ::Geom::Coord const t); - virtual ~Snapper() {} + Snapper() {} + Snapper(SnapManager *sm, ::Geom::Coord const t); + virtual ~Snapper() {} virtual Geom::Coord getSnapperTolerance() const = 0; //returns the tolerance of the snapper in screen pixels (i.e. independent of zoom) virtual bool getSnapperAlwaysSnap() const = 0; //if true, then the snapper will always snap, regardless of its tolerance @@ -53,7 +53,7 @@ public: // These four methods are only used for grids, for which snapping can be enabled individually void setEnabled(bool s); - void setSnapVisibleOnly(bool s); + void setSnapVisibleOnly(bool s); bool getEnabled() const {return _snap_enabled;} bool getSnapVisibleOnly() const {return _snap_visible_only;} @@ -61,7 +61,7 @@ public: SnapPreferences::PointType const &/*t*/, Geom::Point const &/*p*/, SnapSourceType const &/*source_type*/, - bool const &/*first_point*/, + long /*source_num*/, Geom::OptRect const &/*bbox_to_snap*/, std::vector<SPItem const *> const */*it*/, std::vector<std::pair<Geom::Point, int> > */*unselected_nodes*/) const {}; @@ -90,9 +90,9 @@ public: } Geom::Point projection(Geom::Point const &p) const { // returns the projection of p on this constraintline - Geom::Point const p1_on_cl = _has_point ? _point : p; - Geom::Point const p2_on_cl = p1_on_cl + _direction; - return Geom::projection(p, Geom::Line(p1_on_cl, p2_on_cl)); + Geom::Point const p1_on_cl = _has_point ? _point : p; + Geom::Point const p2_on_cl = p1_on_cl + _direction; + return Geom::projection(p, Geom::Line(p1_on_cl, p2_on_cl)); } private: @@ -103,20 +103,20 @@ public: }; virtual void constrainedSnap(SnappedConstraints &/*sc*/, - SnapPreferences::PointType const &/*t*/, + SnapPreferences::PointType const &/*t*/, Geom::Point const &/*p*/, SnapSourceType const &/*source_type*/, - bool const &/*first_point*/, + long /*source_num*/, Geom::OptRect const &/*bbox_to_snap*/, ConstraintLine const &/*c*/, std::vector<SPItem const *> const */*it*/) const {}; protected: - SnapManager *_snapmanager; + SnapManager *_snapmanager; - // This is only used for grids, for which snapping can be enabled individually - bool _snap_enabled; ///< true if this snapper is enabled, otherwise false - bool _snap_visible_only; + // This is only used for grids, for which snapping can be enabled individually + bool _snap_enabled; ///< true if this snapper is enabled, otherwise false + bool _snap_visible_only; }; } diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 6af2f7169..e4259e52c 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -372,10 +372,16 @@ static gchar *sp_flowtext_description(SPItem *item) { Inkscape::Text::Layout const &layout = SP_FLOWTEXT(item)->layout; int const nChars = layout.iteratorToCharIndex(layout.end()); + + char *trunc = ""; + if (layout.inputTruncated()) { + trunc = _(" [truncated]"); + } + if (SP_FLOWTEXT(item)->has_internal_frame()) - return g_strdup_printf(ngettext("<b>Flowed text</b> (%d character)", "<b>Flowed text</b> (%d characters)", nChars), nChars); + return g_strdup_printf(ngettext("<b>Flowed text</b> (%d character%s)", "<b>Flowed text</b> (%d characters%s)", nChars), nChars, trunc); else - return g_strdup_printf(ngettext("<b>Linked flowed text</b> (%d character)", "<b>Linked flowed text</b> (%d characters)", nChars), nChars); + return g_strdup_printf(ngettext("<b>Linked flowed text</b> (%d character%s)", "<b>Linked flowed text</b> (%d characters%s)", nChars), nChars, trunc); } static NRArenaItem * diff --git a/src/sp-font-face.cpp b/src/sp-font-face.cpp index 1ec6f4601..704985b8c 100644 --- a/src/sp-font-face.cpp +++ b/src/sp-font-face.cpp @@ -13,7 +13,7 @@ * http://www.w3.org/TR/SVG/fonts.html#FontFaceElement * * Author: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008, Felipe C. da S. Sanches * diff --git a/src/sp-font-face.h b/src/sp-font-face.h index 8fe1c752f..e492ba091 100644 --- a/src/sp-font-face.h +++ b/src/sp-font-face.h @@ -14,7 +14,7 @@ * http://www.w3.org/TR/SVG/fonts.html#FontFaceElement * * Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * diff --git a/src/sp-font.cpp b/src/sp-font.cpp index 75fb18638..de272c72f 100644 --- a/src/sp-font.cpp +++ b/src/sp-font.cpp @@ -8,7 +8,7 @@ * SVG <font> element implementation * * Author: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008, Felipe C. da S. Sanches * diff --git a/src/sp-font.h b/src/sp-font.h index fad7ead42..a0f895a52 100644 --- a/src/sp-font.h +++ b/src/sp-font.h @@ -9,7 +9,7 @@ * SVG <font> element implementation * * Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * diff --git a/src/sp-glyph-kerning.cpp b/src/sp-glyph-kerning.cpp index 6d08f212c..872efc853 100644 --- a/src/sp-glyph-kerning.cpp +++ b/src/sp-glyph-kerning.cpp @@ -10,7 +10,7 @@ * W3C SVG 1.1 spec, page 476, section 20.7 * * Author: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008, Felipe C. da S. Sanches * diff --git a/src/sp-glyph-kerning.h b/src/sp-glyph-kerning.h index ec0866c2c..ce9b4bb15 100644 --- a/src/sp-glyph-kerning.h +++ b/src/sp-glyph-kerning.h @@ -10,7 +10,7 @@ * SVG <hkern> and <vkern> elements implementation * * Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * diff --git a/src/sp-glyph.cpp b/src/sp-glyph.cpp index 8af78a0aa..37e266da0 100644 --- a/src/sp-glyph.cpp +++ b/src/sp-glyph.cpp @@ -9,7 +9,7 @@ * SVG <glyph> element implementation * * Author: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008, Felipe C. da S. Sanches * diff --git a/src/sp-glyph.h b/src/sp-glyph.h index 8c35a3a83..316204c23 100644 --- a/src/sp-glyph.h +++ b/src/sp-glyph.h @@ -10,7 +10,7 @@ * SVG <glyph> element implementation * * Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 65aad1e2d..e3f708142 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -53,6 +53,13 @@ #include "color-profile.h" //#define DEBUG_LCMS #ifdef DEBUG_LCMS + + +#define DEBUG_MESSAGE(key, ...)\ +{\ + g_message( __VA_ARGS__ );\ +} + #include "preferences.h" #include <gtk/gtkmessagedialog.h> #endif // DEBUG_LCMS @@ -105,7 +112,7 @@ extern "C" #ifdef DEBUG_LCMS extern guint update_in_progress; -#define DEBUG_MESSAGE(key, ...) \ +#define DEBUG_MESSAGE_SCISLAC(key, ...) \ {\ Inkscape::Preferences *prefs = Inkscape::Preferences::get();\ bool dump = prefs->getBool("/options/scislac/" #key);\ diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 7ac7880a7..3845be232 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -67,7 +67,6 @@ 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 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, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const *snapprefs); @@ -129,7 +128,6 @@ sp_group_class_init (SPGroupClass *klass) item_class->bbox = sp_group_bbox; item_class->print = sp_group_print; item_class->description = sp_group_description; - item_class->set_transform = sp_group_set_transform; item_class->show = sp_group_show; item_class->hide = sp_group_hide; item_class->snappoints = sp_group_snappoints; @@ -291,24 +289,6 @@ static gchar * sp_group_description (SPItem * item) return SP_GROUP(item)->group->getDescription(); } -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); - - Geom::Matrix last_trans; - sp_svg_transform_read(SP_OBJECT_REPR(item)->attribute("transform"), &last_trans); - 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) { - persp3d_apply_affine_transformation(*i, inc_trans); - } - - return xform; -} - static void sp_group_set(SPObject *object, unsigned key, char const *value) { SPGroup *group = SP_GROUP(object); diff --git a/src/sp-marker-loc.h b/src/sp-marker-loc.h index 98cab3746..b6877e5aa 100644 --- a/src/sp-marker-loc.h +++ b/src/sp-marker-loc.h @@ -5,6 +5,8 @@ * These enums are to allow us to have 4-element arrays that represent a set of marker locations * (all, start, mid, and end). This allows us to iterate through the array in places where we need * to do a process across all of the markers, instead of separate code stanzas for each. + * + * IMPORTANT: the code assumes that the locations have the values as written below! so don't change the values!!! */ enum SPMarkerLoc { SP_MARKER_LOC = 0, diff --git a/src/sp-missing-glyph.cpp b/src/sp-missing-glyph.cpp index ffc29a71e..d25a5f812 100644 --- a/src/sp-missing-glyph.cpp +++ b/src/sp-missing-glyph.cpp @@ -9,7 +9,7 @@ * SVG <missing-glyph> element implementation * * Author: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008, Felipe C. da S. Sanches * diff --git a/src/sp-missing-glyph.h b/src/sp-missing-glyph.h index 2a4cfde07..0b3f74360 100644 --- a/src/sp-missing-glyph.h +++ b/src/sp-missing-glyph.h @@ -10,7 +10,7 @@ * SVG <missing-glyph> element implementation * * Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 47720c5d6..9b72a4157 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -304,6 +304,7 @@ static void sp_namedview_release(SPObject *object) static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *value) { SPNamedView *nv = SP_NAMEDVIEW(object); + // TODO investigate why we grab this and then never use it SPUnit const &px = sp_unit_get_by_id(SP_UNIT_PX); switch (key) { diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 2120ddd64..bbcb25356 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -295,6 +295,7 @@ sp_path_set(SPObject *object, unsigned int key, gchar const *value) object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_CONNECTOR_TYPE: + case SP_ATTR_CONNECTOR_CURVATURE: case SP_ATTR_CONNECTION_START: case SP_ATTR_CONNECTION_END: path->connEndPair.setAttr(key, value); diff --git a/src/sp-script.cpp b/src/sp-script.cpp index a40132450..ad41b8021 100644 --- a/src/sp-script.cpp +++ b/src/sp-script.cpp @@ -4,7 +4,7 @@ * SVG <script> implementation * * Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2008 authors * diff --git a/src/sp-script.h b/src/sp-script.h index fa1906052..127eeedf7 100644 --- a/src/sp-script.h +++ b/src/sp-script.h @@ -5,7 +5,7 @@ * SVG <script> implementation * * Author: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Author * diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 0d3fd791b..b45f8cbb6 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -421,20 +421,30 @@ sp_text_description(SPItem *item) GString *xs = SP_PX_TO_METRIC_STRING(style->font_size.computed, sp_desktop_namedview(SP_ACTIVE_DESKTOP)->getDefaultMetric()); + char *trunc = ""; + Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item); + if (layout && layout->inputTruncated()) { + trunc = _(" [truncated]"); + } + char *ret = ( SP_IS_TEXT_TEXTPATH(item) - ? g_strdup_printf(_("<b>Text on path</b> (%s, %s)"), n, xs->str) - : g_strdup_printf(_("<b>Text</b> (%s, %s)"), n, xs->str) ); + ? g_strdup_printf(_("<b>Text on path</b>%s (%s, %s)"), trunc, n, xs->str) + : g_strdup_printf(_("<b>Text</b>%s (%s, %s)"), trunc, n, xs->str) ); g_free(n); return ret; } static void sp_text_snappoints(SPItem const *item, bool const target, SnapPointsWithType &p, Inkscape::SnapPreferences const */*snapprefs*/) { - // the baseline anchor of the first char + // Choose a point on the baseline for snapping from or to, with the horizontal position + // of this point depending on the text alignment (left vs. right) Inkscape::Text::Layout const *layout = te_get_layout((SPItem *) item); - if(layout != NULL) { - int type = target ? int(Inkscape::SNAPTARGET_TEXT_BASELINE) : int(Inkscape::SNAPSOURCE_TEXT_BASELINE); - p.push_back(std::make_pair(layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item), type)); + if (layout != NULL && layout->outputExists()) { + boost::optional<Geom::Point> pt = layout->baselineAnchorPoint(); + if (pt) { + int type = target ? int(Inkscape::SNAPTARGET_TEXT_BASELINE) : int(Inkscape::SNAPSOURCE_TEXT_BASELINE); + p.push_back(std::make_pair((*pt) * sp_item_i2d_affine(item), type)); + } } } diff --git a/src/spray-context.cpp b/src/spray-context.cpp index 71dc9648a..585b24c44 100644 --- a/src/spray-context.cpp +++ b/src/spray-context.cpp @@ -6,7 +6,7 @@ * Authors: * Pierre-Antoine MARC * Pierre CACLIN - * Aurel-Aimé MARMION + * Aurel-Aimé MARMION * Julien LERAY * Benoît LAVORATA * Vincent MONTAGNE @@ -39,14 +39,14 @@ #include "desktop-style.h" #include "message-context.h" #include "pixmaps/cursor-spray.xpm" -#include "pixmaps/cursor-spray-move.xpm" -#include "pixmaps/cursor-thin.xpm" -#include "pixmaps/cursor-thicken.xpm" -#include "pixmaps/cursor-attract.xpm" -#include "pixmaps/cursor-repel.xpm" -#include "pixmaps/cursor-push.xpm" -#include "pixmaps/cursor-roughen.xpm" -#include "pixmaps/cursor-color.xpm" +//#include "pixmaps/cursor-spray-move.xpm" +//#include "pixmaps/cursor-thin.xpm" +//#include "pixmaps/cursor-thicken.xpm" +//#include "pixmaps/cursor-attract.xpm" +//#include "pixmaps/cursor-repel.xpm" +//#include "pixmaps/cursor-push.xpm" +//#include "pixmaps/cursor-roughen.xpm" +//#include "pixmaps/cursor-color.xpm" #include <boost/optional.hpp> #include "libnr/nr-matrix-ops.h" #include "libnr/nr-scale-translate-ops.h" @@ -74,7 +74,7 @@ #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 "preferences.h" #include "style.h" @@ -104,7 +104,7 @@ static void sp_spray_context_setup(SPEventContext *ec); static void sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val); static gint sp_spray_context_root_handler(SPEventContext *ec, GdkEvent *event); -static SPEventContextClass *parent_class; +static SPEventContextClass *parent_class = 0; @@ -143,8 +143,7 @@ double NormalDistribution(double mu,double sigma) //Fin de la création de NormalDistribution -GtkType -sp_spray_context_get_type(void) +GtkType sp_spray_context_get_type(void) { static GType type = 0; if (!type) { @@ -163,8 +162,7 @@ sp_spray_context_get_type(void) return type; } -static void -sp_spray_context_class_init(SPSprayContextClass *klass) +static void sp_spray_context_class_init(SPSprayContextClass *klass) { GObjectClass *object_class = (GObjectClass *) klass; SPEventContextClass *event_context_class = (SPEventContextClass *) klass; @@ -177,9 +175,9 @@ sp_spray_context_class_init(SPSprayContextClass *klass) event_context_class->set = sp_spray_context_set; event_context_class->root_handler = sp_spray_context_root_handler; } + /*Method to rotate items*/ -void -sp_spray_rotate_rel(Geom::Point c,SPDesktop *desktop,SPItem *item, Geom::Rotate const &rotation) +void sp_spray_rotate_rel(Geom::Point c,SPDesktop */*desktop*/,SPItem *item, Geom::Rotate const &rotation) { Geom::Point center = c; @@ -197,23 +195,23 @@ sp_spray_rotate_rel(Geom::Point c,SPDesktop *desktop,SPItem *item, Geom::Rotate item->updateRepr(); } } + /*Method to scale items*/ -void -sp_spray_scale_rel (Geom::Point c, SPDesktop *desktop, SPItem *item, Geom::Scale const &scale) +void sp_spray_scale_rel(Geom::Point c, SPDesktop */*desktop*/, SPItem *item, Geom::Scale const &scale) { - Geom::Translate const s(c); + Geom::Translate const s(c); + - sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * s.inverse() * scale * s ); sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); } -static void -sp_spray_context_init(SPSprayContext *tc) -{ + +static void sp_spray_context_init(SPSprayContext *tc) +{ SPEventContext *event_context = SP_EVENT_CONTEXT(tc); - + event_context->cursor_shape = cursor_spray_xpm; @@ -247,8 +245,7 @@ sp_spray_context_init(SPSprayContext *tc) new (&tc->style_set_connection) sigc::connection(); } -static void -sp_spray_context_dispose(GObject *object) +static void sp_spray_context_dispose(GObject *object) { SPSprayContext *tc = SP_SPRAY_CONTEXT(object); @@ -267,7 +264,7 @@ sp_spray_context_dispose(GObject *object) G_OBJECT_CLASS(parent_class)->dispose(object); } -bool is_transform_modes (gint mode) +bool is_transform_modes(gint mode) { return (mode == SPRAY_MODE_COPY || mode == SPRAY_MODE_CLONE || @@ -275,8 +272,7 @@ bool is_transform_modes (gint mode) mode == SPRAY_OPTION); } -void -sp_spray_update_cursor (SPSprayContext *tc, bool with_shift) +void sp_spray_update_cursor(SPSprayContext *tc, bool /*with_shift*/) { SPEventContext *event_context = SP_EVENT_CONTEXT(tc); SPDesktop *desktop = event_context->desktop; @@ -309,8 +305,7 @@ sp_spray_update_cursor (SPSprayContext *tc, bool with_shift) g_free(sel_message); } -static void -sp_spray_context_setup(SPEventContext *ec) +static void sp_spray_context_setup(SPEventContext *ec) { SPSprayContext *tc = SP_SPRAY_CONTEXT(ec); @@ -338,7 +333,7 @@ sp_spray_context_setup(SPEventContext *ec) tc->_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack()); - sp_event_context_read(ec, "distrib"); + sp_event_context_read(ec, "distrib"); sp_event_context_read(ec, "width"); sp_event_context_read(ec, "ratio"); sp_event_context_read(ec, "tilt"); @@ -372,21 +367,20 @@ sp_spray_context_setup(SPEventContext *ec) } } -static void -sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val) +static void sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val) { SPSprayContext *tc = SP_SPRAY_CONTEXT(ec); Glib::ustring path = val->getEntryName(); if (path == "width") { - tc->width = CLAMP(val->getDouble(0.1), -1000.0, 1000.0); + tc->width = 0.01 * CLAMP(val->getInt(10), 1, 100); } else if (path == "mode") { tc->mode = val->getInt(); sp_spray_update_cursor(tc, false); } else if (path == "distribution") { tc->distrib = val->getInt(1); } else if (path == "population") { - tc->population = CLAMP(val->getDouble(), 0.0, 1.0); + tc->population = 0.01 * CLAMP(val->getInt(10), 1, 100); } else if (path == "tilt") { tc->tilt = CLAMP(val->getDouble(0.1), 0, 1000.0); } else if (path == "ratio") { @@ -398,13 +392,13 @@ sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val) } else if (path == "rot_max") { tc->rot_max = CLAMP(val->getDouble(0), 0, 10.0); } else if (path == "scale_min") { - tc->scale_min = CLAMP(val->getDouble(1.0), 0, 10.0); + tc->scale_min = CLAMP(val->getDouble(1.0), 0, 10.0); } else if (path == "scale_max") { tc->scale_max = CLAMP(val->getDouble(1.0), 0, 10.0); } else if (path == "mean") { - tc->mean = CLAMP(val->getDouble(1.0), 0, 1.0); + tc->mean = 0.01 * CLAMP(val->getInt(10), 1, 100); } else if (path == "standard_deviation") { - tc->standard_deviation = CLAMP(val->getDouble(1.0), 0, 1.0); + tc->standard_deviation = 0.01 * CLAMP(val->getInt(10), 1, 100); } else if (path == "usepressure") { tc->usepressure = val->getBool(); } else if (path == "doh") { @@ -418,8 +412,7 @@ sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val) } } -static void -sp_spray_extinput(SPSprayContext *tc, GdkEvent *event) +static void sp_spray_extinput(SPSprayContext *tc, GdkEvent *event) { if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &tc->pressure)) tc->pressure = CLAMP (tc->pressure, TC_MIN_PRESSURE, TC_MAX_PRESSURE); @@ -427,8 +420,7 @@ sp_spray_extinput(SPSprayContext *tc, GdkEvent *event) tc->pressure = TC_DEFAULT_PRESSURE; } -double -get_dilate_radius (SPSprayContext *tc) +double get_dilate_radius(SPSprayContext *tc) { return 250 * tc->width/SP_EVENT_CONTEXT(tc)->desktop->current_zoom(); @@ -436,8 +428,7 @@ get_dilate_radius (SPSprayContext *tc) } -double -get_path_force (SPSprayContext *tc) +double get_path_force(SPSprayContext *tc) { double force = 8 * (tc->usepressure? tc->pressure : TC_DEFAULT_PRESSURE) /sqrt(SP_EVENT_CONTEXT(tc)->desktop->current_zoom()); @@ -447,33 +438,28 @@ get_path_force (SPSprayContext *tc) return force * tc->force; } -double -get_path_mean (SPSprayContext *tc) +double get_path_mean(SPSprayContext *tc) { return tc->mean; } -double -get_path_standard_deviation (SPSprayContext *tc) +double get_path_standard_deviation(SPSprayContext *tc) { return tc->standard_deviation; } -double -get_move_force (SPSprayContext *tc) +double get_move_force(SPSprayContext *tc) { double force = (tc->usepressure? tc->pressure : TC_DEFAULT_PRESSURE); return force * tc->force; } -double -get_move_mean (SPSprayContext *tc) +double get_move_mean(SPSprayContext *tc) { return tc->mean; } -double -get_move_standard_deviation (SPSprayContext *tc) +double get_move_standard_deviation(SPSprayContext *tc) { return tc->standard_deviation; } @@ -511,8 +497,26 @@ while(!((r_temp>=0)&&(r_temp<=1))) -bool -sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, SPItem *item, Geom::Point p, Geom::Point vector, gint mode, double radius, double force, double population, double &scale, double scale_min, double scale_max, bool reverse, double mean, double standard_deviation, double ratio,double tilt, double rot_min, double rot_max, gint _distrib ) +bool sp_spray_dilate_recursive(SPDesktop *desktop, + Inkscape::Selection *selection, + SPItem *item, + Geom::Point p, + Geom::Point /*vector*/, + gint mode, + double radius, + double /*force*/, + double population, + double &scale, + double scale_min, + double scale_max, + bool /*reverse*/, + double mean, + double standard_deviation, + double ratio, + double tilt, + double rot_min, + double rot_max, + gint _distrib ) { @@ -551,13 +555,13 @@ sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, S Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { - double dr; double dp; + double dr; double dp; random_position(dr,dp,mean,standard_deviation,_distrib); dr=dr*radius; double _fid = g_random_double_range(0,1); SPItem *item_copied; - double angle = g_random_double_range(rot_min, rot_max); - double _scale = g_random_double_range(scale_min, scale_max); + double angle = g_random_double_range(rot_min, rot_max); + double _scale = g_random_double_range(scale_min, scale_max); if(_fid<=population) { // duplicate @@ -571,17 +575,17 @@ sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, S SPObject *new_obj = doc->getObjectByRepr(copy); item_copied = (SPItem *) new_obj; //convertion object->item Geom::Point center=item->getCenter(); - sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale)); - sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale)); - - sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle)); + sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale)); + sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale)); + + sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle)); Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());//Move the cursor p sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); - - - + + + did = true; } } @@ -623,8 +627,8 @@ sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, S random_position(dr,dp,mean,standard_deviation,_distrib); dr=dr*radius; double _fid = g_random_double_range(0,1); - double angle = (g_random_double_range(rot_min, rot_max)); - double _scale = g_random_double_range(scale_min, scale_max); + double angle = (g_random_double_range(rot_min, rot_max)); + double _scale = g_random_double_range(scale_min, scale_max); if (i==2) { Inkscape::XML::Node *copy1 = old_repr->duplicate(xml_doc); parent->appendChild(copy1); @@ -640,11 +644,11 @@ sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, S parent->appendChild(copy2); SPObject *new_obj2 = doc->getObjectByRepr(copy2); item_copied = (SPItem *) new_obj2; - - Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());//Move around the cursor + + Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());//Move around the cursor Geom::Point center=Pere->getCenter(); - sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale)); + sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale)); sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale)); sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle)); sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); @@ -661,10 +665,10 @@ sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, S } } else if (mode == SPRAY_MODE_CLONE) { - + Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item)); if (a) { - double dr; double dp; + double dr; double dp; random_position(dr,dp,mean,standard_deviation,_distrib); dr=dr*radius; double _fid = g_random_double_range(0,1); @@ -673,7 +677,7 @@ sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, S if(_fid<=population) { - SPItem *item_copied; + SPItem *item_copied; 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); @@ -683,33 +687,43 @@ sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, S Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); parent->appendChild(clone); //Ajout du clone à la liste d'enfants du père (selection initiale clone->setAttribute("xlink:href", g_strdup_printf("#%s", old_repr->attribute("id")), false); //Génère le lien entre les attributs du père et du fils - - SPObject *clone_object = doc->getObjectByRepr(clone); + + SPObject *clone_object = doc->getObjectByRepr(clone); item_copied = (SPItem *) clone_object;//conversion object->item Geom::Point center=item->getCenter(); - sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale)); + sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale)); sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale)); - sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle)); + sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle)); Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint()); - sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); + sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); Inkscape::GC::release(clone); did = true; } }} return did; - + } -bool -sp_spray_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, - Geom::Point p, double radius, double force, - bool do_h, bool do_s, bool do_l, bool do_o) +bool sp_spray_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*/, + Geom::Point /*p*/, + double /*radius*/, + double /*force*/, + bool /*do_h*/, + bool /*do_s*/, + bool /*do_l*/, + bool /*do_o*/) { bool did = false; @@ -717,8 +731,7 @@ sp_spray_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, } -bool -sp_spray_dilate (SPSprayContext *tc, Geom::Point event_p, Geom::Point p, Geom::Point vector, bool reverse) +bool sp_spray_dilate(SPSprayContext *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse) { Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(tc)->desktop); SPDesktop *desktop = SP_EVENT_CONTEXT(tc)->desktop; @@ -815,8 +828,7 @@ sp_spray_dilate (SPSprayContext *tc, Geom::Point event_p, Geom::Point p, Geom::P return did; } -void -sp_spray_update_area (SPSprayContext *tc) +void sp_spray_update_area(SPSprayContext *tc) { double radius = get_dilate_radius(tc); Geom::Matrix const sm ( Geom::Scale(radius/(1-tc->ratio), radius/(1+tc->ratio)) ); @@ -824,8 +836,7 @@ sp_spray_update_area (SPSprayContext *tc) sp_canvas_item_show(tc->dilate_area); } -void -sp_spray_switch_mode (SPSprayContext *tc, gint mode, bool with_shift) +void sp_spray_switch_mode(SPSprayContext *tc, gint mode, bool with_shift) { SP_EVENT_CONTEXT(tc)->desktop->setToolboxSelectOneValue ("spray_tool_mode", mode); //sélectionne le bouton numéro "mode" // need to set explicitly, because the prefs may not have changed by the previous @@ -833,8 +844,7 @@ sp_spray_switch_mode (SPSprayContext *tc, gint mode, bool with_shift) sp_spray_update_cursor (tc, with_shift); } -void -sp_spray_switch_mode_temporarily (SPSprayContext *tc, gint mode, bool with_shift) +void sp_spray_switch_mode_temporarily(SPSprayContext *tc, gint mode, bool with_shift) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // Juggling about so that prefs have the old value but tc->mode and the button show new mode: @@ -847,8 +857,7 @@ sp_spray_switch_mode_temporarily (SPSprayContext *tc, gint mode, bool with_shift sp_spray_update_cursor (tc, with_shift); } -gint -sp_spray_context_root_handler(SPEventContext *event_context, +gint sp_spray_context_root_handler(SPEventContext *event_context, GdkEvent *event) { SPSprayContext *tc = SP_SPRAY_CONTEXT(event_context); @@ -922,7 +931,7 @@ sp_spray_context_root_handler(SPEventContext *event_context, sp_spray_dilate (tc, motion_w, motion_doc, motion_doc - tc->last_push, event->button.state & GDK_SHIFT_MASK? true : false); //tc->last_push = motion_doc; tc->has_dilated = true; - + // it's slow, so prevent clogging up with events gobble_motion_events(GDK_BUTTON1_MASK); return TRUE; @@ -942,7 +951,7 @@ sp_spray_context_root_handler(SPEventContext *event_context, Geom::Point const scroll_w(event->button.x,event->button.y); Geom::Point const scroll_dt = desktop->point();; Geom::Point motion_doc(desktop->dt2doc(scroll_dt)); - switch (event->scroll.direction) + switch (event->scroll.direction) { case GDK_SCROLL_UP: { @@ -957,16 +966,16 @@ sp_spray_context_root_handler(SPEventContext *event_context, tc->is_dilating = true; tc->has_dilated = false; if(tc->is_dilating && !event_context->space_panning) - + sp_spray_dilate (tc, scroll_w, desktop->dt2doc(scroll_dt), Geom::Point(0,0),false); - + tc->has_dilated=true; tc->population=temp; desktop->setToolboxAdjustmentValue ("population", tc->population * 100); - + ret = TRUE; } break; @@ -1042,17 +1051,17 @@ case GDK_SCROLL_LEFT: case GDK_j: if (MOD__SHIFT_ONLY) { sp_spray_switch_mode(tc, SPRAY_MODE_COPY, MOD__SHIFT); ret = TRUE; - } + } case GDK_J: if (MOD__SHIFT_ONLY) { sp_spray_switch_mode(tc, SPRAY_MODE_COPY, MOD__SHIFT); ret = TRUE; } - + break; case GDK_m: case GDK_M: case GDK_0: - + break; case GDK_i: case GDK_I: @@ -1065,12 +1074,12 @@ break; ret = TRUE; } break; - + case GDK_l: if (MOD__SHIFT_ONLY) { sp_spray_switch_mode(tc, SPRAY_MODE_CLONE, MOD__SHIFT); ret = TRUE; } - + case GDK_L: if (MOD__SHIFT_ONLY) { sp_spray_switch_mode(tc, SPRAY_MODE_CLONE, MOD__SHIFT); diff --git a/src/style.cpp b/src/style.cpp index 0b946f348..111018c2a 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -28,6 +28,7 @@ #include "svg/svg.h" #include "svg/svg-color.h" #include "svg/svg-icc-color.h" +#include "svg/svg-device-color.h" #include "display/canvas-bpath.h" #include "attributes.h" @@ -3184,6 +3185,17 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume } paint->value.color.icc = tmp; } + if (strneq(str, "device-gray(", 12) || + strneq(str, "device-rgb(", 11) || + strneq(str, "device-cmyk(", 12) || + strneq(str, "device-nchannel(", 16)) { + SVGDeviceColor* tmp = new SVGDeviceColor(); + if ( ! sp_svg_read_device_color( str, &str, tmp ) ) { + delete tmp; + tmp = 0; + } + paint->value.color.device = tmp; + } } } } diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index a8e24c311..7d43b68ee 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -35,6 +35,16 @@ #include "preferences.h" #include "svg-color.h" #include "svg-icc-color.h" +#include "svg-device-color.h" + +#if ENABLE_LCMS +#include <lcms.h> +#include "color.h" +#include "color-profile.h" +#include "document.h" +#include "inkscape.h" +#include "profile-manager.h" +#endif // ENABLE_LCMS using std::sprintf; @@ -341,9 +351,9 @@ sp_svg_read_color(gchar const *str, gchar const **end_ptr, guint32 dfl) * this check wrapper. */ gchar const *end = str; guint32 const ret = internal_sp_svg_read_color(str, &end, dfl); - assert(ret == dfl && end == str + assert(((ret == dfl) && (end == str)) || (((ret & 0xff) == 0) - && str < end)); + && (str < end))); if (str < end) { gchar *buf = (gchar *) g_malloc(end + 1 - str); memcpy(buf, str, end - str); @@ -454,6 +464,42 @@ sp_svg_create_color_hash() return colors; } +#if ENABLE_LCMS +//helper function borrowed from src/widgets/sp-color-icc-selector.cpp: +void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guint const*& scalies ); + +void icc_color_to_sRGB(SVGICCColor* icc, guchar* r, guchar* g, guchar* b){ + guchar color_out[4]; + guchar color_in[4]; + if (icc){ +g_message("profile name: %s", icc->colorProfile.c_str()); + Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(icc->colorProfile.c_str()); + if ( prof ) { + cmsHTRANSFORM trans = prof->getTransfToSRGB8(); + if ( trans ) { + gchar const** names = 0; + gchar const** tips = 0; + guint const* scales = 0; + getThings( prof->getColorSpace(), names, tips, scales ); + + guint count = _cmsChannelsOf( prof->getColorSpace() ); + if (count>4) count=4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?) + for (guint i=0;i<count; i++){ + color_in[i] = (guchar) ((((gdouble)icc->colors[i])*256.0) * (gdouble)scales[i]); +g_message("input[%d]: %d",i, color_in[i]); + } + + cmsDoTransform( trans, color_in, color_out, 1 ); +g_message("transform to sRGB done"); + } + *r = color_out[0]; + *g = color_out[1]; + *b = color_out[2]; + } + } +} +#endif //ENABLE_LCMS + /* * Some discussion at http://markmail.org/message/bhfvdfptt25kgtmj * Allowed ASCII first characters: ':', 'A'-'Z', '_', 'a'-'z' @@ -536,7 +582,7 @@ bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor while ( g_ascii_isspace(*str) ) { str++; } - good &= *str == ')'; + good &= (*str == ')'); } } @@ -554,6 +600,117 @@ bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor return good; } + +bool sp_svg_read_icc_color( gchar const *str, SVGICCColor* dest ) +{ + return sp_svg_read_icc_color(str, NULL, dest); +} + +bool sp_svg_read_device_color( gchar const *str, gchar const **end_ptr, SVGDeviceColor* dest) +{ + bool good = true; + unsigned int max_colors; + + if ( end_ptr ) { + *end_ptr = str; + } + if ( dest ) { + dest->colors.clear(); + } + + if ( !str ) { + // invalid input + good = false; + } else { + while ( g_ascii_isspace(*str) ) { + str++; + } + + dest->type = DEVICE_COLOR_INVALID; + if (strneq( str, "device-gray(", 12 )){ + dest->type = DEVICE_GRAY; + max_colors=1; + str += 12; + } + + if (strneq( str, "device-rgb(", 11 )){ + dest->type = DEVICE_RGB; + max_colors=3; + str += 11; + } + + if (strneq( str, "device-cmyk(", 12 )){ + dest->type = DEVICE_CMYK; + max_colors=4; + str += 12; + } + + if (strneq( str, "device-nchannel(", 16 )){ + dest->type = DEVICE_NCHANNEL; + max_colors=0; + str += 16; + } + + if ( dest->type != DEVICE_COLOR_INVALID ) { + while ( g_ascii_isspace(*str) ) { + str++; + } + + while ( *str && *str != ')' ) { + if ( g_ascii_isdigit(*str) || *str == '.' || *str == '-' || *str == '+') { + gchar* endPtr = 0; + gdouble dbl = g_ascii_strtod( str, &endPtr ); + if ( !errno ) { + if ( dest ) { + dest->colors.push_back( dbl ); + } + str = endPtr; + } else { + good = false; + break; + } + + while ( g_ascii_isspace(*str) || *str == ',' ) { + str++; + } + } else { + break; + } + } + } + + // We need to have ended on a closing parenthesis + if ( good ) { + while ( g_ascii_isspace(*str) ) { + str++; + } + good &= (*str == ')'); + } + } + + if ( dest->colors.size() == 0) good=false; + if ( dest->type != DEVICE_NCHANNEL && (dest->colors.size() != max_colors)) good=false; + + if ( good ) { + if ( end_ptr ) { + *end_ptr = str; + } + } else { + if ( dest ) { + dest->type = DEVICE_COLOR_INVALID; + dest->colors.clear(); + } + } + + return good; +} + + +bool sp_svg_read_device_color( gchar const *str, SVGDeviceColor* dest) +{ + return sp_svg_read_device_color(str, NULL, dest); +} + /* Local Variables: mode:c++ diff --git a/src/svg/svg-color.h b/src/svg/svg-color.h index 692c1dd00..f4e534652 100644 --- a/src/svg/svg-color.h +++ b/src/svg/svg-color.h @@ -4,12 +4,16 @@ #include <glib/gtypes.h> class SVGICCColor; +class SVGDeviceColor; guint32 sp_svg_read_color(gchar const *str, unsigned int dfl); guint32 sp_svg_read_color(gchar const *str, gchar const **end_ptr, guint32 def); void sp_svg_write_color(char *buf, unsigned int buflen, unsigned int rgba32); bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor* dest ); - +bool sp_svg_read_icc_color( gchar const *str, SVGICCColor* dest ); +bool sp_svg_read_device_color( gchar const *str, gchar const **end_ptr, SVGDeviceColor* dest ); +bool sp_svg_read_device_color( gchar const *str, SVGDeviceColor* dest ); +void icc_color_to_sRGB(SVGICCColor* dest, guchar* r, guchar* g, guchar* b); #endif /* !SVG_SVG_COLOR_H_SEEN */ diff --git a/src/svg/svg-device-color.h b/src/svg/svg-device-color.h new file mode 100644 index 000000000..305133ed3 --- /dev/null +++ b/src/svg/svg-device-color.h @@ -0,0 +1,26 @@ +#ifndef SVG_DEVICE_COLOR_H_SEEN +#define SVG_DEVICE_COLOR_H_SEEN + +#include <string> +#include <vector> + +typedef enum {DEVICE_COLOR_INVALID, DEVICE_GRAY, DEVICE_RGB, DEVICE_CMYK, DEVICE_NCHANNEL} SVGDeviceColorType; + +struct SVGDeviceColor { + SVGDeviceColorType type; + std::vector<double> colors; +}; + + +#endif /* !SVG_DEVICE_COLOR_H_SEEN */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp index 942f74d46..94f1cf312 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -64,6 +64,7 @@ unsigned int sp_svg_number_read_d(gchar const *str, double *val) return 1; } +// TODO must add a buffer length parameter for safety: static unsigned int sp_svg_number_write_ui(gchar *buf, unsigned int val) { unsigned int i = 0; diff --git a/src/text-context.cpp b/src/text-context.cpp index e6f4f083b..fc28dc8e4 100644 --- a/src/text-context.cpp +++ b/src/text-context.cpp @@ -425,11 +425,18 @@ sp_text_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve // find out item under mouse, disregarding groups item_ungrouped = desktop->item_at_point(Geom::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); + + Inkscape::Text::Layout const *layout = te_get_layout(item_ungrouped); + if (layout->inputTruncated()) { + SP_CTRLRECT(tc->indicator)->setColor(0xff0000ff, false, 0); + } else { + SP_CTRLRECT(tc->indicator)->setColor(0x0000ff7f, false, 0); + } Geom::OptRect ibbox = sp_item_bbox_desktop(item_ungrouped); if (ibbox) { SP_CTRLRECT(tc->indicator)->setRectangle(*ibbox); } + sp_canvas_item_show(tc->indicator); event_context->cursor_shape = cursor_text_insert_xpm; event_context->hot_x = 7; @@ -1590,18 +1597,30 @@ sp_text_context_update_cursor(SPTextContext *tc, bool scroll_to_see) Inkscape::Text::Layout const *layout = te_get_layout(tc->text); int const nChars = layout->iteratorToCharIndex(layout->end()); + char *trunc = ""; + bool truncated = false; + if (layout->inputTruncated()) { + truncated = true; + trunc = _(" [truncated]"); + } if (SP_IS_FLOWTEXT(tc->text)) { SPItem *frame = SP_FLOWTEXT(tc->text)->get_frame (NULL); // first frame only if (frame) { + if (truncated) { + SP_CTRLRECT(tc->frame)->setColor(0xff0000ff, false, 0); + } else { + SP_CTRLRECT(tc->frame)->setColor(0x0000ff7f, false, 0); + } sp_canvas_item_show(tc->frame); Geom::OptRect frame_bbox = sp_item_bbox_desktop(frame); if (frame_bbox) { SP_CTRLRECT(tc->frame)->setRectangle(*frame_bbox); } } - SP_EVENT_CONTEXT(tc)->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("Type or edit flowed text (%d characters); <b>Enter</b> to start new paragraph."), nChars); + + SP_EVENT_CONTEXT(tc)->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("Type or edit flowed text (%d characters%s); <b>Enter</b> to start new paragraph."), nChars, trunc); } else { - SP_EVENT_CONTEXT(tc)->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("Type or edit text (%d characters); <b>Enter</b> to start new line."), nChars); + SP_EVENT_CONTEXT(tc)->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("Type or edit text (%d characters%s); <b>Enter</b> to start new line."), nChars, trunc); } } else { diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 2bdee4c10..e93ebdffa 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -1843,6 +1843,37 @@ void sp_te_apply_style(SPItem *text, Inkscape::Text::Layout::iterator const &sta text->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } +bool is_part_of_text_subtree (SPObject *obj) +{ + return (SP_IS_TSPAN(obj) + || SP_IS_TEXT(obj) + || SP_IS_FLOWTEXT(obj) + || SP_IS_FLOWTSPAN(obj) + || SP_IS_FLOWDIV(obj) + || SP_IS_FLOWPARA(obj) + || SP_IS_FLOWLINE(obj) + || SP_IS_FLOWREGIONBREAK(obj)); +} + +bool is_top_level_text_object (SPObject *obj) +{ + return (SP_IS_TEXT(obj) + || SP_IS_FLOWTEXT(obj)); +} + +bool has_visible_text (SPObject *obj) +{ + if (SP_IS_STRING(obj) && !SP_STRING(obj)->string.empty()) + return true; // maybe we should also check that it's not all whitespace? + + for (SPObject const *child = obj->firstChild() ; child ; child = SP_OBJECT_NEXT(child)) { + if (has_visible_text((SPObject *) child)) + return true; + } + + return false; +} + /* Local Variables: mode:c++ diff --git a/src/text-editing.h b/src/text-editing.h index 83ddae77f..7e845dbc9 100644 --- a/src/text-editing.h +++ b/src/text-editing.h @@ -59,4 +59,8 @@ void sp_te_adjust_tspan_letterspacing_screen(SPItem *text, Inkscape::Text::Layou void sp_te_adjust_linespacing_screen(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPDesktop *desktop, gdouble by); void sp_te_apply_style(SPItem *text, Inkscape::Text::Layout::iterator const &start, Inkscape::Text::Layout::iterator const &end, SPCSSAttr const *css); +bool is_part_of_text_subtree (SPObject *obj); +bool is_top_level_text_object (SPObject *obj); +bool has_visible_text (SPObject *obj); + #endif diff --git a/src/transf_mat_3x4.cpp b/src/transf_mat_3x4.cpp index b7cd278d4..6b49dc44a 100644 --- a/src/transf_mat_3x4.cpp +++ b/src/transf_mat_3x4.cpp @@ -115,6 +115,7 @@ TransfMat3x4::pt_to_str (Proj::Axis axis) { return g_strdup(os.str().c_str()); } +/* Check for equality (with a small tolerance epsilon) */ bool TransfMat3x4::operator==(const TransfMat3x4 &rhs) const { @@ -129,29 +130,16 @@ TransfMat3x4::operator==(const TransfMat3x4 &rhs) const return true; } -/* multiply a projective matrix by an affine matrix */ +/* Multiply a projective matrix by an affine matrix (by only multiplying the 'affine part' of the + * projective matrix) */ TransfMat3x4 TransfMat3x4::operator*(Geom::Matrix const &A) const { TransfMat3x4 ret; - // Is it safe to always use the currently active document? - double h = sp_document_height(inkscape_active_document()); - - /* - * Note: The strange multiplication involving the document height is due to the buggy - * intertwining of SVG and document coordinates. Essentially, what we do is first - * convert from "real-world" to SVG coordinates, then apply the transformation A - * (by multiplying with the Geom::Matrix) and then convert back from SVG to real-world - * coordinates. Maybe there is even a more Inkscape-ish way to achieve this? - * Once Inkscape has gotton rid of the two different coordiate systems, we can change - * this function to an ordinary matrix multiplication. - */ for (int j = 0; j < 4; ++j) { - ret.tmat[0][j] = A[0]*tmat[0][j] + A[2]*(h*tmat[2][j] - tmat[1][j]) + A[4]*tmat[2][j]; - ret.tmat[1][j] = A[1]*tmat[0][j] + A[3]*(h*tmat[2][j] - tmat[1][j]) + A[5]*tmat[2][j]; + ret.tmat[0][j] = A[0]*tmat[0][j] + A[2]*tmat[1][j] + A[4]*tmat[2][j]; + ret.tmat[1][j] = A[1]*tmat[0][j] + A[3]*tmat[1][j] + A[5]*tmat[2][j]; ret.tmat[2][j] = tmat[2][j]; - - ret.tmat[1][j] = h*ret.tmat[2][j] - ret.tmat[1][j]; // switch back from SVG to desktop coordinates } return ret; diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index fd1b07394..fac5bad80 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -71,6 +71,8 @@ ink_common_sources += \ ui/dialog/panel-dialog.h \ ui/dialog/print.cpp \ ui/dialog/print.h \ + ui/dialog/print-colors-preview-dialog.cpp \ + ui/dialog/print-colors-preview-dialog.h \ ui/dialog/scriptdialog.cpp \ ui/dialog/scriptdialog.h \ ui/dialog/spray-option.cpp \ diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 7f853bedc..2116d46c3 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -41,6 +41,7 @@ #include "ui/dialog/floating-behavior.h" #include "ui/dialog/dock-behavior.h" #include "ui/dialog/spray-option.h" +#include "ui/dialog/print-colors-preview-dialog.h" #include "preferences.h" #ifdef ENABLE_SVG_FONTS @@ -102,6 +103,7 @@ DialogManager::DialogManager() { registerFactory("LivePathEffect", &create<LivePathEffectEditor, FloatingBehavior>); registerFactory("Memory", &create<Memory, FloatingBehavior>); registerFactory("Messages", &create<Messages, FloatingBehavior>); + registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, FloatingBehavior>); registerFactory("Script", &create<ScriptDialog, FloatingBehavior>); #ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create<SvgFontsDialog, FloatingBehavior>); @@ -129,6 +131,7 @@ DialogManager::DialogManager() { registerFactory("LivePathEffect", &create<LivePathEffectEditor, DockBehavior>); registerFactory("Memory", &create<Memory, DockBehavior>); registerFactory("Messages", &create<Messages, DockBehavior>); + registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, DockBehavior>); registerFactory("Script", &create<ScriptDialog, DockBehavior>); #ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create<SvgFontsDialog, DockBehavior>); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 7e31b874a..982fb3415 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -414,7 +414,8 @@ static void sanitizeName( Glib::ustring& str ) } } -void DocumentProperties::linkSelectedProfile() +void +DocumentProperties::linkSelectedProfile() { //store this profile in the SVG document (create <color-profile> element in the XML) // TODO remove use of 'active' desktop diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index c7f505046..1345ffe55 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -4,7 +4,7 @@ /* Authors: * Nicholas Bishop <nicholasbishop@gmail.org> * Rodrigo Kumpera <kumpera@gmail.com> - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2007 Authors * diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index b217f8695..90516063c 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -741,6 +741,11 @@ void InkscapePreferences::initPageFilters() _page_filters.add_line(true, "", _show_filters_info_box, "", _("Show icons and descriptions for the filter primitives available at the filter effects dialog.")); + /* threaded blur */ //related comments/widgets/functions should be renamed and option should be moved elsewhere when inkscape is fully multi-threaded + _filter_multi_threaded.init("/options/threading/numthreads", 1.0, 8.0, 1.0, 2.0, 4.0, true, false); + _page_filters.add_line( false, _("Number of Threads:"), _filter_multi_threaded, _("(requires restart)"), + _("Configure number of processors/threads to use with rendering of gaussian blur."), false); + this->AddPage(_page_filters, _("Filters"), PREFS_PAGE_FILTERS); } diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 705e7a352..16e62df59 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -171,6 +171,7 @@ protected: PrefRadioButton _blur_quality_best, _blur_quality_better, _blur_quality_normal, _blur_quality_worse, _blur_quality_worst; PrefRadioButton _filter_quality_best, _filter_quality_better, _filter_quality_normal, _filter_quality_worse, _filter_quality_worst; PrefCheckButton _show_filters_info_box; + PrefSpinButton _filter_multi_threaded; PrefCheckButton _trans_scale_stroke, _trans_scale_corner, _trans_gradient,_trans_pattern; PrefRadioButton _trans_optimized, _trans_preserved; diff --git a/src/ui/dialog/print-colors-preview-dialog.cpp b/src/ui/dialog/print-colors-preview-dialog.cpp new file mode 100644 index 000000000..f4d83c271 --- /dev/null +++ b/src/ui/dialog/print-colors-preview-dialog.cpp @@ -0,0 +1,100 @@ +/** @file + * @brief Print Colors Preview dialog - implementation + */ +/* Authors: + * Felipe C. da S. Sanches <juca@members.fsf.org> + * + * Copyright (C) 2009 Authors + * Released under GNU GPLv2 (or later). Read the file 'COPYING' for more information. + */ + +#include "desktop.h" +#include "print-colors-preview-dialog.h" +#include "preferences.h" +#include <glibmm/i18n.h> + +namespace Inkscape { +namespace UI { +namespace Dialog { + +//Yes, I know we shouldn't hardcode CMYK. This class needs to be refactored +// in order to accomodate spot colors and color components defined using +// ICC colors. --Juca + +void PrintColorsPreviewDialog::toggle_cyan(){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/options/printcolorspreview/cyan", cyan->get_active()); + + SPDesktop *desktop = getDesktop(); + desktop->setDisplayModePrintColorsPreview(); +} + +void PrintColorsPreviewDialog::toggle_magenta(){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/options/printcolorspreview/magenta", magenta->get_active()); + + SPDesktop *desktop = getDesktop(); + desktop->setDisplayModePrintColorsPreview(); +} + +void PrintColorsPreviewDialog::toggle_yellow(){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/options/printcolorspreview/yellow", yellow->get_active()); + + SPDesktop *desktop = getDesktop(); + desktop->setDisplayModePrintColorsPreview(); +} + +void PrintColorsPreviewDialog::toggle_black(){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/options/printcolorspreview/black", black->get_active()); + + SPDesktop *desktop = getDesktop(); + desktop->setDisplayModePrintColorsPreview(); +} + +PrintColorsPreviewDialog::PrintColorsPreviewDialog() + : UI::Widget::Panel("", "/dialogs/printcolorspreview", SP_VERB_DIALOG_PRINT_COLORS_PREVIEW) +{ + Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox()); + + cyan = new Gtk::ToggleButton(_("Cyan")); + vbox->pack_start( *cyan, false, false ); +// tips.set_tip((*cyan), _("Render cyan separation")); + cyan->signal_clicked().connect( sigc::mem_fun(*this, &PrintColorsPreviewDialog::toggle_cyan) ); + + magenta = new Gtk::ToggleButton(_("Magenta")); + vbox->pack_start( *magenta, false, false ); +// tips.set_tip((*magenta), _("Render magenta separation")); + magenta->signal_clicked().connect( sigc::mem_fun(*this, &PrintColorsPreviewDialog::toggle_magenta) ); + + yellow = new Gtk::ToggleButton(_("Yellow")); + vbox->pack_start( *yellow, false, false ); +// tips.set_tip((*yellow), _("Render yellow separation")); + yellow->signal_clicked().connect( sigc::mem_fun(*this, &PrintColorsPreviewDialog::toggle_yellow) ); + + black = new Gtk::ToggleButton(_("Black")); + vbox->pack_start( *black, false, false ); +// tips.set_tip((*black), _("Render black separation")); + black->signal_clicked().connect( sigc::mem_fun(*this, &PrintColorsPreviewDialog::toggle_black) ); + + gint val; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + val = prefs->getBool("/options/printcolorspreview/cyan"); + cyan->set_active( val != 0 ); + val = prefs->getBool("/options/printcolorspreview/magenta"); + magenta->set_active( val != 0 ); + val = prefs->getBool("/options/printcolorspreview/yellow"); + yellow->set_active( val != 0 ); + val = prefs->getBool("/options/printcolorspreview/black"); + black->set_active( val != 0 ); + + _getContents()->add(*vbox); + _getContents()->show_all(); +} + +PrintColorsPreviewDialog::~PrintColorsPreviewDialog(){} + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape diff --git a/src/ui/dialog/print-colors-preview-dialog.h b/src/ui/dialog/print-colors-preview-dialog.h new file mode 100644 index 000000000..246908556 --- /dev/null +++ b/src/ui/dialog/print-colors-preview-dialog.h @@ -0,0 +1,48 @@ +/** @file + * @brief Print Colors Preview dialog + */ +/* Authors: + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> + * + * Copyright (C) 2009 Authors + * Released under GNU GPLv2 (or later). Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_DIALOG_PRINT_COLORS_PREVIEW_H +#define INKSCAPE_UI_DIALOG_PRINT_COLORS_PREVIEW_H + +#include "ui/widget/panel.h" +#include "verbs.h" + +#include <gtkmm.h> +#include <gtkmm/box.h> + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class PrintColorsPreviewDialog : public UI::Widget::Panel { +public: + PrintColorsPreviewDialog(); + ~PrintColorsPreviewDialog(); + + static PrintColorsPreviewDialog &getInstance() + { return *new PrintColorsPreviewDialog(); } + +private: + void toggle_cyan(); + void toggle_magenta(); + void toggle_yellow(); + void toggle_black(); + + Gtk::ToggleButton* cyan; + Gtk::ToggleButton* magenta; + Gtk::ToggleButton* yellow; + Gtk::ToggleButton* black; +}; + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + +#endif //#ifndef INKSCAPE_UI_PRINT_COLORS_PREVIEW_H diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index f9db265d6..60cab06a2 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -31,11 +31,15 @@ -static void -draw_page (GtkPrintOperation *operation, - GtkPrintContext *context, - gint /*page_nr*/, - gpointer user_data) +static void draw_page( +#ifdef WIN32 + GtkPrintOperation *operation, +#else + GtkPrintOperation *, +#endif + GtkPrintContext *context, + gint /*page_nr*/, + gpointer user_data) { struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data; //printf("%s %d\n",__FUNCTION__, page_nr); diff --git a/src/ui/dialog/spray-option.cpp b/src/ui/dialog/spray-option.cpp index 8bfe455fa..a9e037381 100644 --- a/src/ui/dialog/spray-option.cpp +++ b/src/ui/dialog/spray-option.cpp @@ -14,11 +14,11 @@ #include "graphlayout/graphlayout.h" #include "inkscape.h" #include "macros.h" -#include "node-context.h" +#include "node-context.h" #include "preferences.h" #include "removeoverlap/removeoverlap.h" #include "selection.h" -#include "shape-editor.h" +#include "shape-editor.h" #include "sp-flowtext.h" #include "sp-item-transform.h" #include "sp-text.h" @@ -43,21 +43,22 @@ namespace Dialog { class Action { public: Action(const Glib::ustring &id, - const Glib::ustring &tiptext, - guint row, guint column, + const Glib::ustring &/*tiptext*/, + guint /*row*/, + guint /*column*/, Gtk::Table &parent, - Gtk::Tooltips &tooltips, + Gtk::Tooltips &/*tooltips*/, SprayOptionClass &dialog): _dialog(dialog), _id(id), _parent(parent) {} - + virtual ~Action(){} virtual void on_button_click(){} SprayOptionClass &_dialog; - + private : - + Glib::ustring _id; Gtk::Table &_parent; }; @@ -85,7 +86,7 @@ public: dialog._Table().set_col_spacings(3); double increm = ((double)_max - (double)_min)/10; - double val_ini = ((double)_max + (double)_min)/2; + double val_ini = ((double)_max + (double)_min)/2; _Gap.set_digits(1); _Gap.set_size_request(60, -1); _Gap.set_increments(increm , 0); @@ -102,14 +103,14 @@ public: virtual void on_button_click(){ if (!_dialog.getDesktop()) return; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - + prefs->setDouble(_pref_path, SP_VERB_CONTEXT_SPRAY); - + double const Gap = _Gap.get_value(); - - + + prefs->setDouble(_pref_path, Gap); sp_document_done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_CONTEXT_SPRAY, @@ -117,7 +118,7 @@ public: } -}; +}; class ActionF : public Action { private: @@ -143,7 +144,7 @@ public: { dialog.F_Table().set_col_spacings(3); - _Label.set_label(id); + _Label.set_label(id); _Gap1.set_digits(1); _Gap1.set_size_request(60, -1); @@ -152,7 +153,7 @@ public: _Gap1.set_value(1); dialog.tooltips().set_tip(_Gap1, _("Minimum")); - + _Label1.set_label(Q_("Min")); _Gap2.set_digits(1); @@ -162,11 +163,11 @@ public: _Gap2.set_value(1); dialog.tooltips().set_tip(_Gap2, _("Maximum")); - + _Label2.set_label(_("Max:")); - + _Gap1.signal_changed().connect(sigc::mem_fun(*this, &ActionF::on_button_click)); - _Gap2.signal_changed().connect(sigc::mem_fun(*this, &ActionF::on_button_click)); + _Gap2.signal_changed().connect(sigc::mem_fun(*this, &ActionF::on_button_click)); dialog.F_Table().attach(_Label, column, column+1, row, row+1, Gtk::FILL, Gtk::FILL); dialog.F_Table().attach(_Label1, column+1, column+2, row, row+1, Gtk::FILL, Gtk::FILL); @@ -178,15 +179,15 @@ public: virtual void on_button_click(){ if (!_dialog.getDesktop()) return; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - + prefs->setDouble(_pref1_path, SP_VERB_CONTEXT_SPRAY); prefs->setDouble(_pref2_path, SP_VERB_CONTEXT_SPRAY); - + double const Gap1 = _Gap1.get_value(); double const Gap2 = _Gap2.get_value(); - + prefs->setDouble(_pref1_path, Gap1); prefs->setDouble(_pref2_path, Gap2); @@ -195,21 +196,21 @@ public: } -}; +}; void SprayOptionClass::combo_action() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); cout<<"combo.get_active_row_number = "<<_combo.get_active_row_number()<<endl; - + int const distrib = _combo.get_active_row_number(); - + prefs->setInt("/tools/spray/distribution", distrib); - + sp_document_done(sp_desktop_document(this->getDesktop()), SP_VERB_CONTEXT_SPRAY, - _("Remove overlaps")); + _("Remove overlaps")); } @@ -217,11 +218,9 @@ void SprayOptionClass::combo_action() { void SprayOptionClass::action() { - int r=1; - for (list<Action *>::iterator it = _actionList.begin(); - it != _actionList.end(); - it ++) + for (list<Action *>::iterator it = _actionList.begin(); it != _actionList.end(); ++it) { (*it)->on_button_click(); + } combo_action(); } @@ -242,24 +241,41 @@ void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selecti SprayOptionClass::SprayOptionClass() : UI::Widget::Panel ("", "/dialogs/spray", SP_VERB_DIALOG_SPRAY_OPTION), - _distributionFrame(_("Distribution")), - _Frame(_("Cursor Options")), - _FFrame(_("Random Options")), + _actionList(), + _distributionFrame(Q_("sprayOptions|Distribution")), + _Frame(Q_("sprayOptions|Cursor Options")), + _FFrame(Q_("sprayOptions|Random Options")), + _distributionTable(), _gaussianTable(1, 5, false), _ETable(3,2,false), _FTable(2,5,false), - _unifLabel(_("Uniform")), - _gaussLabel(_("Gaussian ")), - _anchorLabel(_("Distribution : ")) - + _anchorBox(), + _unifBox(), + _gaussianBox(), + _HBox(), + _FHBox(), + _BoutonBox(), + _distributionBox(), + _VBox(), + _FVBox(), + _ActionBox(), + _anchorLabel(Q_("sprayOptions|Distribution:")), + _unifLabel(Q_("sprayOptions|Uniform")), + _gaussLabel(Q_("sprayOptions|Gaussian")), + _Label(), + _FLabel(), + _unif(), + _gauss(), + _combo(), + _tooltips() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); //ComboBoxText - _combo.append_text(_("Uniforme")); - _combo.append_text(_("Gaussienne")); - + _combo.append_text(Q_("sprayOptions|Uniform")); + _combo.append_text(Q_("sprayOptions|Gaussian")); + _combo.set_active(prefs->getInt("/tools/spray/distribution", 1)); _combo.signal_changed().connect(sigc::mem_fun(*this, &SprayOptionClass::combo_action)); @@ -274,19 +290,19 @@ SprayOptionClass::SprayOptionClass() //Hbox Random - addFButton(_("Scale : ") ,_("Applique un facteur d'échelle"), 0, 0, "/tools/spray/scale_min","/tools/spray/scale_max"); - addFButton(_("Rotation : ") ,_("Fait tourner"), 1, 0, "/tools/spray/rot_min","/tools/spray/rot_max"); + addFButton(Q_("sprayOptions|Scale:") ,_("Apply a scale factor"), 0, 0, "/tools/spray/scale_min","/tools/spray/scale_max"); + addFButton(Q_("sprayOptions|Rotation:") ,_("Apply rotation"), 1, 0, "/tools/spray/rot_min","/tools/spray/rot_max"); _FHBox.pack_start(_FLabel); _FHBox.pack_start(_FTable); //Implementation dans la Vbox Cursor _FVBox.pack_start(_FHBox); - _FFrame.add(_FVBox); + _FFrame.add(_FVBox); //Hbox Cursor - addEButton(_("Ratio : ") ,_("Excentricité de l'ellipse"), 0, 0, 0, 1,"/tools/spray/ratio"); - addEButton(_("Angle : ") ,_("Angle de l'ellipse"), 1, 0, 0, 5,"/tools/spray/tilt"); - addEButton(_("Width : ") ,_("Taille de l'ellipse"), 2, 0, 0, 1,"/tools/spray/width"); + addEButton(Q_("sprayOptions|Ratio:") ,_("Eccentricity of the ellipse"), 0, 0, 0, 1,"/tools/spray/ratio"); + addEButton(Q_("sprayOptions|Angle:") ,_("Angle of the ellipse"), 1, 0, 0, 5,"/tools/spray/tilt"); + addEButton(Q_("sprayOptions|Width:") ,_("Size of the ellipse"), 2, 0, 0, 1,"/tools/spray/width"); _HBox.pack_start(_Label); _HBox.pack_start(_ETable); @@ -297,26 +313,26 @@ SprayOptionClass::SprayOptionClass() Gtk::Box *contents = _getContents(); contents->set_spacing(4); - - - + + + // Crée dans l'ordre suivant les différentes Frames (cadres de réglages) contents->pack_start(_distributionFrame, true, true); - contents->pack_start(_FFrame, true, true); + contents->pack_start(_FFrame, true, true); contents->pack_start(_Frame, true, true); - - + + // Connect to the global selection change, to invalidate cached randomize_bbox g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); randomize_bbox = Geom::OptRect(); show_all_children(); - - + + } @@ -342,7 +358,7 @@ void SprayOptionClass::addEButton(const Glib::ustring &id, const Glib::ustring &tiptext, guint row, guint column, guint min, guint max, - Glib::ustring const &pref_path) + Glib::ustring const &pref_path) { _actionList.push_back( new ActionE(id, tiptext,row, column,*this,min ,max, pref_path )); } @@ -351,7 +367,7 @@ void SprayOptionClass::addFButton(const Glib::ustring &id, const Glib::ustring &tiptext, guint row, guint column, Glib::ustring const &pref1_path, - Glib::ustring const &pref2_path) + Glib::ustring const &pref2_path) { _actionList.push_back( new ActionF(id, tiptext,row, column,*this,pref1_path, pref2_path )); } diff --git a/src/ui/dialog/spray-option.h b/src/ui/dialog/spray-option.h index 75dfe1e35..42090a120 100644 --- a/src/ui/dialog/spray-option.h +++ b/src/ui/dialog/spray-option.h @@ -33,11 +33,11 @@ #include "graphlayout/graphlayout.h" #include "inkscape.h" #include "macros.h" -#include "node-context.h" +#include "node-context.h" #include "preferences.h" #include "removeoverlap/removeoverlap.h" #include "selection.h" -#include "shape-editor.h" +#include "shape-editor.h" #include "sp-flowtext.h" #include "sp-item-transform.h" #include "sp-text.h" @@ -71,19 +71,19 @@ private: SprayOptionClass(SprayOptionClass const &d); SprayOptionClass& operator=(SprayOptionClass const &d); - + public: SprayOptionClass(); - virtual ~SprayOptionClass(); + virtual ~SprayOptionClass(); void test() { cout<<"appel de test !!"<<endl; } static SprayOptionClass &getInstance() { return *new SprayOptionClass(); } - + Gtk::Table &_Table(){return _ETable;} Gtk::Table &F_Table(){return _FTable;} Gtk::Tooltips &tooltips(){return _tooltips;} void action(); - void combo_action(); + void combo_action(); Geom::OptRect randomize_bbox; SprayOptionClass &get_SprayOptionClass(); @@ -97,17 +97,32 @@ protected: const Glib::ustring &pref1_path, const Glib::ustring &pref2_path); std::list<Action *> _actionList; - Gtk::Frame _distributionFrame, _Frame, _FFrame ; - Gtk::Table _distributionTable, _gaussianTable, _ETable, _FTable; + Gtk::Frame _distributionFrame; + Gtk::Frame _Frame; + Gtk::Frame _FFrame; + Gtk::Table _distributionTable; + Gtk::Table _gaussianTable; + Gtk::Table _ETable; + Gtk::Table _FTable; Gtk::HBox _anchorBox; - Gtk::HBox _unifBox, _gaussianBox, _HBox, _FHBox, _BoutonBox; - Gtk::VBox _distributionBox, _VBox, _FVBox, _ActionBox; + Gtk::HBox _unifBox; + Gtk::HBox _gaussianBox; + Gtk::HBox _HBox; + Gtk::HBox _FHBox; + Gtk::HBox _BoutonBox; + Gtk::VBox _distributionBox; + Gtk::VBox _VBox; + Gtk::VBox _FVBox; + Gtk::VBox _ActionBox; Gtk::Label _anchorLabel; - Gtk::Label _unifLabel, _gaussLabel, _Label, _FLabel; - Gtk::CheckButton _unif, _gauss; + Gtk::Label _unifLabel; + Gtk::Label _gaussLabel; + Gtk::Label _Label; + Gtk::Label _FLabel; + Gtk::CheckButton _unif; + Gtk::CheckButton _gauss; Gtk::ComboBoxText _combo; Gtk::Tooltips _tooltips; - }; diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 5f86196b1..cb22e029b 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -2,7 +2,7 @@ * @brief SVG Fonts dialog - implementation */ /* Authors: - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Authors * Released under GNU GPLv2 (or later). Read the file 'COPYING' for more information. diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h index e6042ed42..e819187a1 100644 --- a/src/ui/dialog/svg-fonts-dialog.h +++ b/src/ui/dialog/svg-fonts-dialog.h @@ -2,7 +2,7 @@ * @brief SVG Fonts dialog */ /* Authors: - * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * Felipe Corrêa da Silva Sanches <juca@members.fsf.org> * * Copyright (C) 2008 Authors * Released under GNU GPLv2 (or later). Read the file 'COPYING' for more information. diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 1f708e3de..450d4202d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -47,7 +47,7 @@ #include "display/nr-plain-stuff.h" #include "sp-gradient-reference.h" -//#define USE_DOCUMENT_PALETTE 1 +#define USE_DOCUMENT_PALETTE 1 namespace Inkscape { namespace UI { diff --git a/src/ui/widget/spin-slider.cpp b/src/ui/widget/spin-slider.cpp index b610c1ee6..e3e73a51f 100644 --- a/src/ui/widget/spin-slider.cpp +++ b/src/ui/widget/spin-slider.cpp @@ -3,7 +3,7 @@ * * Author: * Nicholas Bishop <nicholasbishop@gmail.com> - * Felipe C. da S. Sanches <felipe.sanches@gmail.com> + * Felipe C. da S. Sanches <juca@members.fsf.org> * * Copyright (C) 2007 Author * diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index ab46b21a6..78ceec467 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -103,7 +103,7 @@ vp_knot_moved_handler (SPKnot */*knot*/, Geom::Point const *ppointer, guint stat sel_boxes = (*vp)->selectedBoxes(sp_desktop_selection(inkscape_active_desktop())); // we create a new perspective ... - Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp); + Persp3D *new_persp = persp3d_create_xml_element (dragger->parent->document, old_persp->perspective_impl); /* ... unlink the boxes from the old one and FIXME: We need to unlink the _un_selected boxes of each VP so that @@ -230,7 +230,7 @@ unsigned int VanishingPoint::global_counter = 0; void VanishingPoint::set_pos(Proj::Pt2 const &pt) { g_return_if_fail (_persp); - _persp->tmat.set_image_pt (_axis, pt); + _persp->perspective_impl->tmat.set_image_pt (_axis, pt); } std::list<SPBox3D *> diff --git a/src/verbs.cpp b/src/verbs.cpp index 56b63e95e..6f86c3cce 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1749,6 +1749,9 @@ ZoomVerb::perform(SPAction *action, void *data, void */*pdata*/) case SP_VERB_VIEW_MODE_OUTLINE: dt->setDisplayModeOutline(); break; + case SP_VERB_VIEW_MODE_PRINT_COLORS_PREVIEW: + dt->setDisplayModePrintColorsPreview(); + break; case SP_VERB_VIEW_MODE_TOGGLE: dt->displayModeToggle(); break; @@ -1871,6 +1874,9 @@ DialogVerb::perform(SPAction *action, void *data, void */*pdata*/) case SP_VERB_DIALOG_SVG_FONTS: dt->_dlg_mgr->showDialog("SvgFontsDialog"); break; + case SP_VERB_DIALOG_PRINT_COLORS_PREVIEW: + dt->_dlg_mgr->showDialog("PrintColorsPreviewDialog"); + break; default: break; } @@ -2626,6 +2632,8 @@ Verb *Verb::_base_verbs[] = { N_("Switch to normal display without filters"), NULL), new ZoomVerb(SP_VERB_VIEW_MODE_OUTLINE, "ViewModeOutline", N_("_Outline"), N_("Switch to outline (wireframe) display mode"), NULL), + new ZoomVerb(SP_VERB_VIEW_MODE_PRINT_COLORS_PREVIEW, "ViewModePrintColorsPreview", N_("_Print Colors Preview"), + N_("Switch to print colors preview mode"), NULL), new ZoomVerb(SP_VERB_VIEW_MODE_TOGGLE, "ViewModeToggle", N_("_Toggle"), N_("Toggle between normal and outline display modes"), NULL), @@ -2701,6 +2709,8 @@ Verb *Verb::_base_verbs[] = { N_("Manage, edit, and apply SVG filters"), NULL), new DialogVerb(SP_VERB_DIALOG_SVG_FONTS, "DialogSVGFonts", N_("SVG Font Editor..."), N_("Edit SVG fonts"), NULL), + new DialogVerb(SP_VERB_DIALOG_PRINT_COLORS_PREVIEW, "DialogPrintColorsPreview", N_("Print Colors..."), + N_("Select which color separations to render in Print Colors Preview rendermode"), NULL), /* Help */ new HelpVerb(SP_VERB_HELP_ABOUT_EXTENSIONS, "HelpAboutExtensions", N_("About E_xtensions"), diff --git a/src/verbs.h b/src/verbs.h index 3ea2fdee8..d0abcdca2 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -214,6 +214,7 @@ enum { SP_VERB_VIEW_MODE_NORMAL, SP_VERB_VIEW_MODE_NO_FILTERS, SP_VERB_VIEW_MODE_OUTLINE, + SP_VERB_VIEW_MODE_PRINT_COLORS_PREVIEW, SP_VERB_VIEW_MODE_TOGGLE, SP_VERB_VIEW_CMS_TOGGLE, SP_VERB_VIEW_ICON_PREVIEW, @@ -251,6 +252,7 @@ enum { SP_VERB_DIALOG_LIVE_PATH_EFFECT, SP_VERB_DIALOG_FILTER_EFFECTS, SP_VERB_DIALOG_SVG_FONTS, + SP_VERB_DIALOG_PRINT_COLORS_PREVIEW, /* Help */ SP_VERB_HELP_ABOUT_EXTENSIONS, SP_VERB_HELP_MEMORY, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index e3bf1ae9c..b63992afe 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -613,12 +613,20 @@ SPDesktopWidget::updateTitle(gchar const* uri) if (this->desktop->number > 1) { if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { g_string_printf (name, _("%s: %d (outline) - Inkscape"), fname, this->desktop->number); + } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { + g_string_printf (name, _("%s: %d (no filters) - Inkscape"), fname, this->desktop->number); + } else if (this->desktop->getMode() == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW) { + g_string_printf (name, _("%s: %d (print colors preview) - Inkscape"), fname, this->desktop->number); } else { g_string_printf (name, _("%s: %d - Inkscape"), fname, this->desktop->number); } } else { if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { g_string_printf (name, _("%s (outline) - Inkscape"), fname); + } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { + g_string_printf (name, _("%s (no filters) - Inkscape"), fname); + } else if (this->desktop->getMode() == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW) { + g_string_printf (name, _("%s (print colors preview) - Inkscape"), fname); } else { g_string_printf (name, _("%s - Inkscape"), fname); } diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 5824b102c..743502d27 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -714,7 +714,7 @@ int sp_icon_get_phys_size(int size) static int lastSys[Inkscape::ICON_SIZE_DECORATION + 1]; static int vals[Inkscape::ICON_SIZE_DECORATION + 1]; - size = CLAMP( size, GTK_ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION ); + size = CLAMP( size, static_cast<int>(GTK_ICON_SIZE_MENU), static_cast<int>(Inkscape::ICON_SIZE_DECORATION) ); if ( !sizeMapDone ) { injectCustomSize(); diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index c90b55e73..c70d96991 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -727,6 +727,7 @@ sp_vruler_size_allocate (GtkWidget *widget, GtkAllocation *allocation) // code, those warnings are actually desired. They say "Hey! Fix this". We // definitely don't want to hide/ignore them. --JonCruz +// TODO address const/non-const gchar* issue: /// Ruler metrics. static GtkRulerMetric const sp_ruler_metrics[] = { // NOTE: the order of records in this struct must correspond to the SPMetric enum. diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index a10d2380c..3b4b6b711 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -17,12 +17,12 @@ #include "inkscape.h" #include "profile-manager.h" -#define noDEBUG_LCMS +#define DEBUG_LCMS #if ENABLE_LCMS #include "color-profile-fns.h" #include "color-profile.h" -//#define DEBUG_LCMS + #ifdef DEBUG_LCMS #include "preferences.h" #include <gtk/gtkmessagedialog.h> @@ -603,7 +603,7 @@ void ColorICCSelector::_profilesChanged( std::string const & name ) void ColorICCSelector::_colorChanged() { _updating = TRUE; -// sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color ); + //sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color ); #ifdef DEBUG_LCMS g_message( "/^^^^^^^^^ %p::_colorChanged(%08x:%s)", this, diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 779895de4..3ba39dd30 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -32,6 +32,10 @@ #include "sp-color-scales.h" #include "sp-color-icc-selector.h" #include "sp-color-wheel-selector.h" +#include "svg/svg-icc-color.h" +#include "../inkscape.h" +#include "../document.h" +#include "../profile-manager.h" struct SPColorNotebookTracker { const gchar* name; @@ -324,9 +328,37 @@ void ColorNotebook::init() row++; - /* Create RGBA entry and color preview */ GtkWidget *rgbabox = gtk_hbox_new (FALSE, 0); +#if ENABLE_LCMS + /* Create color management icons */ + _box_colormanaged = gtk_event_box_new (); + GtkWidget *colormanaged = gtk_image_new_from_icon_name ("color-management-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_container_add (GTK_CONTAINER (_box_colormanaged), colormanaged); + GtkTooltips *tooltips_colormanaged = gtk_tooltips_new (); + gtk_tooltips_set_tip (tooltips_colormanaged, _box_colormanaged, _("Color Managed"), ""); + gtk_widget_set_sensitive (_box_colormanaged, false); + gtk_box_pack_start(GTK_BOX(rgbabox), _box_colormanaged, FALSE, FALSE, 2); + + _box_outofgamut = gtk_event_box_new (); + GtkWidget *outofgamut = gtk_image_new_from_icon_name ("out-of-gamut-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_container_add (GTK_CONTAINER (_box_outofgamut), outofgamut); + GtkTooltips *tooltips_outofgamut = gtk_tooltips_new (); + gtk_tooltips_set_tip (tooltips_outofgamut, _box_outofgamut, _("Out of gamut!"), ""); + gtk_widget_set_sensitive (_box_outofgamut, false); + gtk_box_pack_start(GTK_BOX(rgbabox), _box_outofgamut, FALSE, FALSE, 2); + + _box_toomuchink = gtk_event_box_new (); + GtkWidget *toomuchink = gtk_image_new_from_icon_name ("too-much-ink-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_container_add (GTK_CONTAINER (_box_toomuchink), toomuchink); + GtkTooltips *tooltips_toomuchink = gtk_tooltips_new (); + gtk_tooltips_set_tip (tooltips_toomuchink, _box_toomuchink, _("Too much ink!"), ""); + gtk_widget_set_sensitive (_box_toomuchink, false); + gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2); + +#endif //ENABLE_LCMS + + /* Create RGBA entry and color preview */ _rgbal = gtk_label_new_with_mnemonic (_("RGBA_:")); gtk_misc_set_alignment (GTK_MISC (_rgbal), 1.0, 0.5); gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2); @@ -341,7 +373,13 @@ void ColorNotebook::init() sp_set_font_size_smaller (rgbabox); gtk_widget_show_all (rgbabox); - gtk_table_attach (GTK_TABLE (table), rgbabox, 1, 2, row, row + 1, GTK_FILL, GTK_SHRINK, XPAD, YPAD); + +#if ENABLE_LCMS + //the "too much ink" icon is initially hidden + gtk_widget_hide(GTK_WIDGET(_box_toomuchink)); +#endif //ENABLE_LCMS + + gtk_table_attach (GTK_TABLE (table), rgbabox, 0, 2, row, row + 1, GTK_FILL, GTK_SHRINK, XPAD, YPAD); #ifdef SPCS_PREVIEW _p = sp_color_preview_new (0xffffffff); @@ -485,6 +523,40 @@ void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) { g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); +#if ENABLE_LCMS + /* update color management icon*/ + gtk_widget_set_sensitive (_box_colormanaged, color.icc != NULL); + + /* update out-of-gamut icon */ + gtk_widget_set_sensitive (_box_outofgamut, false); + if (color.icc){ + Inkscape::ColorProfile* target_profile = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); + if ( target_profile ) + gtk_widget_set_sensitive (_box_outofgamut, target_profile->GamutCheck(color)); + } + + /* update too-much-ink icon */ + gtk_widget_set_sensitive (_box_toomuchink, false); + if (color.icc){ + Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); + if (prof->getColorSpace() == icSigCmykData || prof->getColorSpace() == icSigCmyData){ + gtk_widget_show(GTK_WIDGET(_box_toomuchink)); + double ink_sum = 0; + for (unsigned int i=0; i<color.icc->colors.size(); i++){ + ink_sum += color.icc->colors[i]; + } + + /* Some literature states that when the sum of paint values exceed 320%, it is considered to be a satured color, + which means the paper can get too wet due to an excessive ammount of ink. This may lead to several issues + such as misalignment and poor quality of printing in general.*/ + if ( ink_sum > 3.2 ) + gtk_widget_set_sensitive (_box_toomuchink, true); + } else { + gtk_widget_hide(GTK_WIDGET(_box_toomuchink)); + } + } +#endif //ENABLE_LCMS + if ( !_updatingrgba ) { gchar s[32]; diff --git a/src/widgets/sp-color-notebook.h b/src/widgets/sp-color-notebook.h index bf6fb1002..5eb29ac73 100644 --- a/src/widgets/sp-color-notebook.h +++ b/src/widgets/sp-color-notebook.h @@ -61,6 +61,9 @@ protected: gulong _entryId; GtkWidget *_book; GtkWidget *_rgbal, *_rgbae; /* RGBA entry */ +#if ENABLE_LCMS + GtkWidget *_box_outofgamut, *_box_colormanaged, *_box_toomuchink; +#endif //ENABLE_LCMS GtkWidget *_p; /* Color preview */ GtkWidget *_btn; GtkWidget *_popup; diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp index cf06247e7..e41b81e5c 100644 --- a/src/widgets/sp-color-scales.cpp +++ b/src/widgets/sp-color-scales.cpp @@ -10,6 +10,8 @@ #include <glibmm/i18n.h> #include "../dialogs/dialog-events.h" #include "sp-color-scales.h" +#include "svg/svg-icc-color.h" +#include "svg/svg-device-color.h" #define CSC_CHANNEL_R (1 << 0) #define CSC_CHANNEL_G (1 << 1) @@ -230,6 +232,12 @@ void ColorScales::_recalcColor( gboolean changing ) case SP_COLOR_SCALES_MODE_CMYK: { _getCmykaFloatv( c ); + color.device = new SVGDeviceColor(); + color.device->type=DEVICE_CMYK; + color.device->colors.clear(); + for (int i=0;i<4;i++){ + color.device->colors.push_back(c[i]); + } float rgb[3]; sp_color_cmyk_to_rgb_floatv( rgb, c[0], c[1], c[2], c[3] ); @@ -241,6 +249,10 @@ void ColorScales::_recalcColor( gboolean changing ) g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode); break; } + + /* Preserve ICC */ + color.icc = _color.icc ? new SVGICCColor(*_color.icc) : 0; + _updateInternals( color, alpha, _dragging ); } else @@ -470,11 +482,20 @@ void ColorScales::setMode(SPColorScalesMode mode) gtk_widget_show (_s[4]); gtk_widget_show (_b[4]); _updating = TRUE; - sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]); - setScaled( _a[0], c[0] ); - setScaled( _a[1], c[1] ); - setScaled( _a[2], c[2] ); - setScaled( _a[3], c[3] ); + + if (_color.device && _color.device->type == DEVICE_CMYK){ + setScaled( _a[0], _color.device->colors[0] ); + setScaled( _a[1], _color.device->colors[1] ); + setScaled( _a[2], _color.device->colors[2] ); + setScaled( _a[3], _color.device->colors[3] ); + } else { + //If we still dont have a device-color, convert from rbga + sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]); + setScaled( _a[0], c[0] ); + setScaled( _a[1], c[1] ); + setScaled( _a[2], c[2] ); + setScaled( _a[3], c[3] ); + } setScaled( _a[4], rgba[3] ); _updating = FALSE; _updateSliders( CSC_CHANNELS_ALL ); diff --git a/src/widgets/sp-color-wheel-selector.cpp b/src/widgets/sp-color-wheel-selector.cpp index 174b071f9..6012f4e20 100644 --- a/src/widgets/sp-color-wheel-selector.cpp +++ b/src/widgets/sp-color-wheel-selector.cpp @@ -10,7 +10,8 @@ #include "../dialogs/dialog-events.h" #include "sp-color-wheel-selector.h" #include "sp-color-scales.h" - +#include "sp-color-icc-selector.h" +#include "../svg/svg-icc-color.h" G_BEGIN_DECLS @@ -205,6 +206,11 @@ sp_color_wheel_selector_new (void) /* Helpers for setting color value */ +static void preserve_icc(SPColor *color, SPColorWheelSelector *cs){ + ColorSelector* selector = (ColorSelector*)(SP_COLOR_SELECTOR(cs)->base); + color->icc = selector->getColor().icc ? new SVGICCColor(*selector->getColor().icc) : 0; +} + void ColorWheelSelector::_colorChanged() { #ifdef DUMP_CHANGE_INFO @@ -237,6 +243,7 @@ void ColorWheelSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorW wheelSelector->_updating = TRUE; + preserve_icc(&wheelSelector->_color, cs); wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); wheelSelector->_updating = FALSE; @@ -249,6 +256,8 @@ void ColorWheelSelector::_sliderGrabbed( SPColorSlider *slider, SPColorWheelSele if (!wheelSelector->_dragging) { wheelSelector->_dragging = TRUE; wheelSelector->_grabbed(); + + preserve_icc(&wheelSelector->_color, cs); wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); } } @@ -260,6 +269,8 @@ void ColorWheelSelector::_sliderReleased( SPColorSlider *slider, SPColorWheelSel if (wheelSelector->_dragging) { wheelSelector->_dragging = FALSE; wheelSelector->_released(); + + preserve_icc(&wheelSelector->_color, cs); wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); } } @@ -269,6 +280,7 @@ void ColorWheelSelector::_sliderChanged( SPColorSlider *slider, SPColorWheelSele (void)slider; ColorWheelSelector* wheelSelector = (ColorWheelSelector*)(SP_COLOR_SELECTOR(cs)->base); + preserve_icc(&wheelSelector->_color, cs); wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); } @@ -285,6 +297,7 @@ void ColorWheelSelector::_wheelChanged( SPColorWheel *wheel, SPColorWheelSelecto sp_color_slider_set_colors (SP_COLOR_SLIDER(wheelSelector->_slider), start, mid, end); + preserve_icc(&color, cs); wheelSelector->_updateInternals( color, wheelSelector->_alpha, sp_color_wheel_is_adjusting( wheel ) ); } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index b10c60c79..02cd0b478 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -926,11 +926,11 @@ sp_commands_toolbox_new() GtkWidget * sp_snap_toolbox_new() { - GtkWidget *tb = gtk_vbox_new(FALSE, 0); - gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING); - g_object_set_data(G_OBJECT(tb), "desktop", NULL); + GtkWidget *tb = gtk_vbox_new(FALSE, 0); + gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING); + g_object_set_data(G_OBJECT(tb), "desktop", NULL); - //GtkWidget *tb = gtk_toolbar_new(); + //GtkWidget *tb = gtk_toolbar_new(); //g_object_set_data(G_OBJECT(tb), "desktop", NULL); gtk_widget_set_sensitive(tb, FALSE); @@ -1904,314 +1904,314 @@ update_commands_toolbox(SPDesktop */*desktop*/, SPEventContext */*eventcontext*/ void toggle_snap_callback (GtkToggleAction *act, gpointer data) { //data points to the toolbox - if (g_object_get_data(G_OBJECT(data), "freeze" )) { - return; - } - - gpointer ptr = g_object_get_data(G_OBJECT(data), "desktop"); - g_assert(ptr != NULL); - - SPDesktop *dt = reinterpret_cast<SPDesktop*>(ptr); - SPNamedView *nv = sp_desktop_namedview(dt); - SPDocument *doc = SP_OBJECT_DOCUMENT(nv); - - if (dt == NULL || nv == NULL) { - g_warning("No desktop or namedview specified (in toggle_snap_callback)!"); - return; - } - - Inkscape::XML::Node *repr = SP_OBJECT_REPR(nv); - - if (repr == NULL) { - g_warning("This namedview doesn't have a xml representation attached!"); - return; - } - - bool saved = sp_document_get_undo_sensitive(doc); - sp_document_set_undo_sensitive(doc, false); - - bool v = false; - SPAttributeEnum attr = (SPAttributeEnum) GPOINTER_TO_INT(g_object_get_data(G_OBJECT(act), "SP_ATTR_INKSCAPE")); - - switch (attr) { - case SP_ATTR_INKSCAPE_SNAP_GLOBAL: - dt->toggleSnapGlobal(); - break; - case SP_ATTR_INKSCAPE_SNAP_BBOX: - v = nv->snap_manager.snapprefs.getSnapModeBBox(); - sp_repr_set_boolean(repr, "inkscape:snap-bbox", !v); - break; - case SP_ATTR_INKSCAPE_BBOX_PATHS: - v = nv->snap_manager.snapprefs.getSnapToBBoxPath(); - sp_repr_set_boolean(repr, "inkscape:bbox-paths", !v); - break; - case SP_ATTR_INKSCAPE_BBOX_NODES: - v = nv->snap_manager.snapprefs.getSnapToBBoxNode(); - sp_repr_set_boolean(repr, "inkscape:bbox-nodes", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_NODES: - v = nv->snap_manager.snapprefs.getSnapModeNode(); - sp_repr_set_boolean(repr, "inkscape:snap-nodes", !v); - break; - case SP_ATTR_INKSCAPE_OBJECT_PATHS: - v = nv->snap_manager.snapprefs.getSnapToItemPath(); - sp_repr_set_boolean(repr, "inkscape:object-paths", !v); - break; - case SP_ATTR_INKSCAPE_OBJECT_NODES: - v = nv->snap_manager.snapprefs.getSnapToItemNode(); - sp_repr_set_boolean(repr, "inkscape:object-nodes", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES: - v = nv->snap_manager.snapprefs.getSnapSmoothNodes(); - sp_repr_set_boolean(repr, "inkscape:snap-smooth-nodes", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS: - v = nv->snap_manager.snapprefs.getSnapIntersectionCS(); - sp_repr_set_boolean(repr, "inkscape:snap-intersection-paths", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_CENTER: - v = nv->snap_manager.snapprefs.getIncludeItemCenter(); - sp_repr_set_boolean(repr, "inkscape:snap-center", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_GRIDS: - v = nv->snap_manager.snapprefs.getSnapToGrids(); - sp_repr_set_boolean(repr, "inkscape:snap-grids", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_TO_GUIDES: - v = nv->snap_manager.snapprefs.getSnapToGuides(); - sp_repr_set_boolean(repr, "inkscape:snap-to-guides", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_PAGE: - v = nv->snap_manager.snapprefs.getSnapToPageBorder(); - sp_repr_set_boolean(repr, "inkscape:snap-page", !v); - break; - /*case SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE: - v = nv->snap_manager.snapprefs.getSnapIntersectionGG(); - sp_repr_set_boolean(repr, "inkscape:snap-intersection-grid-guide", !v); - break;*/ - case SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS: - v = nv->snap_manager.snapprefs.getSnapLineMidpoints(); - sp_repr_set_boolean(repr, "inkscape:snap-midpoints", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS: - v = nv->snap_manager.snapprefs.getSnapObjectMidpoints(); - sp_repr_set_boolean(repr, "inkscape:snap-object-midpoints", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS: - v = nv->snap_manager.snapprefs.getSnapBBoxEdgeMidpoints(); - sp_repr_set_boolean(repr, "inkscape:snap-bbox-edge-midpoints", !v); - break; - case SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS: - v = nv->snap_manager.snapprefs.getSnapBBoxMidpoints(); - sp_repr_set_boolean(repr, "inkscape:snap-bbox-midpoints", !v); - break; - default: - g_warning("toggle_snap_callback has been called with an ID for which no action has been defined"); - break; - } - - // The snapping preferences are stored in the document, and therefore toggling makes the document dirty - doc->setModifiedSinceSave(); - - sp_document_set_undo_sensitive(doc, saved); + if (g_object_get_data(G_OBJECT(data), "freeze" )) { + return; + } + + gpointer ptr = g_object_get_data(G_OBJECT(data), "desktop"); + g_assert(ptr != NULL); + + SPDesktop *dt = reinterpret_cast<SPDesktop*>(ptr); + SPNamedView *nv = sp_desktop_namedview(dt); + SPDocument *doc = SP_OBJECT_DOCUMENT(nv); + + if (dt == NULL || nv == NULL) { + g_warning("No desktop or namedview specified (in toggle_snap_callback)!"); + return; + } + + Inkscape::XML::Node *repr = SP_OBJECT_REPR(nv); + + if (repr == NULL) { + g_warning("This namedview doesn't have a xml representation attached!"); + return; + } + + bool saved = sp_document_get_undo_sensitive(doc); + sp_document_set_undo_sensitive(doc, false); + + bool v = false; + SPAttributeEnum attr = (SPAttributeEnum) GPOINTER_TO_INT(g_object_get_data(G_OBJECT(act), "SP_ATTR_INKSCAPE")); + + switch (attr) { + case SP_ATTR_INKSCAPE_SNAP_GLOBAL: + dt->toggleSnapGlobal(); + break; + case SP_ATTR_INKSCAPE_SNAP_BBOX: + v = nv->snap_manager.snapprefs.getSnapModeBBox(); + sp_repr_set_boolean(repr, "inkscape:snap-bbox", !v); + break; + case SP_ATTR_INKSCAPE_BBOX_PATHS: + v = nv->snap_manager.snapprefs.getSnapToBBoxPath(); + sp_repr_set_boolean(repr, "inkscape:bbox-paths", !v); + break; + case SP_ATTR_INKSCAPE_BBOX_NODES: + v = nv->snap_manager.snapprefs.getSnapToBBoxNode(); + sp_repr_set_boolean(repr, "inkscape:bbox-nodes", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_NODES: + v = nv->snap_manager.snapprefs.getSnapModeNode(); + sp_repr_set_boolean(repr, "inkscape:snap-nodes", !v); + break; + case SP_ATTR_INKSCAPE_OBJECT_PATHS: + v = nv->snap_manager.snapprefs.getSnapToItemPath(); + sp_repr_set_boolean(repr, "inkscape:object-paths", !v); + break; + case SP_ATTR_INKSCAPE_OBJECT_NODES: + v = nv->snap_manager.snapprefs.getSnapToItemNode(); + sp_repr_set_boolean(repr, "inkscape:object-nodes", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES: + v = nv->snap_manager.snapprefs.getSnapSmoothNodes(); + sp_repr_set_boolean(repr, "inkscape:snap-smooth-nodes", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS: + v = nv->snap_manager.snapprefs.getSnapIntersectionCS(); + sp_repr_set_boolean(repr, "inkscape:snap-intersection-paths", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_CENTER: + v = nv->snap_manager.snapprefs.getIncludeItemCenter(); + sp_repr_set_boolean(repr, "inkscape:snap-center", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_GRIDS: + v = nv->snap_manager.snapprefs.getSnapToGrids(); + sp_repr_set_boolean(repr, "inkscape:snap-grids", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_TO_GUIDES: + v = nv->snap_manager.snapprefs.getSnapToGuides(); + sp_repr_set_boolean(repr, "inkscape:snap-to-guides", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_PAGE: + v = nv->snap_manager.snapprefs.getSnapToPageBorder(); + sp_repr_set_boolean(repr, "inkscape:snap-page", !v); + break; + /*case SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE: + v = nv->snap_manager.snapprefs.getSnapIntersectionGG(); + sp_repr_set_boolean(repr, "inkscape:snap-intersection-grid-guide", !v); + break;*/ + case SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS: + v = nv->snap_manager.snapprefs.getSnapLineMidpoints(); + sp_repr_set_boolean(repr, "inkscape:snap-midpoints", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS: + v = nv->snap_manager.snapprefs.getSnapObjectMidpoints(); + sp_repr_set_boolean(repr, "inkscape:snap-object-midpoints", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS: + v = nv->snap_manager.snapprefs.getSnapBBoxEdgeMidpoints(); + sp_repr_set_boolean(repr, "inkscape:snap-bbox-edge-midpoints", !v); + break; + case SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS: + v = nv->snap_manager.snapprefs.getSnapBBoxMidpoints(); + sp_repr_set_boolean(repr, "inkscape:snap-bbox-midpoints", !v); + break; + default: + g_warning("toggle_snap_callback has been called with an ID for which no action has been defined"); + break; + } + + // The snapping preferences are stored in the document, and therefore toggling makes the document dirty + doc->setModifiedSinceSave(); + + sp_document_set_undo_sensitive(doc, saved); } void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions(desktop); - - gchar const * descr = - "<ui>" - " <toolbar name='SnapToolbar'>" - " <toolitem action='ToggleSnapGlobal' />" - " <separator />" - " <toolitem action='ToggleSnapFromBBoxCorner' />" - " <toolitem action='ToggleSnapToBBoxPath' />" - " <toolitem action='ToggleSnapToBBoxNode' />" - " <toolitem action='ToggleSnapToFromBBoxEdgeMidpoints' />" - " <toolitem action='ToggleSnapToFromBBoxCenters' />" - " <separator />" - " <toolitem action='ToggleSnapFromNode' />" - " <toolitem action='ToggleSnapToItemPath' />" - " <toolitem action='ToggleSnapToPathIntersections' />" - " <toolitem action='ToggleSnapToItemNode' />" - " <toolitem action='ToggleSnapToSmoothNodes' />" - " <toolitem action='ToggleSnapToFromLineMidpoints' />" - " <toolitem action='ToggleSnapToFromObjectCenters' />" - " <toolitem action='ToggleSnapToFromRotationCenter' />" - " <separator />" - " <toolitem action='ToggleSnapToPageBorder' />" - " <toolitem action='ToggleSnapToGrids' />" - " <toolitem action='ToggleSnapToGuides' />" - //" <toolitem action='ToggleSnapToGridGuideIntersections' />" - " </toolbar>" - "</ui>"; - - Inkscape::IconSize secondarySize = prefToSize("/toolbox/secondary", 1); - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapGlobal", - _("Snap"), _("Enable snapping"), INKSCAPE_ICON_SNAP, secondarySize, - SP_ATTR_INKSCAPE_SNAP_GLOBAL); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapFromBBoxCorner", - _("Bounding box"), _("Snap bounding box corners"), INKSCAPE_ICON_SNAP_BOUNDING_BOX, - secondarySize, SP_ATTR_INKSCAPE_SNAP_BBOX); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToBBoxPath", - _("Bounding box edges"), _("Snap to edges of a bounding box"), - INKSCAPE_ICON_SNAP_BOUNDING_BOX_EDGES, secondarySize, SP_ATTR_INKSCAPE_BBOX_PATHS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToBBoxNode", - _("Bounding box corners"), _("Snap to bounding box corners"), - INKSCAPE_ICON_SNAP_BOUNDING_BOX_CORNERS, secondarySize, SP_ATTR_INKSCAPE_BBOX_NODES); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromBBoxEdgeMidpoints", - _("BBox Edge Midpoints"), _("Snap from and to midpoints of bounding box edges"), - INKSCAPE_ICON_SNAP_BOUNDING_BOX_MIDPOINTS, secondarySize, - SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromBBoxCenters", - _("BBox Centers"), _("Snapping from and to centers of bounding boxes"), - INKSCAPE_ICON_SNAP_BOUNDING_BOX_CENTER, secondarySize, SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapFromNode", - _("Nodes"), _("Snap nodes or handles"), INKSCAPE_ICON_SNAP_NODES, secondarySize, SP_ATTR_INKSCAPE_SNAP_NODES); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToItemPath", - _("Paths"), _("Snap to paths"), INKSCAPE_ICON_SNAP_NODES_PATH, secondarySize, - SP_ATTR_INKSCAPE_OBJECT_PATHS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToPathIntersections", - _("Path intersections"), _("Snap to path intersections"), - INKSCAPE_ICON_SNAP_NODES_INTERSECTION, secondarySize, SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToItemNode", - _("To nodes"), _("Snap to cusp nodes"), INKSCAPE_ICON_SNAP_NODES_CUSP, secondarySize, - SP_ATTR_INKSCAPE_OBJECT_NODES); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToSmoothNodes", - _("Smooth nodes"), _("Snap to smooth nodes"), INKSCAPE_ICON_SNAP_NODES_SMOOTH, - secondarySize, SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromLineMidpoints", - _("Line Midpoints"), _("Snap from and to midpoints of line segments"), - INKSCAPE_ICON_SNAP_NODES_MIDPOINT, secondarySize, SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromObjectCenters", - _("Object Centers"), _("Snap from and to centers of objects"), - INKSCAPE_ICON_SNAP_NODES_CENTER, secondarySize, SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromRotationCenter", - _("Rotation Centers"), _("Snap from and to an item's rotation center"), - INKSCAPE_ICON_SNAP_NODES_ROTATION_CENTER, secondarySize, SP_ATTR_INKSCAPE_SNAP_CENTER); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToPageBorder", - _("Page border"), _("Snap to the page border"), INKSCAPE_ICON_SNAP_PAGE, - secondarySize, SP_ATTR_INKSCAPE_SNAP_PAGE); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToGrids", - _("Grids"), _("Snap to grids"), INKSCAPE_ICON_GRID_RECTANGULAR, secondarySize, - SP_ATTR_INKSCAPE_SNAP_GRIDS); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - { - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToGuides", - _("Guides"), _("Snap to guides"), INKSCAPE_ICON_GUIDES, secondarySize, - SP_ATTR_INKSCAPE_SNAP_TO_GUIDES); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - } - - /*{ - InkToggleAction* act = ink_toggle_action_new("ToggleSnapToGridGuideIntersections", - _("Grid/guide intersections"), _("Snap to intersections of a grid with a guide"), - INKSCAPE_ICON_SNAP_GRID_GUIDE_INTERSECTIONS, secondarySize, - SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE); - - gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); - }*/ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions(desktop); + + gchar const * descr = + "<ui>" + " <toolbar name='SnapToolbar'>" + " <toolitem action='ToggleSnapGlobal' />" + " <separator />" + " <toolitem action='ToggleSnapFromBBoxCorner' />" + " <toolitem action='ToggleSnapToBBoxPath' />" + " <toolitem action='ToggleSnapToBBoxNode' />" + " <toolitem action='ToggleSnapToFromBBoxEdgeMidpoints' />" + " <toolitem action='ToggleSnapToFromBBoxCenters' />" + " <separator />" + " <toolitem action='ToggleSnapFromNode' />" + " <toolitem action='ToggleSnapToItemPath' />" + " <toolitem action='ToggleSnapToPathIntersections' />" + " <toolitem action='ToggleSnapToItemNode' />" + " <toolitem action='ToggleSnapToSmoothNodes' />" + " <toolitem action='ToggleSnapToFromLineMidpoints' />" + " <toolitem action='ToggleSnapToFromObjectCenters' />" + " <toolitem action='ToggleSnapToFromRotationCenter' />" + " <separator />" + " <toolitem action='ToggleSnapToPageBorder' />" + " <toolitem action='ToggleSnapToGrids' />" + " <toolitem action='ToggleSnapToGuides' />" + //" <toolitem action='ToggleSnapToGridGuideIntersections' />" + " </toolbar>" + "</ui>"; + + Inkscape::IconSize secondarySize = prefToSize("/toolbox/secondary", 1); + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapGlobal", + _("Snap"), _("Enable snapping"), INKSCAPE_ICON_SNAP, secondarySize, + SP_ATTR_INKSCAPE_SNAP_GLOBAL); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapFromBBoxCorner", + _("Bounding box"), _("Snap bounding box corners"), INKSCAPE_ICON_SNAP_BOUNDING_BOX, + secondarySize, SP_ATTR_INKSCAPE_SNAP_BBOX); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToBBoxPath", + _("Bounding box edges"), _("Snap to edges of a bounding box"), + INKSCAPE_ICON_SNAP_BOUNDING_BOX_EDGES, secondarySize, SP_ATTR_INKSCAPE_BBOX_PATHS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToBBoxNode", + _("Bounding box corners"), _("Snap to bounding box corners"), + INKSCAPE_ICON_SNAP_BOUNDING_BOX_CORNERS, secondarySize, SP_ATTR_INKSCAPE_BBOX_NODES); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromBBoxEdgeMidpoints", + _("BBox Edge Midpoints"), _("Snap from and to midpoints of bounding box edges"), + INKSCAPE_ICON_SNAP_BOUNDING_BOX_MIDPOINTS, secondarySize, + SP_ATTR_INKSCAPE_SNAP_BBOX_EDGE_MIDPOINTS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromBBoxCenters", + _("BBox Centers"), _("Snapping from and to centers of bounding boxes"), + INKSCAPE_ICON_SNAP_BOUNDING_BOX_CENTER, secondarySize, SP_ATTR_INKSCAPE_SNAP_BBOX_MIDPOINTS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapFromNode", + _("Nodes"), _("Snap nodes or handles"), INKSCAPE_ICON_SNAP_NODES, secondarySize, SP_ATTR_INKSCAPE_SNAP_NODES); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToItemPath", + _("Paths"), _("Snap to paths"), INKSCAPE_ICON_SNAP_NODES_PATH, secondarySize, + SP_ATTR_INKSCAPE_OBJECT_PATHS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToPathIntersections", + _("Path intersections"), _("Snap to path intersections"), + INKSCAPE_ICON_SNAP_NODES_INTERSECTION, secondarySize, SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToItemNode", + _("To nodes"), _("Snap to cusp nodes"), INKSCAPE_ICON_SNAP_NODES_CUSP, secondarySize, + SP_ATTR_INKSCAPE_OBJECT_NODES); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToSmoothNodes", + _("Smooth nodes"), _("Snap to smooth nodes"), INKSCAPE_ICON_SNAP_NODES_SMOOTH, + secondarySize, SP_ATTR_INKSCAPE_SNAP_SMOOTH_NODES); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromLineMidpoints", + _("Line Midpoints"), _("Snap from and to midpoints of line segments"), + INKSCAPE_ICON_SNAP_NODES_MIDPOINT, secondarySize, SP_ATTR_INKSCAPE_SNAP_LINE_MIDPOINTS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromObjectCenters", + _("Object Centers"), _("Snap from and to centers of objects"), + INKSCAPE_ICON_SNAP_NODES_CENTER, secondarySize, SP_ATTR_INKSCAPE_SNAP_OBJECT_MIDPOINTS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToFromRotationCenter", + _("Rotation Centers"), _("Snap from and to an item's rotation center"), + INKSCAPE_ICON_SNAP_NODES_ROTATION_CENTER, secondarySize, SP_ATTR_INKSCAPE_SNAP_CENTER); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToPageBorder", + _("Page border"), _("Snap to the page border"), INKSCAPE_ICON_SNAP_PAGE, + secondarySize, SP_ATTR_INKSCAPE_SNAP_PAGE); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToGrids", + _("Grids"), _("Snap to grids"), INKSCAPE_ICON_GRID_RECTANGULAR, secondarySize, + SP_ATTR_INKSCAPE_SNAP_GRIDS); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + { + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToGuides", + _("Guides"), _("Snap to guides"), INKSCAPE_ICON_GUIDES, secondarySize, + SP_ATTR_INKSCAPE_SNAP_TO_GUIDES); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + } + + /*{ + InkToggleAction* act = ink_toggle_action_new("ToggleSnapToGridGuideIntersections", + _("Grid/guide intersections"), _("Snap to intersections of a grid with a guide"), + INKSCAPE_ICON_SNAP_GRID_GUIDE_INTERSECTIONS, secondarySize, + SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE); + + gtk_action_group_add_action( mainActions->gobj(), GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_snap_callback), toolbox ); + }*/ GtkUIManager* mgr = gtk_ui_manager_new(); GError* errVal = 0; @@ -2243,94 +2243,94 @@ void setup_snap_toolbox(GtkWidget *toolbox, SPDesktop *desktop) void update_snap_toolbox(SPDesktop *desktop, SPEventContext */*eventcontext*/, GtkWidget *toolbox) { - g_assert(desktop != NULL); - g_assert(toolbox != NULL); - - SPNamedView *nv = sp_desktop_namedview(desktop); - if (nv == NULL) { - g_warning("Namedview cannot be retrieved (in update_snap_toolbox)!"); - return; - } - - Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions(desktop); - - Glib::RefPtr<Gtk::Action> act1 = mainActions->get_action("ToggleSnapGlobal"); - Glib::RefPtr<Gtk::Action> act2 = mainActions->get_action("ToggleSnapFromBBoxCorner"); - Glib::RefPtr<Gtk::Action> act3 = mainActions->get_action("ToggleSnapToBBoxPath"); - Glib::RefPtr<Gtk::Action> act4 = mainActions->get_action("ToggleSnapToBBoxNode"); - Glib::RefPtr<Gtk::Action> act4b = mainActions->get_action("ToggleSnapToFromBBoxEdgeMidpoints"); - Glib::RefPtr<Gtk::Action> act4c = mainActions->get_action("ToggleSnapToFromBBoxCenters"); - Glib::RefPtr<Gtk::Action> act5 = mainActions->get_action("ToggleSnapFromNode"); - Glib::RefPtr<Gtk::Action> act6 = mainActions->get_action("ToggleSnapToItemPath"); - Glib::RefPtr<Gtk::Action> act6b = mainActions->get_action("ToggleSnapToPathIntersections"); - Glib::RefPtr<Gtk::Action> act7 = mainActions->get_action("ToggleSnapToItemNode"); - Glib::RefPtr<Gtk::Action> act8 = mainActions->get_action("ToggleSnapToSmoothNodes"); - Glib::RefPtr<Gtk::Action> act9 = mainActions->get_action("ToggleSnapToFromLineMidpoints"); - Glib::RefPtr<Gtk::Action> act10 = mainActions->get_action("ToggleSnapToFromObjectCenters"); - Glib::RefPtr<Gtk::Action> act11 = mainActions->get_action("ToggleSnapToFromRotationCenter"); - Glib::RefPtr<Gtk::Action> act12 = mainActions->get_action("ToggleSnapToPageBorder"); - //Glib::RefPtr<Gtk::Action> act13 = mainActions->get_action("ToggleSnapToGridGuideIntersections"); - Glib::RefPtr<Gtk::Action> act14 = mainActions->get_action("ToggleSnapToGrids"); - Glib::RefPtr<Gtk::Action> act15 = mainActions->get_action("ToggleSnapToGuides"); - - - if (!act1) { - return; // The snap actions haven't been defined yet (might be the case during startup) - } - - // The ..._set_active calls below will toggle the buttons, but this shouldn't lead to - // changes in our document because we're only updating the UI; - // Setting the "freeze" parameter to true will block the code in toggle_snap_callback() - g_object_set_data(G_OBJECT(toolbox), "freeze", GINT_TO_POINTER(TRUE)); - - bool const c1 = nv->snap_manager.snapprefs.getSnapEnabledGlobally(); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act1->gobj()), c1); - - bool const c2 = nv->snap_manager.snapprefs.getSnapModeBBox(); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act2->gobj()), c2); - gtk_action_set_sensitive(GTK_ACTION(act2->gobj()), c1); - - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act3->gobj()), nv->snap_manager.snapprefs.getSnapToBBoxPath()); - gtk_action_set_sensitive(GTK_ACTION(act3->gobj()), c1 && c2); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4->gobj()), nv->snap_manager.snapprefs.getSnapToBBoxNode()); - gtk_action_set_sensitive(GTK_ACTION(act4->gobj()), c1 && c2); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4b->gobj()), nv->snap_manager.snapprefs.getSnapBBoxEdgeMidpoints()); - gtk_action_set_sensitive(GTK_ACTION(act4b->gobj()), c1 && c2); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4c->gobj()), nv->snap_manager.snapprefs.getSnapBBoxMidpoints()); - gtk_action_set_sensitive(GTK_ACTION(act4c->gobj()), c1 && c2); - - bool const c3 = nv->snap_manager.snapprefs.getSnapModeNode(); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act5->gobj()), c3); - gtk_action_set_sensitive(GTK_ACTION(act5->gobj()), c1); - - bool const c4 = nv->snap_manager.snapprefs.getSnapToItemPath(); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act6->gobj()), c4); - gtk_action_set_sensitive(GTK_ACTION(act6->gobj()), c1 && c3); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act6b->gobj()), nv->snap_manager.snapprefs.getSnapIntersectionCS()); - gtk_action_set_sensitive(GTK_ACTION(act6b->gobj()), c1 && c3 && c4); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act7->gobj()), nv->snap_manager.snapprefs.getSnapToItemNode()); - gtk_action_set_sensitive(GTK_ACTION(act7->gobj()), c1 && c3); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act8->gobj()), nv->snap_manager.snapprefs.getSnapSmoothNodes()); - gtk_action_set_sensitive(GTK_ACTION(act8->gobj()), c1 && c3); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act9->gobj()), nv->snap_manager.snapprefs.getSnapLineMidpoints()); - gtk_action_set_sensitive(GTK_ACTION(act9->gobj()), c1 && c3); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act10->gobj()), nv->snap_manager.snapprefs.getSnapObjectMidpoints()); - gtk_action_set_sensitive(GTK_ACTION(act10->gobj()), c1 && c3); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act11->gobj()), nv->snap_manager.snapprefs.getIncludeItemCenter()); - gtk_action_set_sensitive(GTK_ACTION(act11->gobj()), c1 && c3); - - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act12->gobj()), nv->snap_manager.snapprefs.getSnapToPageBorder()); - gtk_action_set_sensitive(GTK_ACTION(act12->gobj()), c1); - //gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act13->gobj()), nv->snap_manager.snapprefs.getSnapIntersectionGG()); - //gtk_action_set_sensitive(GTK_ACTION(act13->gobj()), c1); - - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act14->gobj()), nv->snap_manager.snapprefs.getSnapToGrids()); - gtk_action_set_sensitive(GTK_ACTION(act14->gobj()), c1); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act15->gobj()), nv->snap_manager.snapprefs.getSnapToGuides()); - gtk_action_set_sensitive(GTK_ACTION(act15->gobj()), c1); - - - g_object_set_data(G_OBJECT(toolbox), "freeze", GINT_TO_POINTER(FALSE)); // unfreeze (see above) + g_assert(desktop != NULL); + g_assert(toolbox != NULL); + + SPNamedView *nv = sp_desktop_namedview(desktop); + if (nv == NULL) { + g_warning("Namedview cannot be retrieved (in update_snap_toolbox)!"); + return; + } + + Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions(desktop); + + Glib::RefPtr<Gtk::Action> act1 = mainActions->get_action("ToggleSnapGlobal"); + Glib::RefPtr<Gtk::Action> act2 = mainActions->get_action("ToggleSnapFromBBoxCorner"); + Glib::RefPtr<Gtk::Action> act3 = mainActions->get_action("ToggleSnapToBBoxPath"); + Glib::RefPtr<Gtk::Action> act4 = mainActions->get_action("ToggleSnapToBBoxNode"); + Glib::RefPtr<Gtk::Action> act4b = mainActions->get_action("ToggleSnapToFromBBoxEdgeMidpoints"); + Glib::RefPtr<Gtk::Action> act4c = mainActions->get_action("ToggleSnapToFromBBoxCenters"); + Glib::RefPtr<Gtk::Action> act5 = mainActions->get_action("ToggleSnapFromNode"); + Glib::RefPtr<Gtk::Action> act6 = mainActions->get_action("ToggleSnapToItemPath"); + Glib::RefPtr<Gtk::Action> act6b = mainActions->get_action("ToggleSnapToPathIntersections"); + Glib::RefPtr<Gtk::Action> act7 = mainActions->get_action("ToggleSnapToItemNode"); + Glib::RefPtr<Gtk::Action> act8 = mainActions->get_action("ToggleSnapToSmoothNodes"); + Glib::RefPtr<Gtk::Action> act9 = mainActions->get_action("ToggleSnapToFromLineMidpoints"); + Glib::RefPtr<Gtk::Action> act10 = mainActions->get_action("ToggleSnapToFromObjectCenters"); + Glib::RefPtr<Gtk::Action> act11 = mainActions->get_action("ToggleSnapToFromRotationCenter"); + Glib::RefPtr<Gtk::Action> act12 = mainActions->get_action("ToggleSnapToPageBorder"); + //Glib::RefPtr<Gtk::Action> act13 = mainActions->get_action("ToggleSnapToGridGuideIntersections"); + Glib::RefPtr<Gtk::Action> act14 = mainActions->get_action("ToggleSnapToGrids"); + Glib::RefPtr<Gtk::Action> act15 = mainActions->get_action("ToggleSnapToGuides"); + + + if (!act1) { + return; // The snap actions haven't been defined yet (might be the case during startup) + } + + // The ..._set_active calls below will toggle the buttons, but this shouldn't lead to + // changes in our document because we're only updating the UI; + // Setting the "freeze" parameter to true will block the code in toggle_snap_callback() + g_object_set_data(G_OBJECT(toolbox), "freeze", GINT_TO_POINTER(TRUE)); + + bool const c1 = nv->snap_manager.snapprefs.getSnapEnabledGlobally(); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act1->gobj()), c1); + + bool const c2 = nv->snap_manager.snapprefs.getSnapModeBBox(); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act2->gobj()), c2); + gtk_action_set_sensitive(GTK_ACTION(act2->gobj()), c1); + + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act3->gobj()), nv->snap_manager.snapprefs.getSnapToBBoxPath()); + gtk_action_set_sensitive(GTK_ACTION(act3->gobj()), c1 && c2); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4->gobj()), nv->snap_manager.snapprefs.getSnapToBBoxNode()); + gtk_action_set_sensitive(GTK_ACTION(act4->gobj()), c1 && c2); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4b->gobj()), nv->snap_manager.snapprefs.getSnapBBoxEdgeMidpoints()); + gtk_action_set_sensitive(GTK_ACTION(act4b->gobj()), c1 && c2); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act4c->gobj()), nv->snap_manager.snapprefs.getSnapBBoxMidpoints()); + gtk_action_set_sensitive(GTK_ACTION(act4c->gobj()), c1 && c2); + + bool const c3 = nv->snap_manager.snapprefs.getSnapModeNode(); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act5->gobj()), c3); + gtk_action_set_sensitive(GTK_ACTION(act5->gobj()), c1); + + bool const c4 = nv->snap_manager.snapprefs.getSnapToItemPath(); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act6->gobj()), c4); + gtk_action_set_sensitive(GTK_ACTION(act6->gobj()), c1 && c3); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act6b->gobj()), nv->snap_manager.snapprefs.getSnapIntersectionCS()); + gtk_action_set_sensitive(GTK_ACTION(act6b->gobj()), c1 && c3 && c4); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act7->gobj()), nv->snap_manager.snapprefs.getSnapToItemNode()); + gtk_action_set_sensitive(GTK_ACTION(act7->gobj()), c1 && c3); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act8->gobj()), nv->snap_manager.snapprefs.getSnapSmoothNodes()); + gtk_action_set_sensitive(GTK_ACTION(act8->gobj()), c1 && c3); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act9->gobj()), nv->snap_manager.snapprefs.getSnapLineMidpoints()); + gtk_action_set_sensitive(GTK_ACTION(act9->gobj()), c1 && c3); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act10->gobj()), nv->snap_manager.snapprefs.getSnapObjectMidpoints()); + gtk_action_set_sensitive(GTK_ACTION(act10->gobj()), c1 && c3); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act11->gobj()), nv->snap_manager.snapprefs.getIncludeItemCenter()); + gtk_action_set_sensitive(GTK_ACTION(act11->gobj()), c1 && c3); + + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act12->gobj()), nv->snap_manager.snapprefs.getSnapToPageBorder()); + gtk_action_set_sensitive(GTK_ACTION(act12->gobj()), c1); + //gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act13->gobj()), nv->snap_manager.snapprefs.getSnapIntersectionGG()); + //gtk_action_set_sensitive(GTK_ACTION(act13->gobj()), c1); + + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act14->gobj()), nv->snap_manager.snapprefs.getSnapToGrids()); + gtk_action_set_sensitive(GTK_ACTION(act14->gobj()), c1); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act15->gobj()), nv->snap_manager.snapprefs.getSnapToGuides()); + gtk_action_set_sensitive(GTK_ACTION(act15->gobj()), c1); + + + g_object_set_data(G_OBJECT(toolbox), "freeze", GINT_TO_POINTER(FALSE)); // unfreeze (see above) } void show_aux_toolbox(GtkWidget *toolbox_toplevel) @@ -2412,8 +2412,8 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) { if (!IS_NAN(adj->value)) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/star/proportion", adj->value); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/shapes/star/proportion", adj->value); } } @@ -3226,7 +3226,7 @@ box3d_set_button_and_adjustment(Persp3D *persp, Proj::Axis axis, // TODO: Take all selected perspectives into account but don't touch the state button if not all of them // have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states // are reset). - bool is_infinite = !persp3d_VP_is_finite(persp, axis); + bool is_infinite = !persp3d_VP_is_finite(persp->perspective_impl, axis); if (is_infinite) { gtk_toggle_action_set_active(tact, TRUE); @@ -3254,6 +3254,10 @@ box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) { GtkAction *act = 0; GtkToggleAction *tact = 0; Persp3D *persp = persp3d_get_from_repr(persp_repr); + if (!persp) { + // Hmm, is it an error if this happens? + return; + } { adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_x")); act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action")); @@ -3340,7 +3344,7 @@ box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl); } - inkscape_active_document()->current_persp3d = persp3d_get_from_repr(persp_repr); + inkscape_active_document()->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id")); @@ -3364,7 +3368,6 @@ box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis ax // in turn, prevent listener from responding g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); - //Persp3D *persp = document->current_persp3d; std::list<Persp3D *> sel_persps = sp_desktop_selection(desktop)->perspList(); if (sel_persps.empty()) { // this can happen when the document is created; we silently ignore it @@ -3372,7 +3375,7 @@ box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis ax } Persp3D *persp = sel_persps.front(); - persp->tmat.set_infinite_direction (axis, adj->value); + persp->perspective_impl->tmat.set_infinite_direction (axis, adj->value); SP_OBJECT(persp)->updateRepr(); // TODO: use the correct axis here, too @@ -3435,7 +3438,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, Inkscape::Preferences *prefs = Inkscape::Preferences::get(); EgeAdjustmentAction* eact = 0; SPDocument *document = sp_desktop_document (desktop); - Persp3D *persp = document->current_persp3d; + Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl(); EgeAdjustmentAction* box3d_angle_x = 0; EgeAdjustmentAction* box3d_angle_y = 0; @@ -3459,7 +3462,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, box3d_angle_x = eact; } - if (!persp3d_VP_is_finite(persp, Proj::X)) { + if (!persp3d_VP_is_finite(persp_impl, Proj::X)) { gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } else { gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); @@ -3499,7 +3502,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, box3d_angle_y = eact; } - if (!persp3d_VP_is_finite(persp, Proj::Y)) { + if (!persp3d_VP_is_finite(persp_impl, Proj::Y)) { gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } else { gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); @@ -3538,7 +3541,7 @@ static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, box3d_angle_z = eact; } - if (!persp3d_VP_is_finite(persp, Proj::Z)) { + if (!persp3d_VP_is_finite(persp_impl, Proj::Z)) { gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); } else { gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); @@ -3988,6 +3991,7 @@ sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } +/* class PencilToleranceObserver : public Inkscape::Preferences::Observer { public: PencilToleranceObserver(Glib::ustring const &path, GObject *x) : Observer(path), _obj(x) @@ -3996,7 +4000,7 @@ public: } virtual ~PencilToleranceObserver() { if (g_object_get_data(_obj, "prefobserver") == this) { - g_object_set_data(_obj, "prefobserver", NULL); + g_object_set_data(_obj, "prefobserver", NULL); } } virtual void notify(Inkscape::Preferences::Entry const &val) { @@ -4015,7 +4019,7 @@ public: private: GObject *_obj; }; - +*/ static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -4040,9 +4044,6 @@ static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio 1, 2); ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - PencilToleranceObserver *obs = - new PencilToleranceObserver("/tools/freehand/pencil/tolerance", G_OBJECT(holder)); } /* advanced shape options */ @@ -4408,11 +4409,13 @@ static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject */*tbl*/ ) prefs->setDouble( "/tools/spray/width", adj->value ); } -static void sp_spray_force_value_changed( GtkAdjustment *adj, GObject */*tbl*/ ) +/* +static void sp_spray_force_value_changed( GtkAdjustment * / *adj* /, GObject * / *tbl* / ) { //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); //prefs->setDouble( "/tools/spray/force", adj->value * 0.01 ); } +*/ static void sp_spray_mean_value_changed( GtkAdjustment *adj, GObject */*tbl*/ ) { @@ -4432,7 +4435,7 @@ static void sp_spray_pressure_state_changed( GtkToggleAction *act, gpointer /*da prefs->setBool("/tools/spray/usepressure", gtk_toggle_action_get_active(act)); } -static void sp_spray_mode_changed( EgeSelectOneAction *act, GObject *tbl ) +static void sp_spray_mode_changed( EgeSelectOneAction *act, GObject */*tbl*/ ) { int mode = ege_select_one_action_get_active( act ); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -4469,15 +4472,15 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction { /* Width */ - gchar const* labels[] = {_("(pinch spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")}; + gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")}; gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; EgeAdjustmentAction *eact = create_adjustment_action( "SprayWidthAction", _("Width"), _("Width:"), _("The width of the spray area (relative to the visible canvas area)"), "/tools/spray/width", 15, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-spray", - 1, 100, 1.0, 0.0, + 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), - sp_spray_width_value_changed, 0.01, 0, 100 ); + sp_spray_width_value_changed, 1, 0 ); 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 ); @@ -4491,9 +4494,9 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction _("Mean"), _("Mean:"), _("The mean of the spray action"), "/tools/spray/mean", 20, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-mean", - 1, 100, 1.0, 0.0, + 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), - sp_spray_mean_value_changed, 0.01, 0, 100 ); + sp_spray_mean_value_changed, 1, 0 ); 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 ); @@ -4507,9 +4510,9 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction _("SD"), _("SD:"), _("The standard deviation of the spray action"), "/tools/spray/standard_deviation", 20, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-standard_deviation", - 1, 100, 1.0, 0.0, + 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), - sp_spray_standard_deviation_value_changed, 0.01, 0, 100 ); + sp_spray_standard_deviation_value_changed, 1, 0 ); 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 ); @@ -4561,7 +4564,7 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction } { /* Population */ - gchar const* labels[] = {_("(rough, simplified)"), 0, 0, _("(default)"), 0, 0, _("(fine, but many nodes)")}; + gchar const* labels[] = {_("(low population)"), 0, 0, _("(default)"), 0, 0, _("(high population)")}; gdouble values[] = {10, 25, 35, 50, 60, 80, 100}; EgeAdjustmentAction *eact = create_adjustment_action( "SprayPopulationAction", _("Population"), _("Population:"), @@ -4570,7 +4573,7 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-population", 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), - sp_spray_population_value_changed, 0.01, 0, 100 ); + sp_spray_population_value_changed, 1, 0 ); gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); g_object_set_data( holder, "spray_population", eact ); @@ -4637,9 +4640,9 @@ static void update_presets_list (GObject *tbl) } } } - } + } - if (match) { + if (match) { // newly added item is at the same index as the // save command, so we need to change twice for it to take effect ege_select_one_action_set_active(sel, 0); @@ -4768,7 +4771,7 @@ static void sp_dcc_build_presets_list(GObject *tbl) int ii=1; for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i) { - GtkTreeIter iter; + GtkTreeIter iter; Glib::ustring preset_name = prefs->getString(*i + "/name"); gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _(preset_name.data()), 1, ii++, -1 ); @@ -4820,12 +4823,12 @@ static void sp_dcc_save_profile (GtkWidget */*widget*/, GObject *tbl) int temp_index = 0; for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i, ++temp_index) { - Glib::ustring name = prefs->getString(*i + "/name"); - if (!name.empty() && profile_name == name) { - new_index = temp_index; + Glib::ustring name = prefs->getString(*i + "/name"); + if (!name.empty() && profile_name == name) { + new_index = temp_index; save_path = *i; break; - } + } } if (new_index == -1) { @@ -4937,7 +4940,7 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-calligraphy", 1, 100, 1.0, 10.0, labels, values, G_N_ELEMENTS(labels), - sp_ddc_width_value_changed, 1, 0); + sp_ddc_width_value_changed, 1, 0 ); 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 ); @@ -6063,9 +6066,9 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject * if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { // there are no texts in selection, read from prefs - sp_style_read_from_prefs(query, "/tools/text"); + sp_style_read_from_prefs(query, "/tools/text"); - if (g_object_get_data(tbl, "text_style_from_prefs")) { + if (g_object_get_data(tbl, "text_style_from_prefs")) { // do not reset the toolbar style from prefs if we already did it last time sp_style_unref(query); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -6216,7 +6219,7 @@ sp_text_toolbox_selection_modified (Inkscape::Selection *selection, guint /*flag } void -sp_text_toolbox_subselection_changed (gpointer /*dragger*/, GObject *tbl) +sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) { sp_text_toolbox_selection_changed (NULL, tbl); } @@ -6342,8 +6345,85 @@ sp_text_toolbox_anchoring_toggled (GtkRadioButton *button, int prop = GPOINTER_TO_INT(data); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPCSSAttr *css = sp_repr_css_attr_new (); + // move the x of all texts to preserve the same bbox + Inkscape::Selection *selection = sp_desktop_selection(desktop); + for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { + if (SP_IS_TEXT((SPItem *) items->data)) { + SPItem *item = SP_ITEM(items->data); + + unsigned writing_mode = SP_OBJECT_STYLE(item)->writing_mode.value; + // below, variable names suggest horizontal move, but we check the writing direction + // and move in the corresponding axis + int axis; + if (writing_mode == SP_CSS_WRITING_MODE_LR_TB || writing_mode == SP_CSS_WRITING_MODE_RL_TB) { + axis = NR::X; + } else { + axis = NR::Y; + } + + Geom::OptRect bbox + = item->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX); + if (!bbox) + continue; + double width = bbox->dimensions()[axis]; + // If you want to align within some frame, other than the text's own bbox, calculate + // the left and right (or top and bottom for tb text) slacks of the text inside that + // frame (currently unused) + double left_slack = 0; + double right_slack = 0; + unsigned old_align = SP_OBJECT_STYLE(item)->text_align.value; + double move = 0; + if (old_align == SP_CSS_TEXT_ALIGN_START || old_align == SP_CSS_TEXT_ALIGN_LEFT) { + switch (prop) { + case 0: + move = -left_slack; + break; + case 1: + move = width/2 + (right_slack - left_slack)/2; + break; + case 2: + move = width + right_slack; + break; + } + } else if (old_align == SP_CSS_TEXT_ALIGN_CENTER) { + switch (prop) { + case 0: + move = -width/2 - left_slack; + break; + case 1: + move = (right_slack - left_slack)/2; + break; + case 2: + move = width/2 + right_slack; + break; + } + } else if (old_align == SP_CSS_TEXT_ALIGN_END || old_align == SP_CSS_TEXT_ALIGN_RIGHT) { + switch (prop) { + case 0: + move = -width - left_slack; + break; + case 1: + move = -width/2 + (right_slack - left_slack)/2; + break; + case 2: + move = right_slack; + break; + } + } + Geom::Point XY = SP_TEXT(item)->attributes.firstXY(); + if (axis == NR::X) { + XY = XY + Geom::Point (move, 0); + } else { + XY = XY + Geom::Point (0, move); + } + SP_TEXT(item)->attributes.setFirstXY(XY); + SP_OBJECT(item)->updateRepr(); + SP_OBJECT(item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + } + + SPCSSAttr *css = sp_repr_css_attr_new (); switch (prop) { case 0: @@ -6382,8 +6462,8 @@ sp_text_toolbox_anchoring_toggled (GtkRadioButton *button, // If querying returned nothing, read the style from the text tool prefs (default style for new texts) if (result_numbers == QUERY_STYLE_NOTHING) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); } sp_style_unref(query); @@ -6486,8 +6566,8 @@ sp_text_toolbox_style_toggled (GtkToggleButton *button, // If querying returned nothing, read the style from the text tool prefs (default style for new texts) if (result_fontspec == QUERY_STYLE_NOTHING) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); } sp_style_unref(query); @@ -6536,7 +6616,7 @@ sp_text_toolbox_orientation_toggled (GtkRadioButton *button, if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); + prefs->mergeStyle("/tools/text/style", css); } sp_desktop_set_style (desktop, css, true, true); @@ -6571,7 +6651,7 @@ sp_text_toolbox_family_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject * } gboolean -sp_text_toolbox_family_list_keypress (GtkWidget *w, GdkEventKey *event, GObject */*tbl*/) +sp_text_toolbox_family_list_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject */*tbl*/) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) return FALSE; @@ -6648,7 +6728,7 @@ sp_text_toolbox_size_changed (GtkComboBox *cbox, if (result_numbers == QUERY_STYLE_NOTHING) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); + prefs->mergeStyle("/tools/text/style", css); } sp_style_unref(query); @@ -6759,14 +6839,14 @@ cell_data_func (GtkCellLayout */*cell_layout*/, g_free(family_escaped); } -gboolean text_toolbox_completion_match_selected (GtkEntryCompletion *widget, - GtkTreeModel *model, - GtkTreeIter *iter, - GObject *tbl) +gboolean text_toolbox_completion_match_selected(GtkEntryCompletion */*widget*/, + GtkTreeModel *model, + GtkTreeIter *iter, + GObject *tbl) { // We intercept this signal so as to fire family_changed at once (without it, you'd have to // press Enter again after choosing a completion) - gchar *family; + gchar *family = 0; gtk_tree_model_get(model, iter, 0, &family, -1); GtkEntry *entry = GTK_ENTRY (g_object_get_data (G_OBJECT (tbl), "family-entry")); @@ -6799,9 +6879,9 @@ cbe_add_completion (GtkComboBoxEntry *cbe, GObject *tbl){ g_object_unref(completion); } -void sp_text_toolbox_family_popnotify (GtkComboBox *widget, - void *property, - GObject *tbl) +void sp_text_toolbox_family_popnotify(GtkComboBox *widget, + void */*property*/, + GObject *tbl) { // while the drop-down is open, we disable font family changing, reenabling it only when it closes @@ -7109,7 +7189,7 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl { return; } - + // quit if run by the _changed callbacks if (g_object_get_data( tbl, "freeze" )) { @@ -7160,7 +7240,7 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) { return; } - + // quit if run by the _changed callbacks if (g_object_get_data( tbl, "freeze" )) { @@ -7280,7 +7360,7 @@ static void sp_nooverlaps_graph_layout_toggled( GtkToggleAction* act, GtkObject } -static void connector_length_changed(GtkAdjustment *adj, GObject* tbl) +static void connector_length_changed(GtkAdjustment *adj, GObject* /*tbl*/) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/tools/connector/length", adj->value); @@ -7495,9 +7575,9 @@ static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainA g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_new_connection_point), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); } - + // Remove selected connection point button - + { InkAction* inky = ink_action_new( "ConnectorRemoveConnPointAction", _("Remove connection point"), @@ -7507,7 +7587,7 @@ static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainA g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_remove_connection_point), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); } - + // Code to watch for changes to the connector-spacing attribute in // the XML. |
