X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Flive_effects%2Flpe-ruler.cpp;h=e51b03d15bf43e892c9caed579e9f7290f6269cd;hb=a0fc93054e8c588871e8b351074aaf528bd4a89e;hp=4b41752967b6e41df92b098757565a16c89e7416;hpb=6734d1bacf7a9fc2d5e54e098120a2a94752839c;p=inkscape.git diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index 4b4175296..e51b03d15 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,9 +15,11 @@ #include "live_effects/lpe-ruler.h" #include <2geom/piecewise.h> +#include <2geom/sbasis-geometric.h> #include "inkscape.h" #include "desktop.h" + namespace Inkscape { namespace LivePathEffect { @@ -29,17 +30,27 @@ 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), - 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), - 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) + 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), + 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), + 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(&unit)); registerParameter(dynamic_cast(&mark_distance)); registerParameter(dynamic_cast(&mark_length)); registerParameter(dynamic_cast(&minor_mark_length)); @@ -47,7 +58,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,18 +78,28 @@ 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; - n_major = mark_length * n; - n_minor = minor_mark_length * n; + gboolean success; + double real_mark_length = mark_length; + success = sp_convert_distance(&real_mark_length, unit, &sp_unit_get_by_id(SP_UNIT_PX)); + double real_minor_mark_length = minor_mark_length; + success = sp_convert_distance(&real_minor_mark_length, unit, &sp_unit_get_by_id(SP_UNIT_PX)); + + n_major = real_mark_length * n; + n_minor = real_minor_mark_length * n; + if (mark_dir == MARKDIR_BOTH) { + n_major = n_major * 0.5; + n_minor = n_minor * 0.5; + } Point C, D; 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,40 +123,71 @@ 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 >output(D2(Linear(A[X], B[X]), Linear(A[Y], B[Y]))); - - Point dir(unit_vector(B - A)); - Point n(-rot90(dir)); - if (mark_dir == MARKDIR_RIGHT) { - n *= -1.0; - } - - int j = 0; const int mminterval = static_cast(major_mark_steps); - 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 ((j % mminterval) == j_shift) { - output.concat (ruler_mark(A + dir * i, n, MARK_MAJOR)); + const int i_shift = static_cast(shift) % mminterval; + int sign = (mark_dir == MARKDIR_RIGHT ? 1 : -1 ); + + Piecewise >output(pwd2_in); + Piecewise >speed = derivative(pwd2_in); + Piecewise arclength = arcLengthSb(pwd2_in); + double totlength = arclength.lastValue(); + + //find at which times to draw a mark: + std::vector s_cuts; + + double real_mark_distance = mark_distance; + gboolean success = sp_convert_distance(&real_mark_distance, unit, &sp_unit_get_by_id(SP_UNIT_PX)); + + double real_offset = offset; + success = sp_convert_distance(&real_offset, unit, &sp_unit_get_by_id(SP_UNIT_PX)); + for (double s = real_offset; s > roots = multi_roots(arclength, s_cuts); + std::vector t_cuts; + for (unsigned v=0; v0) + t_cuts.push_back(roots[v][0]); + } + //draw the marks + for (unsigned i=0; i 1 && + speed.segs.back()[X].size() <= 1 && + speed.segs.back()[Y].size() <= 1 && + speed.segs.back()[X].tailError(0) <= 1e-10 && + speed.segs.back()[Y].tailError(0) <= 1e-10 + ){ + n = rot90(unit_vector(speed.segs[speed.segs.size()-2].at1()))*sign; + } + output.concat (ruler_mark(A, n, MARK_MAJOR)); + } return output; } -/* ######################## */ - } //namespace LivePathEffect } /* namespace Inkscape */