From: cilix42 Date: Tue, 19 Aug 2008 19:37:49 +0000 (+0000) Subject: Make lpe-ruler work for arbitrary paths, not just line segments X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=83a81a58dfe7ce42270f2883ce4c24ee1b7442ed;p=inkscape.git Make lpe-ruler work for arbitrary paths, not just line segments --- diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index 4b4175296..52ccc29e1 100644 --- a/src/live_effects/lpe-ruler.cpp +++ b/src/live_effects/lpe-ruler.cpp @@ -7,7 +7,6 @@ /* * Authors: * Maximilian Albert - * Johan Engelen * * Copyright (C) Maximilian Albert 2008 * @@ -16,6 +15,7 @@ #include "live_effects/lpe-ruler.h" #include <2geom/piecewise.h> +#include <2geom/sbasis-geometric.h> #include "inkscape.h" #include "desktop.h" @@ -29,6 +29,14 @@ static const Util::EnumData MarkDirData[] = { }; static const Util::EnumDataConverter MarkDirTypeConverter(MarkDirData, sizeof(MarkDirData)/sizeof(*MarkDirData)); +static const Util::EnumData BorderMarkData[] = { + {BORDERMARK_NONE , N_("None"), "none"}, + {BORDERMARK_START , N_("Start"), "start"}, + {BORDERMARK_END , N_("End"), "end"}, + {BORDERMARK_BOTH , N_("Both"), "both"}, +}; +static const Util::EnumDataConverter BorderMarkTypeConverter(BorderMarkData, sizeof(BorderMarkData)/sizeof(*BorderMarkData)); + LPERuler::LPERuler(LivePathEffectObject *lpeobject) : Effect(lpeobject), mark_distance(_("Mark distance"), _("Distance between successive ruler marks"), "mark_distance", &wr, this, 20.0), @@ -38,7 +46,7 @@ LPERuler::LPERuler(LivePathEffectObject *lpeobject) : shift(_("Shift marks by"), _("Shift marks by this many steps"), "shift", &wr, this, 0), mark_dir(_("Mark direction"), _("Direction of marks (when viewing along the path from start to end)"), "mark_dir", MarkDirTypeConverter, &wr, this, MARKDIR_LEFT), offset(_("Offset"), _("Offset of first mark"), "offset", &wr, this, 0.0), - draw_border_marks(_("Draw border marks?"), _("Check this to draw marks at the beginning and end of the path (even if this means that the distance to adjacent marks is smaller than usual)"), "draw_border_marks", &wr, this, true) + border_marks(_("Border marks"), _("Choose whether to draw marks at the beginning and end of the path"), "border_marks", BorderMarkTypeConverter, &wr, this, BORDERMARK_BOTH) { registerParameter(dynamic_cast(&mark_distance)); registerParameter(dynamic_cast(&mark_length)); @@ -47,7 +55,7 @@ LPERuler::LPERuler(LivePathEffectObject *lpeobject) : registerParameter(dynamic_cast(&shift)); registerParameter(dynamic_cast(&offset)); registerParameter(dynamic_cast(&mark_dir)); - registerParameter(dynamic_cast(&draw_border_marks)); + registerParameter(dynamic_cast(&border_marks)); major_mark_steps.param_make_integer(); major_mark_steps.param_set_range(1, 1000); @@ -67,7 +75,7 @@ Geom::Point LPERuler::n_major; Geom::Point LPERuler::n_minor; Geom::Piecewise > -LPERuler::ruler_mark(Geom::Point const &A, Geom::Point const &n, MarkType marktype) +LPERuler::ruler_mark(Geom::Point const &A, Geom::Point const &n, MarkType const &marktype) { using namespace Geom; @@ -78,7 +86,7 @@ LPERuler::ruler_mark(Geom::Point const &A, Geom::Point const &n, MarkType markty switch (marktype) { case MARK_MAJOR: C = A; - D = A + mark_length * n; + D = A + n_major; if (mark_dir == MARKDIR_BOTH) C -= n_major; break; @@ -102,14 +110,14 @@ LPERuler::doEffect_pwd2 (Geom::Piecewise > const & pwd2_i { using namespace Geom; - Point A(pwd2_in.firstValue()); - Point B(pwd2_in.lastValue()); - double path_length = L2(B - A); + Piecewise > pwd2_arclength = arc_length_parametrization(pwd2_in); + Point A(pwd2_arclength.firstValue()); + Point B(pwd2_arclength.lastValue()); + double path_length = Geom::length(pwd2_arclength); - Piecewise >output(D2(Linear(A[X], B[X]), Linear(A[Y], B[Y]))); + Piecewise > n = -rot90(unitVector(derivative(pwd2_arclength))); + Piecewise >output(pwd2_arclength); - Point dir(unit_vector(B - A)); - Point n(-rot90(dir)); if (mark_dir == MARKDIR_RIGHT) { n *= -1.0; } @@ -119,23 +127,21 @@ LPERuler::doEffect_pwd2 (Geom::Piecewise > const & pwd2_i const int j_shift = static_cast(shift) % mminterval; /* draw the ruler */ - if (draw_border_marks && (offset != 0.0 || j_shift != 0)) - output.concat (ruler_mark(A, n, MARK_MAJOR)); - for (double i = offset; i < path_length; i += mark_distance, ++j) { + if ((border_marks == BORDERMARK_START || border_marks == BORDERMARK_BOTH) && (offset != 0.0 || j_shift != 0)) + output.concat (ruler_mark(A, n.firstValue(), MARK_MAJOR)); + for (double t = offset; t < path_length; t += mark_distance, ++j) { if ((j % mminterval) == j_shift) { - output.concat (ruler_mark(A + dir * i, n, MARK_MAJOR)); + output.concat (ruler_mark(pwd2_arclength(t), n(t), MARK_MAJOR)); } else { - output.concat (ruler_mark(A + dir * i, n, MARK_MINOR)); + output.concat (ruler_mark(pwd2_arclength(t), n(t), MARK_MINOR)); } } - if (draw_border_marks) - output.concat (ruler_mark(B, n, MARK_MAJOR)); + if (border_marks == BORDERMARK_END || border_marks == BORDERMARK_BOTH) + output.concat (ruler_mark(B, n.lastValue(), MARK_MAJOR)); return output; } -/* ######################## */ - } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-ruler.h b/src/live_effects/lpe-ruler.h index 0d5bf29e0..6a7a7282b 100644 --- a/src/live_effects/lpe-ruler.h +++ b/src/live_effects/lpe-ruler.h @@ -34,6 +34,13 @@ enum MarkDirType { MARKDIR_BOTH, }; +enum BorderMarkType { + BORDERMARK_NONE, + BORDERMARK_START, + BORDERMARK_END, + BORDERMARK_BOTH, +}; + class LPERuler : public Effect { public: LPERuler(LivePathEffectObject *lpeobject); @@ -42,7 +49,7 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); private: - Geom::Piecewise > ruler_mark(Geom::Point const &A, Geom::Point const &n, MarkType marktype); + Geom::Piecewise > ruler_mark(Geom::Point const &A, Geom::Point const &n, MarkType const &marktype); ScalarParam mark_distance; ScalarParam mark_length; @@ -51,7 +58,7 @@ private: ScalarParam shift; EnumParam mark_dir; ScalarParam offset; - BoolParam draw_border_marks; + EnumParam border_marks; static Geom::Point n_major, n_minor; // used for internal computations