diff options
| author | Ted Gould <ted@gould.cx> | 2008-10-27 18:03:09 +0000 |
|---|---|---|
| committer | Ted Gould <ted@canonical.com> | 2008-10-27 18:03:09 +0000 |
| commit | 7dbe11bc23efa5f51a9b84e7d0f6dd16e63e0902 (patch) | |
| tree | 7d3a2b95b84a03a19cb132cdf88bea0ab6dc4773 /src/display | |
| parent | Merging from trunk (diff) | |
| download | inkscape-7dbe11bc23efa5f51a9b84e7d0f6dd16e63e0902.tar.gz inkscape-7dbe11bc23efa5f51a9b84e7d0f6dd16e63e0902.zip | |
From trunk
(bzr r6885)
Diffstat (limited to 'src/display')
25 files changed, 364 insertions, 197 deletions
diff --git a/src/display/bezier-utils-test.cpp b/src/display/bezier-utils-test.cpp index edeb9e3b7..4d6313886 100644 --- a/src/display/bezier-utils-test.cpp +++ b/src/display/bezier-utils-test.cpp @@ -7,7 +7,7 @@ #define's and `using' directives of the included file. */ #include "bezier-utils.cpp" -using NR::Point; +using Geom::Point; static bool range_approx_equal(double const a[], double const b[], unsigned len); @@ -22,9 +22,9 @@ static bool range_equal(T const a[], T const b[], unsigned len) { return true; } -inline bool point_approx_equal(NR::Point const &a, NR::Point const &b, double const eps) +inline bool point_approx_equal(Geom::Point const &a, Geom::Point const &b, double const eps) { - using NR::X; using NR::Y; + using Geom::X; using Geom::Y; return ( NR_DF_TEST_CLOSE(a[X], b[X], eps) && NR_DF_TEST_CLOSE(a[Y], b[Y], eps) ); } @@ -86,7 +86,7 @@ int main(int /*argc*/, char */*argv*/[]) { utest_start("bezier-utils.cpp"); UTEST_TEST("copy_without_nans_or_adjacent_duplicates") { - NR::Point const src[] = { + Geom::Point const src[] = { Point(2., 3.), Point(2., 3.), Point(0., 0.), diff --git a/src/display/bezier-utils-test.h b/src/display/bezier-utils-test.h index eb2b13d7b..cc24adaad 100644 --- a/src/display/bezier-utils-test.h +++ b/src/display/bezier-utils-test.h @@ -19,9 +19,9 @@ static bool range_approx_equal(double const a[], double const b[], unsigned cons return true; } -static inline bool point_approx_equal(NR::Point const &a, NR::Point const &b, double const eps) +static inline bool point_approx_equal(Geom::Point const &a, Geom::Point const &b, double const eps) { - using NR::X; using NR::Y; + using Geom::X; using Geom::Y; return ( NR_DF_TEST_CLOSE(a[X], b[X], eps) && NR_DF_TEST_CLOSE(a[Y], b[Y], eps) ); } @@ -35,7 +35,7 @@ static inline double square(double const x) { the most important test is that the root-mean-square of errors in the estimation are low rather than that the control points found are the same. **/ -static void compare_ctlpts(NR::Point const est_b[], NR::Point const exp_est_b[]) +static void compare_ctlpts(Geom::Point const est_b[], Geom::Point const exp_est_b[]) { unsigned diff_mask = 0; for (unsigned i = 0; i < 4; ++i) { @@ -62,13 +62,13 @@ static void compare_ctlpts(NR::Point const est_b[], NR::Point const exp_est_b[]) } } -static void compare_rms(NR::Point const est_b[], double const t[], NR::Point const d[], unsigned const n, +static void compare_rms(Geom::Point const est_b[], double const t[], Geom::Point const d[], unsigned const n, double const exp_rms_error) { double sum_errsq = 0.0; for (unsigned i = 0; i < n; ++i) { - NR::Point const fit_pt = bezier_pt(3, est_b, t[i]); - NR::Point const diff = fit_pt - d[i]; + Geom::Point const fit_pt = bezier_pt(3, est_b, t[i]); + Geom::Point const diff = fit_pt - d[i]; sum_errsq += dot(diff, diff); } double const rms_error = sqrt( sum_errsq / n ); @@ -84,13 +84,13 @@ static void compare_rms(NR::Point const est_b[], double const t[], NR::Point con class BezierUtilsTest : public CxxTest::TestSuite { public: - static NR::Point const c[4]; + static Geom::Point const c[4]; static double const t[24]; static unsigned const n; - NR::Point d[24]; - static NR::Point const src_b[4]; - static NR::Point const tHat1; - static NR::Point const tHat2; + Geom::Point d[24]; + static Geom::Point const src_b[4]; + static Geom::Point const tHat1; + static Geom::Point const tHat2; BezierUtilsTest() { @@ -109,23 +109,23 @@ public: void testCopyWithoutNansOrAdjacentDuplicates() { - NR::Point const src[] = { - NR::Point(2., 3.), - NR::Point(2., 3.), - NR::Point(0., 0.), - NR::Point(2., 3.), - NR::Point(2., 3.), - NR::Point(1., 9.), - NR::Point(1., 9.) + Geom::Point const src[] = { + Geom::Point(2., 3.), + Geom::Point(2., 3.), + Geom::Point(0., 0.), + Geom::Point(2., 3.), + Geom::Point(2., 3.), + Geom::Point(1., 9.), + Geom::Point(1., 9.) }; - NR::Point const exp_dest[] = { - NR::Point(2., 3.), - NR::Point(0., 0.), - NR::Point(2., 3.), - NR::Point(1., 9.) + Geom::Point const exp_dest[] = { + Geom::Point(2., 3.), + Geom::Point(0., 0.), + Geom::Point(2., 3.), + Geom::Point(1., 9.) }; g_assert( G_N_ELEMENTS(src) == 7 ); - NR::Point dest[7]; + Geom::Point dest[7]; struct tst { unsigned src_ix0; unsigned src_len; @@ -157,11 +157,11 @@ public: void testBezierPt1() { - NR::Point const a[] = {NR::Point(2.0, 4.0), - NR::Point(1.0, 8.0)}; + Geom::Point const a[] = {Geom::Point(2.0, 4.0), + Geom::Point(1.0, 8.0)}; TS_ASSERT_EQUALS( bezier_pt(1, a, 0.0) , a[0] ); TS_ASSERT_EQUALS( bezier_pt(1, a, 1.0) , a[1] ); - TS_ASSERT_EQUALS( bezier_pt(1, a, 0.5) , NR::Point(1.5, 6.0) ); + TS_ASSERT_EQUALS( bezier_pt(1, a, 0.5) , Geom::Point(1.5, 6.0) ); double const t[] = {0.5, 0.25, 0.3, 0.6}; for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) { double const ti = t[i], si = 1.0 - ti; @@ -171,17 +171,17 @@ public: void testBezierPt2() { - NR::Point const b[] = {NR::Point(1.0, 2.0), - NR::Point(8.0, 4.0), - NR::Point(3.0, 1.0)}; + Geom::Point const b[] = {Geom::Point(1.0, 2.0), + Geom::Point(8.0, 4.0), + Geom::Point(3.0, 1.0)}; TS_ASSERT_EQUALS( bezier_pt(2, b, 0.0) , b[0] ); TS_ASSERT_EQUALS( bezier_pt(2, b, 1.0) , b[2] ); - TS_ASSERT_EQUALS( bezier_pt(2, b, 0.5) , NR::Point(5.0, 2.75) ); + TS_ASSERT_EQUALS( bezier_pt(2, b, 0.5) , Geom::Point(5.0, 2.75) ); double const t[] = {0.5, 0.25, 0.3, 0.6}; for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) { double const ti = t[i], si = 1.0 - ti; - NR::Point const exp_pt( si*si * b[0] + 2*si*ti * b[1] + ti*ti * b[2] ); - NR::Point const pt(bezier_pt(2, b, ti)); + Geom::Point const exp_pt( si*si * b[0] + 2*si*ti * b[1] + ti*ti * b[2] ); + Geom::Point const pt(bezier_pt(2, b, ti)); TS_ASSERT(point_approx_equal(pt, exp_pt, 1e-11)); } } @@ -190,7 +190,7 @@ public: { TS_ASSERT_EQUALS( bezier_pt(3, c, 0.0) , c[0] ); TS_ASSERT_EQUALS( bezier_pt(3, c, 1.0) , c[3] ); - TS_ASSERT_EQUALS( bezier_pt(3, c, 0.5) , NR::Point(4.0, 13.0/8.0) ); + TS_ASSERT_EQUALS( bezier_pt(3, c, 0.5) , Geom::Point(4.0, 13.0/8.0) ); double const t[] = {0.5, 0.25, 0.3, 0.6}; for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) { double const ti = t[i], si = 1.0 - ti; @@ -206,18 +206,18 @@ public: void testComputeMaxErrorRatio() { struct Err_tst { - NR::Point pt; + Geom::Point pt; double u; double err; } const err_tst[] = { {c[0], 0.0, 0.0}, - {NR::Point(4.0, 13.0/8.0), 0.5, 0.0}, - {NR::Point(4.0, 2.0), 0.5, 9.0/64.0}, - {NR::Point(3.0, 2.0), 0.5, 1.0 + 9.0/64.0}, - {NR::Point(6.0, 2.0), 0.5, 4.0 + 9.0/64.0}, + {Geom::Point(4.0, 13.0/8.0), 0.5, 0.0}, + {Geom::Point(4.0, 2.0), 0.5, 9.0/64.0}, + {Geom::Point(3.0, 2.0), 0.5, 1.0 + 9.0/64.0}, + {Geom::Point(6.0, 2.0), 0.5, 4.0 + 9.0/64.0}, {c[3], 1.0, 0.0}, }; - NR::Point d[G_N_ELEMENTS(err_tst)]; + Geom::Point d[G_N_ELEMENTS(err_tst)]; double u[G_N_ELEMENTS(err_tst)]; for (unsigned i = 0; i < G_N_ELEMENTS(err_tst); ++i) { Err_tst const &t = err_tst[i]; @@ -235,8 +235,8 @@ public: { /* n == 2 */ { - NR::Point const d[] = {NR::Point(2.9415, -5.8149), - NR::Point(23.021, 4.9814)}; + Geom::Point const d[] = {Geom::Point(2.9415, -5.8149), + Geom::Point(23.021, 4.9814)}; double u[G_N_ELEMENTS(d)]; double const exp_u[] = {0.0, 1.0}; g_assert( G_N_ELEMENTS(u) == G_N_ELEMENTS(exp_u) ); @@ -248,9 +248,9 @@ public: { double const exp_u[] = {0.0, 0.1829, 0.2105, 0.2105, 0.619, 0.815, 0.999, 1.0}; unsigned const n = G_N_ELEMENTS(exp_u); - NR::Point d[n]; + Geom::Point d[n]; double u[n]; - NR::Point const a(-23.985, 4.915), b(4.9127, 5.203); + Geom::Point const a(-23.985, 4.915), b(4.9127, 5.203); for (unsigned i = 0; i < n; ++i) { double bi = exp_u[i], ai = 1.0 - bi; d[i] = ai * a + bi * b; @@ -262,7 +262,7 @@ public: void testGenerateBezier() { - NR::Point est_b[4]; + Geom::Point est_b[4]; generate_bezier(est_b, d, t, n, tHat1, tHat2, 1.0); compare_ctlpts(est_b, src_b); @@ -274,16 +274,16 @@ public: void testSpBezierFitCubicFull() { - NR::Point est_b[4]; + Geom::Point est_b[4]; int splitpoints[2]; gint const succ = sp_bezier_fit_cubic_full(est_b, splitpoints, d, n, tHat1, tHat2, square(1.2), 1); TS_ASSERT_EQUALS( succ , 1 ); - NR::Point const exp_est_b[4] = { - NR::Point(5.000000, -3.000000), - NR::Point(7.5753, -0.4247), - NR::Point(4.77533, 1.22467), - NR::Point(3, 3) + Geom::Point const exp_est_b[4] = { + Geom::Point(5.000000, -3.000000), + Geom::Point(7.5753, -0.4247), + Geom::Point(4.77533, 1.22467), + Geom::Point(3, 3) }; compare_ctlpts(est_b, exp_est_b); @@ -294,15 +294,15 @@ public: void testSpBezierFitCubic() { - NR::Point est_b[4]; + Geom::Point est_b[4]; gint const succ = sp_bezier_fit_cubic(est_b, d, n, square(1.2)); TS_ASSERT_EQUALS( succ , 1 ); - NR::Point const exp_est_b[4] = { - NR::Point(5.000000, -3.000000), - NR::Point(7.57134, -0.423509), - NR::Point(4.77929, 1.22426), - NR::Point(3, 3) + Geom::Point const exp_est_b[4] = { + Geom::Point(5.000000, -3.000000), + Geom::Point(7.57134, -0.423509), + Geom::Point(4.77929, 1.22426), + Geom::Point(3, 3) }; compare_ctlpts(est_b, exp_est_b); @@ -321,22 +321,22 @@ public: }; // This is not very neat, but since we know this header is only included by the generated CxxTest file it shouldn't give any problems -NR::Point const BezierUtilsTest::c[4] = { - NR::Point(1.0, 2.0), - NR::Point(8.0, 4.0), - NR::Point(3.0, 1.0), - NR::Point(-2.0, -4.0)}; +Geom::Point const BezierUtilsTest::c[4] = { + Geom::Point(1.0, 2.0), + Geom::Point(8.0, 4.0), + Geom::Point(3.0, 1.0), + Geom::Point(-2.0, -4.0)}; double const BezierUtilsTest::t[24] = { 0.0, .001, .03, .05, .09, .13, .18, .25, .29, .33, .39, .44, .51, .57, .62, .69, .75, .81, .91, .93, .97, .98, .999, 1.0}; unsigned const BezierUtilsTest::n = G_N_ELEMENTS(BezierUtilsTest::t); -NR::Point const BezierUtilsTest::src_b[4] = { - NR::Point(5., -3.), - NR::Point(8., 0.), - NR::Point(4., 2.), - NR::Point(3., 3.)}; -NR::Point const BezierUtilsTest::tHat1(unit_vector( BezierUtilsTest::src_b[1] - BezierUtilsTest::src_b[0] )); -NR::Point const BezierUtilsTest::tHat2(unit_vector( BezierUtilsTest::src_b[2] - BezierUtilsTest::src_b[3] )); +Geom::Point const BezierUtilsTest::src_b[4] = { + Geom::Point(5., -3.), + Geom::Point(8., 0.), + Geom::Point(4., 2.), + Geom::Point(3., 3.)}; +Geom::Point const BezierUtilsTest::tHat1(unit_vector( BezierUtilsTest::src_b[1] - BezierUtilsTest::src_b[0] )); +Geom::Point const BezierUtilsTest::tHat2(unit_vector( BezierUtilsTest::src_b[2] - BezierUtilsTest::src_b[3] )); /* Local Variables: diff --git a/src/display/bezier-utils.cpp b/src/display/bezier-utils.cpp index 5d09e66a7..b538f7fba 100644 --- a/src/display/bezier-utils.cpp +++ b/src/display/bezier-utils.cpp @@ -80,10 +80,10 @@ static Geom::Point const unconstrained_tangent(0, 0); #ifdef BEZIER_DEBUG # define DOUBLE_ASSERT(x) g_assert( ( (x) > -SP_HUGE ) && ( (x) < SP_HUGE ) ) # define BEZIER_ASSERT(b) do { \ - DOUBLE_ASSERT((b)[0][NR::X]); DOUBLE_ASSERT((b)[0][NR::Y]); \ - DOUBLE_ASSERT((b)[1][NR::X]); DOUBLE_ASSERT((b)[1][NR::Y]); \ - DOUBLE_ASSERT((b)[2][NR::X]); DOUBLE_ASSERT((b)[2][NR::Y]); \ - DOUBLE_ASSERT((b)[3][NR::X]); DOUBLE_ASSERT((b)[3][NR::Y]); \ + DOUBLE_ASSERT((b)[0][Geom::X]); DOUBLE_ASSERT((b)[0][Geom::Y]); \ + DOUBLE_ASSERT((b)[1][Geom::X]); DOUBLE_ASSERT((b)[1][Geom::Y]); \ + DOUBLE_ASSERT((b)[2][Geom::X]); DOUBLE_ASSERT((b)[2][Geom::Y]); \ + DOUBLE_ASSERT((b)[3][Geom::X]); DOUBLE_ASSERT((b)[3][Geom::Y]); \ } while(0) #else # define DOUBLE_ASSERT(x) do { } while(0) @@ -148,8 +148,8 @@ copy_without_nans_or_adjacent_duplicates(Geom::Point const src[], unsigned src_l if ( si == src_len ) { return 0; } - if (!IS_NAN(src[si][NR::X]) && - !IS_NAN(src[si][NR::Y])) { + if (!IS_NAN(src[si][Geom::X]) && + !IS_NAN(src[si][Geom::Y])) { dest[0] = Geom::Point(src[si]); ++si; break; @@ -160,8 +160,8 @@ copy_without_nans_or_adjacent_duplicates(Geom::Point const src[], unsigned src_l for (; si < src_len; ++si) { Geom::Point const src_pt = Geom::Point(src[si]); if ( src_pt != dest[di] - && !IS_NAN(src_pt[NR::X]) - && !IS_NAN(src_pt[NR::Y])) { + && !IS_NAN(src_pt[Geom::X]) + && !IS_NAN(src_pt[Geom::Y])) { dest[++di] = src_pt; } } @@ -806,7 +806,7 @@ sp_darray_center_tangent(Geom::Point const d[], if ( d[center + 1] == d[center - 1] ) { /* Rotate 90 degrees in an arbitrary direction. */ Geom::Point const diff = d[center] - d[center - 1]; - ret = NR::rot90(diff); + ret = Geom::rot90(diff); } else { ret = d[center - 1] - d[center + 1]; } @@ -959,11 +959,11 @@ compute_hook(Geom::Point const &a, Geom::Point const &b, double const u, BezierC { Geom::Point const P = bezier_pt(3, bezCurve, u); Geom::Point const diff = .5 * (a + b) - P; - double const dist = NR::L2(diff); + double const dist = Geom::L2(diff); if (dist < tolerance) { return 0; } - double const allowed = NR::L2(b - a) + tolerance; + double const allowed = Geom::L2(b - a) + tolerance; return dist / allowed; /** \todo * effic: Hooks are very rare. We could start by comparing diff --git a/src/display/canvas-arena.h b/src/display/canvas-arena.h index 5e6188eee..34bc19946 100644 --- a/src/display/canvas-arena.h +++ b/src/display/canvas-arena.h @@ -32,7 +32,7 @@ struct _SPCanvasArena { guint cursor : 1; guint sticky : 1; - NR::Point c; // what is this? + Geom::Point c; // what is this? NRArena *arena; NRArenaItem *root; diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 0f5045c4d..e181035eb 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -194,17 +194,17 @@ CanvasAxonomGrid::CanvasAxonomGrid (SPNamedView * nv, Inkscape::XML::Node * in_r : CanvasGrid(nv, in_repr, in_doc, GRID_AXONOMETRIC) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gridunit = sp_unit_get_by_abbreviation( prefs->getString("options.grids.axonom", "units").data() ); + gridunit = sp_unit_get_by_abbreviation( prefs->getString("/options/grids/axonom/units").data() ); if (!gridunit) gridunit = &sp_unit_get_by_id(SP_UNIT_PX); - origin[Geom::X] = sp_units_get_pixels( prefs->getDouble("options.grids.axonom", "origin_x", 0.0), *gridunit ); - origin[Geom::Y] = sp_units_get_pixels( prefs->getDouble("options.grids.axonom", "origin_y", 0.0), *gridunit ); - color = prefs->getInt("options.grids.axonom", "color", 0x0000ff20); - empcolor = prefs->getInt("options.grids.axonom", "empcolor", 0x0000ff40); - empspacing = prefs->getInt("options.grids.axonom", "empspacing", 5); - lengthy = sp_units_get_pixels( prefs->getDouble("options.grids.axonom", "spacing_y", 1.0), *gridunit ); - angle_deg[X] = prefs->getDouble("options.grids.axonom", "angle_x", 30.0); - angle_deg[Z] = prefs->getDouble("options.grids.axonom", "angle_z", 30.0); + origin[Geom::X] = sp_units_get_pixels( prefs->getDouble("/options/grids/axonom/origin_x", 0.0), *gridunit ); + origin[Geom::Y] = sp_units_get_pixels( prefs->getDouble("/options/grids/axonom/origin_y", 0.0), *gridunit ); + color = prefs->getInt("/options/grids/axonom/color", 0x0000ff20); + empcolor = prefs->getInt("/options/grids/axonom/empcolor", 0x0000ff40); + empspacing = prefs->getInt("/options/grids/axonom/empspacing", 5); + lengthy = sp_units_get_pixels( prefs->getDouble("/options/grids/axonom/spacing_y", 1.0), *gridunit ); + angle_deg[X] = prefs->getDouble("/options/grids/axonom/angle_x", 30.0); + angle_deg[Z] = prefs->getDouble("/options/grids/axonom/angle_z", 30.0); angle_deg[Y] = 0; angle_rad[X] = deg_to_rad(angle_deg[X]); @@ -298,7 +298,6 @@ static gboolean sp_nv_read_opacity(gchar const *str, guint32 *color) void CanvasAxonomGrid::readRepr() { - /// @todo Replace direct XML preference node manipulation with calls to public prefs API gchar const *value; if ( (value = repr->attribute("originx")) ) { sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &origin[Geom::X], &gridunit); @@ -551,7 +550,7 @@ CanvasAxonomGrid::Render (SPCanvasBuf *buf) //set correct coloring, depending preference (when zoomed out, always major coloring or minor coloring) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint32 _empcolor; - bool preference = prefs->getBool("options.grids", "no_emphasize_when_zoomedout", false); + bool preference = prefs->getBool("/options/grids/no_emphasize_when_zoomedout", false); if( scaled && preference ) { _empcolor = color; } else { diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 9b6b512b0..8505426d3 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -1,10 +1,8 @@ -#define INKSCAPE_CANVAS_GRID_C - -/* - * - * Copyright (C) Johan Engelen 2006-2007 <johan@shouraizou.nl> +/** @file + * @brief Cartesian grid implementation + */ +/* Copyright (C) Johan Engelen 2006-2007 <johan@shouraizou.nl> * Copyright (C) Lauris Kaplinski 2000 - * */ /* As a general comment, I am not exactly proud of how things are done. @@ -13,6 +11,7 @@ * Don't be shy to correct things. */ +#define INKSCAPE_CANVAS_GRID_C #include "sp-canvas-util.h" #include "util/mathfns.h" @@ -416,17 +415,17 @@ CanvasXYGrid::CanvasXYGrid (SPNamedView * nv, Inkscape::XML::Node * in_repr, SPD : CanvasGrid(nv, in_repr, in_doc, GRID_RECTANGULAR) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gridunit = sp_unit_get_by_abbreviation( prefs->getString("options.grids.xy", "units").data() ); + gridunit = sp_unit_get_by_abbreviation( prefs->getString("/options/grids/xy/units").data() ); if (!gridunit) gridunit = &sp_unit_get_by_id(SP_UNIT_PX); - origin[Geom::X] = sp_units_get_pixels(prefs->getDouble("options.grids.xy", "origin_x", 0.0), *gridunit); - origin[Geom::Y] = sp_units_get_pixels(prefs->getDouble("options.grids.xy", "origin_y", 0.0), *gridunit); - color = prefs->getInt("options.grids.xy", "color", 0x0000ff20); - empcolor = prefs->getInt("options.grids.xy", "empcolor", 0x0000ff40); - empspacing = prefs->getInt("options.grids.xy", "empspacing", 5); - spacing[Geom::X] = sp_units_get_pixels(prefs->getDouble("options.grids.xy", "spacing_x", 0.0), *gridunit); - spacing[Geom::Y] = sp_units_get_pixels(prefs->getDouble("options.grids.xy", "spacing_y", 0.0), *gridunit); - render_dotted = prefs->getBool("options.grids.xy", "dotted", false); + origin[Geom::X] = sp_units_get_pixels(prefs->getDouble("/options/grids/xy/origin_x", 0.0), *gridunit); + origin[Geom::Y] = sp_units_get_pixels(prefs->getDouble("/options/grids/xy/origin_y", 0.0), *gridunit); + color = prefs->getInt("/options/grids/xy/color", 0x0000ff20); + empcolor = prefs->getInt("/options/grids/xy/empcolor", 0x0000ff40); + empspacing = prefs->getInt("/options/grids/xy/empspacing", 5); + spacing[Geom::X] = sp_units_get_pixels(prefs->getDouble("/options/grids/xy/spacing_x", 0.0), *gridunit); + spacing[Geom::Y] = sp_units_get_pixels(prefs->getDouble("/options/grids/xy/spacing_y", 0.0), *gridunit); + render_dotted = prefs->getBool("/options/grids/xy/dotted", false); snapper = new CanvasXYGridSnapper(this, &namedview->snap_manager, 0); @@ -889,7 +888,7 @@ CanvasXYGrid::Render (SPCanvasBuf *buf) //set correct coloring, depending preference (when zoomed out, always major coloring or minor coloring) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint32 _empcolor; - bool no_emp_when_zoomed_out = prefs->getBool("options.grids", "no_emphasize_when_zoomedout", false); + bool no_emp_when_zoomed_out = prefs->getBool("/options/grids/no_emphasize_when_zoomedout", false); if( (scaled[Geom::X] || scaled[Geom::Y]) && no_emp_when_zoomed_out ) { _empcolor = color; } else { @@ -1000,14 +999,10 @@ void CanvasXYGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point co */ bool CanvasXYGridSnapper::ThisSnapperMightSnap() const { - return _snap_enabled && _snap_from != 0; + return _snapmanager->snapprefs.getSnapModeBBoxOrNodes(); } - - - - -}; /* namespace Inkscape */ +} // namespace Inkscape /* diff --git a/src/display/canvas-grid.h b/src/display/canvas-grid.h index 66f3bc43c..f50537065 100644 --- a/src/display/canvas-grid.h +++ b/src/display/canvas-grid.h @@ -1,16 +1,13 @@ -#ifndef INKSCAPE_CANVAS_GRID_H -#define INKSCAPE_CANVAS_GRID_H - -/* - * Inkscape::CXYGrid - * - * Generic (and quite unintelligent) grid item for gnome canvas - * - * Copyright (C) Johan Engelen 2006-2007 <johan@shouraizou.nl> +/** @file + * @brief Cartesian grid item for the Inkscape canvas + */ +/* Copyright (C) Johan Engelen 2006-2007 <johan@shouraizou.nl> * Copyright (C) Lauris Kaplinski 2000 - * */ +#ifndef INKSCAPE_CANVAS_GRID_H +#define INKSCAPE_CANVAS_GRID_H + #include <cstring> #include <string> diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index 21e1fbd48..f7a8cfb01 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -74,8 +74,8 @@ static void sp_canvastext_init (SPCanvasText *canvastext) { canvastext->rgba = 0x0000ff7f; - canvastext->s[NR::X] = canvastext->s[NR::Y] = 0.0; - canvastext->affine = NR::identity(); + canvastext->s[Geom::X] = canvastext->s[Geom::Y] = 0.0; + canvastext->affine = Geom::identity(); canvastext->fontsize = 10.0; canvastext->item = NULL; canvastext->text = NULL; @@ -113,9 +113,9 @@ sp_canvastext_render (SPCanvasItem *item, SPCanvasBuf *buf) guint32 rgba = cl->rgba; cairo_set_source_rgba(buf->ct, SP_RGBA32_B_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_R_F(rgba), SP_RGBA32_A_F(rgba)); - NR::Point s = cl->s * cl->affine; - double offsetx = s[NR::X] - buf->rect.x0; - double offsety = s[NR::Y] - buf->rect.y0; + Geom::Point s = cl->s * cl->affine; + double offsetx = s[Geom::X] - buf->rect.x0; + double offsety = s[Geom::Y] - buf->rect.y0; offsetx -= anchor_offset_x; offsety += anchor_offset_y; @@ -150,10 +150,10 @@ sp_canvastext_update (SPCanvasItem *item, Geom::Matrix const &affine, unsigned i cairo_text_extents_t bbox; cairo_text_extents(&tmp_buf, cl->text, &bbox); **/ - item->x1 = s[NR::X] + 0; - item->y1 = s[NR::Y] - cl->fontsize; - item->x2 = s[NR::X] + cl->fontsize * strlen(cl->text); - item->y2 = s[NR::Y] + cl->fontsize * 0.5; // for letters below the baseline + item->x1 = s[Geom::X] + 0; + item->y1 = s[Geom::Y] - cl->fontsize; + item->x2 = s[Geom::X] + cl->fontsize * strlen(cl->text); + item->y2 = s[Geom::Y] + cl->fontsize * 0.5; // for letters below the baseline // adjust update region according to anchor shift // FIXME: use the correct text extent @@ -208,16 +208,16 @@ sp_canvastext_set_coords (SPCanvasText *ct, gdouble x0, gdouble y0) g_return_if_fail (ct != NULL); g_return_if_fail (SP_IS_CANVASTEXT (ct)); - if (DIFFER (x0, ct->s[NR::X]) || DIFFER (y0, ct->s[NR::Y])) { - ct->s[NR::X] = x0; - ct->s[NR::Y] = y0; + if (DIFFER (x0, ct->s[Geom::X]) || DIFFER (y0, ct->s[Geom::Y])) { + ct->s[Geom::X] = x0; + ct->s[Geom::Y] = y0; sp_canvas_item_request_update (SP_CANVAS_ITEM (ct)); } sp_canvas_item_request_update (SP_CANVAS_ITEM (ct)); } void -sp_canvastext_set_coords (SPCanvasText *ct, const NR::Point start) +sp_canvastext_set_coords (SPCanvasText *ct, const Geom::Point start) { sp_canvastext_set_coords(ct, start[0], start[1]); } diff --git a/src/display/canvas-text.h b/src/display/canvas-text.h index bb732ae6f..0e4724d92 100644 --- a/src/display/canvas-text.h +++ b/src/display/canvas-text.h @@ -41,7 +41,7 @@ SPCanvasItem *sp_canvastext_new(SPCanvasGroup *parent, Geom::Point pos, gchar co void sp_canvastext_set_rgba32 (SPCanvasText *ct, guint32 rgba); void sp_canvastext_set_coords (SPCanvasText *ct, gdouble x0, gdouble y0); -void sp_canvastext_set_coords (SPCanvasText *ct, const NR::Point start); +void sp_canvastext_set_coords (SPCanvasText *ct, const Geom::Point start); void sp_canvastext_set_text (SPCanvasText *ct, gchar const* new_text); void sp_canvastext_set_number_as_text (SPCanvasText *ct, int num); void sp_canvastext_set_fontsize (SPCanvasText *ct, double size); diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index 5f20d077a..ef60f0502 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -89,7 +89,7 @@ static void nr_arena_glyphs_init(NRArenaGlyphs *glyphs) { glyphs->style = NULL; - glyphs->g_transform.set_identity(); + glyphs->g_transform.setIdentity(); glyphs->font = NULL; glyphs->glyph = 0; @@ -142,7 +142,7 @@ nr_arena_glyphs_update(NRArenaItem *item, NRRectL */*area*/, NRGC *gc, guint /*s bbox.x0 = bbox.y0 = NR_HUGE; bbox.x1 = bbox.y1 = -NR_HUGE; - float const scale = NR::expansion(gc->transform); + float const scale = gc->transform.descrim(); if (!glyphs->style->fill.isNone()) { Geom::Matrix t; @@ -265,7 +265,7 @@ nr_arena_glyphs_set_path(NRArenaGlyphs *glyphs, SPCurve */*curve*/, unsigned int if (transform) { glyphs->g_transform = *transform; } else { - glyphs->g_transform.set_identity(); + glyphs->g_transform.setIdentity(); } if (font) font->Ref(); @@ -298,7 +298,7 @@ nr_arena_glyphs_fill_mask(NRArenaGlyphs *glyphs, NRRectL *area, NRPixBlock *m) if (glyphs->rfont && nr_rect_l_test_intersect_ptr(area, &item->bbox)) { raster_glyph *g = glyphs->rfont->GetGlyph(glyphs->glyph); - if ( g ) g->Blit(NR::Point(glyphs->x, glyphs->y), *m); + if ( g ) g->Blit(Geom::Point(glyphs->x, glyphs->y), *m); } return item->state; @@ -310,7 +310,7 @@ nr_arena_glyphs_stroke_mask(NRArenaGlyphs *glyphs, NRRectL *area, NRPixBlock *m) NRArenaItem *item = NR_ARENA_ITEM(glyphs); if (glyphs->sfont && nr_rect_l_test_intersect_ptr(area, &item->bbox)) { raster_glyph *g=glyphs->sfont->GetGlyph(glyphs->glyph); - if ( g ) g->Blit(NR::Point(glyphs->x, glyphs->y),*m); + if ( g ) g->Blit(Geom::Point(glyphs->x, glyphs->y),*m); } return item->state; diff --git a/src/display/nr-arena-glyphs.h b/src/display/nr-arena-glyphs.h index 9c6762363..5bf94f3fc 100644 --- a/src/display/nr-arena-glyphs.h +++ b/src/display/nr-arena-glyphs.h @@ -33,7 +33,7 @@ NRType nr_arena_glyphs_get_type (void); struct NRArenaGlyphs : public NRArenaItem { /* Glyphs data */ SPStyle *style; - NR::Matrix g_transform; + Geom::Matrix g_transform; font_instance *font; gint glyph; @@ -41,7 +41,7 @@ struct NRArenaGlyphs : public NRArenaItem { raster_font *sfont; float x, y; -// NR::Matrix cached_tr; +// Geom::Matrix cached_tr; // Shape *cached_shp; // bool cached_shp_dirty; // bool cached_style_dirty; diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp index c8a988483..17c9ab07c 100644 --- a/src/display/nr-arena-image.cpp +++ b/src/display/nr-arena-image.cpp @@ -15,7 +15,7 @@ #include <libnr/nr-compose-transform.h> #include <2geom/transforms.h> #include <libnr/nr-blit.h> -#include "../prefs-utils.h" +#include "../preferences.h" #include "nr-arena-image.h" #include "style.h" #include "display/nr-arena.h" @@ -173,7 +173,8 @@ nr_arena_image_update( NRArenaItem *item, NRRectL */*area*/, NRGC *gc, unsigned static unsigned int nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixBlock *pb, unsigned int /*flags*/ ) { - nr_arena_image_x_sample = prefs_get_int_attribute ("options.bitmapoversample", "value", 1); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + nr_arena_image_x_sample = prefs->getInt("/options/bitmapoversample/value", 1); nr_arena_image_y_sample = nr_arena_image_x_sample; bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE); @@ -228,7 +229,7 @@ nr_arena_image_render( cairo_t *ct, NRArenaItem *item, NRRectL */*area*/, NRPixB if (!ct) return item->state; - guint32 rgba = prefs_get_int_attribute("options.wireframecolors", "images", 0xff0000ff); + guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff); // FIXME: we use RGBA buffers but cairo writes BGRA (on i386), so we must cheat // by setting color channels in the "wrong" order cairo_set_source_rgba(ct, SP_RGBA32_B_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_R_F(rgba), SP_RGBA32_A_F(rgba)); diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp index b9a0cc371..d944b4228 100644 --- a/src/display/nr-arena-item.cpp +++ b/src/display/nr-arena-item.cpp @@ -30,7 +30,7 @@ #include "nr-filter.h" #include "libnr/nr-rect.h" #include "nr-arena-group.h" -#include "prefs-utils.h" +#include "preferences.h" namespace GC = Inkscape::GC; @@ -343,13 +343,14 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area // render clip and mask, if any guint32 saved_rgba = item->arena->outlinecolor; // save current outline color // render clippath as an object, using a different color + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (item->clip) { - item->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "clips", 0x00ff00ff); // green clips + item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/clips", 0x00ff00ff); // green clips NR_ARENA_ITEM_VIRTUAL (item->clip, render) (ct, item->clip, &carea, pb, flags); } // render mask as an object, using a different color if (item->mask) { - item->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "masks", 0x0000ffff); // blue masks + item->arena->outlinecolor = prefs->getInt("/options/wireframecolors/masks", 0x0000ffff); // blue masks NR_ARENA_ITEM_VIRTUAL (item->mask, render) (ct, item->mask, &carea, pb, flags); } item->arena->outlinecolor = saved_rgba; // restore outline color diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp index 6a252e5f5..4c988be46 100644 --- a/src/display/nr-arena-shape.cpp +++ b/src/display/nr-arena-shape.cpp @@ -29,7 +29,6 @@ #include <livarot/float-line.h> #include <livarot/int-line.h> #include <style.h> -#include "prefs-utils.h" #include "inkscape-cairo.h" #include "helper/geom.h" #include "helper/geom-curves.h" diff --git a/src/display/nr-arena-shape.h b/src/display/nr-arena-shape.h index 8ff8c476a..455757806 100644 --- a/src/display/nr-arena-shape.h +++ b/src/display/nr-arena-shape.h @@ -154,6 +154,7 @@ struct NRArenaShape : public NRArenaItem { static NRArenaShape *create(NRArena *arena) { NRArenaShape *obj=reinterpret_cast<NRArenaShape *>(nr_object_new(NR_TYPE_ARENA_SHAPE)); obj->init(arena); + obj->key = 0; return obj; } diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index 76b541ace..14a039630 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -30,7 +30,7 @@ #include "libnr/nr-matrix.h" #include "libnr/nr-matrix-fns.h" #include "util/fixed_point.h" -#include "prefs-utils.h" +#include "preferences.h" // IIR filtering method based on: // L.J. van Vliet, I.T. Young, and P.W. Verbeek, Recursive Gaussian Derivative Filters, @@ -85,7 +85,7 @@ namespace NR { FilterGaussian::FilterGaussian() { - _deviation_x = _deviation_y = prefs_get_double_attribute("options.filtertest", "value", 1.0); + _deviation_x = _deviation_y = 0.0; } FilterPrimitive *FilterGaussian::create() @@ -545,7 +545,8 @@ int FilterGaussian::render(FilterSlot &slot, FilterUnits const &units) int const PC = NR_PIXBLOCK_BPP(in); // Subsampling constants - int const quality = prefs_get_int_attribute("options.blurquality", "value", 0); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int const quality = prefs->getInt("/options/blurquality/value"); int const x_step_l2 = _effect_subsample_step_log2(deviation_x_org, quality); int const y_step_l2 = _effect_subsample_step_log2(deviation_y_org, quality); int const x_step = 1<<x_step_l2; diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp index 1501afcbe..c099663fd 100644 --- a/src/display/nr-filter-slot.cpp +++ b/src/display/nr-filter-slot.cpp @@ -65,6 +65,9 @@ inline static int _min2(const double a, const double b) { namespace NR { FilterSlot::FilterSlot(int slots, NRArenaItem const *item) + : filterquality(FILTER_QUALITY_BEST), + _last_out(-1), + _arena_item(item) { _slot_count = ((slots > 0) ? slots : 2); _slot = new NRPixBlock*[_slot_count]; @@ -74,10 +77,6 @@ FilterSlot::FilterSlot(int slots, NRArenaItem const *item) _slot[i] = NULL; _slot_number[i] = NR_FILTER_SLOT_NOT_SET; } - - _last_out = -1; - - _arena_item = item; } FilterSlot::~FilterSlot() @@ -163,7 +162,11 @@ void FilterSlot::get_final(int slot_nr, NRPixBlock *result) { memset(NR_PIXBLOCK_PX(result), 0, size); if (fabs(trans[1]) > 1e-6 || fabs(trans[2]) > 1e-6) { - transform_bicubic(result, final_usr, trans); + if (filterquality == FILTER_QUALITY_BEST) { + transform_bicubic(result, final_usr, trans); + } else { + transform_nearest(result, final_usr, trans); + } } else if (fabs(trans[0] - 1) > 1e-6 || fabs(trans[3] - 1) > 1e-6) { scale_bicubic(result, final_usr); } else { @@ -223,7 +226,11 @@ void FilterSlot::set(int slot_nr, NRPixBlock *pb) g_warning("Memory allocation failed in NR::FilterSlot::set (transform)"); return; } - transform_bicubic(trans_pb, pb, trans); + if (filterquality == FILTER_QUALITY_BEST) { + transform_bicubic(trans_pb, pb, trans); + } else { + transform_nearest(trans_pb, pb, trans); + } nr_pixblock_release(pb); delete pb; pb = trans_pb; @@ -338,6 +345,10 @@ void FilterSlot::set_units(FilterUnits const &units) { this->units = units; } +void FilterSlot::set_quality(FilterQuality const q) { + filterquality = q; +} + } /* diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index aaf22e513..b566be10e 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -15,6 +15,7 @@ */ #include "libnr/nr-pixblock.h" +#include "display/nr-filter-types.h" #include "display/nr-filter-units.h" struct NRArenaItem; @@ -72,6 +73,9 @@ public: /** Sets the unit system to be used for the internal images. */ void set_units(FilterUnits const &units); + /** Sets the filtering quality. Affects used interpolation methods */ + void set_quality(FilterQuality const q); + private: NRPixBlock **_slot; int *_slot_number; @@ -79,6 +83,8 @@ private: int _last_out; + FilterQuality filterquality; + NRArenaItem const *_arena_item; FilterUnits units; diff --git a/src/display/nr-filter-types.h b/src/display/nr-filter-types.h index ee24840cf..a54bfa670 100644 --- a/src/display/nr-filter-types.h +++ b/src/display/nr-filter-types.h @@ -37,6 +37,14 @@ enum FilterSlotType { /* Unnamed slot is for NR::FilterSlot internal use. Passing it as * parameter to NR::FilterSlot accessors may have unforeseen consequences. */ +enum FilterQuality { + FILTER_QUALITY_BEST = 2, + FILTER_QUALITY_BETTER = 1, + FILTER_QUALITY_NORMAL = 0, + FILTER_QUALITY_WORSE = -1, + FILTER_QUALITY_WORST = -2 +}; + } /* namespace NR */ #endif // __NR_FILTER_TYPES_H__ diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 8930a74df..31aec0748 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -46,6 +46,8 @@ #include "libnr/nr-scale.h" #include "svg/svg-length.h" #include "sp-filter-units.h" +#include "preferences.h" + #if defined (SOLARIS) && (SOLARIS == 8) #include "round.h" using Inkscape::round; @@ -111,8 +113,12 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) return 1; } - Matrix trans = item->ctm; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + FilterQuality const filterquality = (FilterQuality)prefs->getInt("/options/filterquality/value"); + + Geom::Matrix trans = item->ctm; FilterSlot slot(_slot_count, item); + slot.set_quality(filterquality); Geom::Rect item_bbox; if (item->item_bbox) { @@ -130,7 +136,7 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) } Geom::Rect filter_area = filter_effect_area(item_bbox); - if (item_bbox.isEmpty()) { + if (item_bbox.area() == 0.0) { // It's no use to try and filter an empty object. return 1; } @@ -152,18 +158,19 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) units.set_automatic_resolution(false); units.set_resolution(_x_pixels, y_len); } else { - Point origo = filter_area.min(); + Geom::Point origo = filter_area.min(); origo *= trans; - Point max_i(filter_area.max()[X], filter_area.min()[Y]); + Geom::Point max_i(filter_area.max()[X], filter_area.min()[Y]); max_i *= trans; - Point max_j(filter_area.min()[X], filter_area.max()[Y]); + Geom::Point max_j(filter_area.min()[X], filter_area.max()[Y]); max_j *= trans; double i_len = sqrt((origo[X] - max_i[X]) * (origo[X] - max_i[X]) + (origo[Y] - max_i[Y]) * (origo[Y] - max_i[Y])); double j_len = sqrt((origo[X] - max_j[X]) * (origo[X] - max_j[X]) + (origo[Y] - max_j[Y]) * (origo[Y] - max_j[Y])); units.set_automatic_resolution(true); - units.set_resolution(i_len, j_len); + double const divisor = _resolution_divisor(filterquality); + units.set_resolution(i_len / divisor, j_len / divisor); } units.set_paraller(false); @@ -211,7 +218,7 @@ int Filter::render(NRArenaItem const *item, NRPixBlock *pb) return 0; } -void Filter::area_enlarge(NRRectL &bbox, Matrix const &m) { +void Filter::area_enlarge(NRRectL &bbox, Geom::Matrix const &m) { for (int i = 0 ; i < _primitive_count ; i++) { if (_primitive[i]) _primitive[i]->area_enlarge(bbox, m); } @@ -238,7 +245,7 @@ void Filter::bbox_enlarge(NRRectL &bbox) { Geom::Rect Filter::filter_effect_area(Geom::Rect const &bbox) { - Point minp, maxp; + Geom::Point minp, maxp; double len_x = bbox.max()[X] - bbox.min()[X]; double len_y = bbox.max()[Y] - bbox.min()[Y]; /* TODO: fetch somehow the object ex and em lengths */ @@ -432,6 +439,26 @@ void Filter::reset_resolution() { _y_pixels = -1; } +double Filter::_resolution_divisor(FilterQuality const quality) const { + double divisor = 1; + switch (quality) { + case FILTER_QUALITY_WORST: + divisor = 8; + break; + case FILTER_QUALITY_WORSE: + divisor = 4; + break; + case FILTER_QUALITY_NORMAL: + divisor = 2; + break; + case FILTER_QUALITY_BETTER: + case FILTER_QUALITY_BEST: + default: + break; + } + return divisor; +} + } /* namespace NR */ /* diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index 1dbdfd1ef..ae3857c65 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -144,7 +144,7 @@ public: * to be rendered so that after filtering, the original area is * drawn correctly. */ - void area_enlarge(NRRectL &area, Matrix const &m); + void area_enlarge(NRRectL &area, Geom::Matrix const &m); /** * Given an object bounding box, this function enlarges it so that * it contains the filter effect area. @@ -198,6 +198,7 @@ private: void _create_constructor_table(); void _enlarge_primitive_table(); void _common_init(); + double _resolution_divisor(FilterQuality const quality) const; }; diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 28d29b59c..02c9a9ea2 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -91,11 +91,17 @@ SvgFont::scaled_font_init (cairo_scaled_font_t *scaled_font, return CAIRO_STATUS_SUCCESS; } -unsigned int compare_them(char* s1, char* s2){ - unsigned int p=0; - while((s1[p] == s2[p]) && s1[p] != '\0' && s2[p] != '\0') p++; - if (s1[p]=='\0') return p; - else return 0; +unsigned int size_of_substring(gchar* substring, gchar* str){ + const gchar* original_substring = substring; + + while((g_utf8_get_char(substring)==g_utf8_get_char(str)) && g_utf8_get_char(substring) != 0 && g_utf8_get_char(str) != 0){ + substring = g_utf8_next_char(substring); + str = g_utf8_next_char(str); + } + if (g_utf8_get_char(substring)==0) + return substring - original_substring; + else + return 0; } cairo_status_t @@ -115,15 +121,31 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, unsigned long i; int count = 0; - char* _utf8 = (char*) utf8; + gchar* _utf8 = (gchar*) utf8; unsigned int len; - //First we findout whats the worst case number of glyphs. - while(_utf8[0] != '\0'){ - _utf8++; - count++; + bool missing; + //First we findout whats the number of glyphs needed. + while(g_utf8_get_char(_utf8) != 0){ + missing = true; + for (i=0; i < (unsigned long) this->glyphs.size(); i++){ + if ( (len = size_of_substring(this->glyphs[i]->unicode, _utf8)) ){ + //TODO: store this cluster + _utf8+=len; + count++; + missing=false; + break; + } + } + if (missing){ + //TODO: store this cluster + _utf8++; + count++; + } } +//g_warning("count is %d", count); + //We use that info to allocate memory for the glyphs *glyphs = (cairo_glyph_t*) malloc(count*sizeof(cairo_glyph_t)); @@ -134,10 +156,10 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, double x=0, y=0;//These vars store the position of the glyph within the rendered string bool is_horizontal_text = true; //TODO _utf8 = (char*) utf8; - while(_utf8[0] != '\0'){ + while(g_utf8_get_char(_utf8) != 0){ len = 0; for (i=0; i < (unsigned long) this->glyphs.size(); i++){ - if ( (len = compare_them(this->glyphs[i]->unicode, _utf8)) ){ + if ( (len = size_of_substring(this->glyphs[i]->unicode, _utf8)) ){ //check whether is there a glyph declared on the SVG document // that matches with the text string in its current position for(SPObject* node = this->font->children;previous_unicode && node;node=node->next){ @@ -167,7 +189,7 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, //advance glyph coordinates: if (is_horizontal_text) x++; else y++; - _utf8+=len; //advance 'len' chars in our string pointer + _utf8+=len; //advance 'len' bytes in our string pointer //continue; goto dirty; } @@ -180,7 +202,7 @@ dirty: //advance glyph coordinates: if (is_horizontal_text) x++; else y++; - _utf8++; //advance 1 char in our string pointer + _utf8 = g_utf8_next_char(_utf8); //advance 1 char in our string pointer } } *num_glyphs = count; diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index d82e39238..53dd6c62c 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -35,7 +35,7 @@ #include <libnr/nr-matrix-fns.h> #include <libnr/nr-matrix-ops.h> #include <libnr/nr-convex-hull.h> -#include "prefs-utils.h" +#include "preferences.h" #include "inkscape.h" #include "sodipodi-ctrlrect.h" #if ENABLE_LCMS @@ -45,6 +45,8 @@ #include "libnr/nr-blit.h" #include "display/inkscape-cairo.h" #include "debug/gdk-event-latency-tracker.h" +#include "desktop.h" +#include "sp-namedview.h" using Inkscape::Debug::GdkEventLatencyTracker; @@ -945,6 +947,10 @@ static void sp_canvas_dirty_rect(SPCanvas* canvas, int nl, int nt, int nr, int n static void sp_canvas_mark_rect(SPCanvas* canvas, int nl, int nt, int nr, int nb, uint8_t val); static int do_update (SPCanvas *canvas); +static gboolean sp_canvas_snap_watchdog_callback(gpointer data); +static void sp_canvas_snap_watchdog_set(SPCanvas *canvas, GdkEventMotion *event); +static void sp_canvas_snap_watchdog_kill(SPCanvas *canvas); + /** * Registers the SPCanvas class if necessary, and returns the type ID * associated to it. @@ -1042,6 +1048,8 @@ sp_canvas_init (SPCanvas *canvas) canvas->is_scrolling = false; + canvas->watchdog_id = 0; + canvas->watchdog_event = NULL; } /** @@ -1106,7 +1114,7 @@ static void track_latency(GdkEvent const *event) { GdkEventLatencyTracker &tracker = GdkEventLatencyTracker::default_tracker(); boost::optional<double> latency = tracker.process(event); if (latency && *latency > 2.0) { - g_warning("Event latency reached %f sec (%1.4f)", *latency, tracker.getSkew()); + //g_warning("Event latency reached %f sec (%1.4f)", *latency, tracker.getSkew()); } } @@ -1157,7 +1165,8 @@ sp_canvas_realize (GtkWidget *widget) widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gdk_window_set_user_data (widget->window, widget); - if ( prefs_get_int_attribute ("options.useextinput", "value", 1) ) + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if ( prefs->getBool("/options/useextinput/value", true) ) gtk_widget_set_events(widget, attributes.event_mask); widget->style = gtk_style_attach (widget->style, widget->window); @@ -1574,7 +1583,10 @@ static inline void request_motions(GdkWindow *w, GdkEventMotion *event) { static int sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) { - int status; + static guint32 prev_time; + static boost::optional<Geom::Point> prev_pos; + + int status; SPCanvas *canvas = SP_CANVAS (widget); track_latency((GdkEvent *)event); @@ -1584,7 +1596,52 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) if (canvas->pixmap_gc == NULL) // canvas being deleted return FALSE; - + + // Snap when speed drops below e.g. 0.1 px/msec, or when no motion events have occured for 100 msec. + // i.e. snap when we're at stand still. The speed threshold enforces snapping for tablets, which will never + // be full at stand still and might keep spitting out motion events. + + // When moving at speeds around the speed limit, Inkscape might snap for one motion event but not for the + // next, which will make the object that's being dragged jump from the snapped position to the mouse + // position and back again. That could be annoying, but I don't see an easy way around this. + + if (event->type == GDK_MOTION_NOTIFY) { + Geom::Point event_pos(event->x, event->y); + guint32 event_t = gdk_event_get_time ( (GdkEvent *) event ); + + sp_canvas_snap_watchdog_kill(canvas); + SPDesktop *dt = SP_ACTIVE_DESKTOP; + + if (prev_pos) { + Geom::Coord dist = Geom::L2(event_pos - *prev_pos); + guint32 delta_t = event_t - prev_time; + gdouble speed = delta_t > 0 ? dist/delta_t : 1000; + // std::cout << "speed = " << speed << " px/msec " << "| time passed = " << delta_t << " msec" << std::endl; + if (speed < 0.1) { + if (dt) { + dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false); + } + } else { + // We're moving fast, so postpone any snapping until the next GDK_MOTION_NOTIFY event. + if (dt) { + dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); + } + // We must snap at some point in time though, so set a watchdog timer at 100 msec from + // now, just in case there's no future motion event that's under the speed limit. + sp_canvas_snap_watchdog_set(canvas, event); + } + } else { + // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog + if (dt) { + dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(true); + } + sp_canvas_snap_watchdog_set(canvas, event); + } + + prev_pos = event_pos; + prev_time = event_t; + } + canvas->state = event->state; pick_current_item (canvas, (GdkEvent *) event); @@ -1597,6 +1654,43 @@ sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) return status; } +gboolean sp_canvas_snap_watchdog_callback(gpointer data) +{ + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (dt) { + dt->namedview->snap_manager.snapprefs.setSnapPostponedGlobally(false); + } + + SPCanvas *canvas = reinterpret_cast<SPCanvas *>(data); + emit_event(canvas, canvas->watchdog_event); + gdk_event_free(canvas->watchdog_event); + canvas->watchdog_event = NULL; + canvas->watchdog_id = 0; + + return FALSE; +} + +void sp_canvas_snap_watchdog_set(SPCanvas *canvas, GdkEventMotion *event) +{ + g_assert(canvas->watchdog_id == 0); + canvas->watchdog_id = g_timeout_add(100, &sp_canvas_snap_watchdog_callback, canvas); + g_assert(canvas->watchdog_event == NULL); + canvas->watchdog_event = gdk_event_copy( (GdkEvent *) event); +} + +void sp_canvas_snap_watchdog_kill(SPCanvas *canvas) +{ + if (canvas->watchdog_id) { + g_source_remove(canvas->watchdog_id); // Kill the watchdog + canvas->watchdog_id = 0; + } + + if (canvas->watchdog_event) { + gdk_event_free(canvas->watchdog_event); + canvas->watchdog_event = NULL; + } +} + static void sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, int draw_x1, int draw_y1, int draw_x2, int draw_y2, int sw) { @@ -1635,7 +1729,8 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, #if ENABLE_LCMS cmsHTRANSFORM transf = 0; - long long int fromDisplay = prefs_get_int_attribute_limited( "options.displayprofile", "from_display", 0, 0, 1 ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); if ( fromDisplay ) { transf = Inkscape::colorprofile_get_display_per( canvas->cms_key ? *(canvas->cms_key) : "" ); } else { diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 60bda5818..8b0958ca5 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -75,7 +75,7 @@ struct SPCanvasItem : public GtkObject { SPCanvasItem *parent; double x1, y1, x2, y2; - NR::Rect bounds; + Geom::Rect bounds; Geom::Matrix xform; }; @@ -193,6 +193,9 @@ struct SPCanvas { Geom::Rect getViewbox() const; NR::IRect getViewboxIntegers() const; + + guint watchdog_id; + GdkEvent *watchdog_event; }; GtkWidget *sp_canvas_new_aa(); diff --git a/src/display/sp-ctrlquadr.cpp b/src/display/sp-ctrlquadr.cpp index 31766c3c2..b307684e5 100644 --- a/src/display/sp-ctrlquadr.cpp +++ b/src/display/sp-ctrlquadr.cpp @@ -97,7 +97,7 @@ sp_ctrlquadr_render (SPCanvasItem *item, SPCanvasBuf *buf) { SPCtrlQuadr *cq = SP_CTRLQUADR (item); - //NR::Rect area (NR::Point(buf->rect.x0, buf->rect.y0), NR::Point(buf->rect.x1, buf->rect.y1)); + //Geom::Rect area (Geom::Point(buf->rect.x0, buf->rect.y0), Geom::Point(buf->rect.x1, buf->rect.y1)); if (!buf->ct) return; |
