Code

Store cached icons to disk between runs, and invalidate/purge as needed.
[inkscape.git] / src / live_effects / lpe-perp_bisector.cpp
1 #define INKSCAPE_LPE_PERP_BISECTOR_CPP
2 /** \file
3  * LPE <perp_bisector> implementation.
4  */
5 /*
6  * Authors:
7  *   Maximilian Albert
8  *   Johan Engelen
9  *
10  * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
11  * Copyright (C) Maximilin Albert 2008 <maximilian.albert@gmail.com>
12  *
13  * Released under GNU GPL, read the file 'COPYING' for more information
14  */
16 #include "live_effects/lpe-perp_bisector.h"
17 #include "display/curve.h"
18 #include "sp-path.h"
19 #include "line-geometry.h"
20 #include "sp-lpe-item.h"
21 #include <2geom/path.h>
23 namespace Inkscape {
24 namespace LivePathEffect {
25 namespace PB {
27 class KnotHolderEntityEnd : public LPEKnotHolderEntity {
28 public:
29     void bisector_end_set(Geom::Point const &p, bool left = true);
30 };
32 class KnotHolderEntityLeftEnd : public KnotHolderEntityEnd {
33 public:
34     virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
35     virtual Geom::Point knot_get();
36 };
38 class KnotHolderEntityRightEnd : public KnotHolderEntityEnd {
39 public:
40     virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
41     virtual Geom::Point knot_get();
42 };
44 // TODO: Make this more generic
45 static LPEPerpBisector *
46 get_effect(SPItem *item)
47 {
48     Effect *effect = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item));
49     if (effect->effectType() != PERP_BISECTOR) {
50         g_print ("Warning: Effect is not of type LPEPerpBisector!\n");
51         return NULL;
52     }
53     return static_cast<LPEPerpBisector *>(effect);
54 }
56 Geom::Point
57 KnotHolderEntityLeftEnd::knot_get() {
58     Inkscape::LivePathEffect::LPEPerpBisector *lpe = get_effect(item);
59     return Geom::Point(lpe->C);
60 }
62 Geom::Point
63 KnotHolderEntityRightEnd::knot_get() {
64     Inkscape::LivePathEffect::LPEPerpBisector *lpe = get_effect(item);
65     return Geom::Point(lpe->D);
66 }
68 void
69 KnotHolderEntityEnd::bisector_end_set(Geom::Point const &p, bool left) {
70     Inkscape::LivePathEffect::LPEPerpBisector *lpe =
71         dynamic_cast<Inkscape::LivePathEffect::LPEPerpBisector *> (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)));
72     if (!lpe) return;
74     Geom::Point const s = snap_knot_position(p);
76     double lambda = Geom::nearest_point(s, lpe->M, lpe->perp_dir);
77     if (left) {
78         lpe->C = lpe->M + lpe->perp_dir * lambda;
79         lpe->length_left.param_set_value(lambda);
80     } else {
81         lpe->D = lpe->M + lpe->perp_dir * lambda;
82         lpe->length_right.param_set_value(-lambda);
83     }
85     // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
86     sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), true, true);
87 }
89 void
90 KnotHolderEntityLeftEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) {
91     bisector_end_set(p);
92 }
94 void
95 KnotHolderEntityRightEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) {
96     bisector_end_set(p, false);
97 }
99 } //namescape PB
101 LPEPerpBisector::LPEPerpBisector(LivePathEffectObject *lpeobject) :
102     Effect(lpeobject),
103     length_left(_("Length left"), _("Specifies the left end of the bisector"), "length-left", &wr, this, 200),
104     length_right(_("Length right"), _("Specifies the right end of the bisector"), "length-right", &wr, this, 200),
105     A(0,0), B(0,0), M(0,0), C(0,0), D(0,0), perp_dir(0,0)
107     show_orig_path = true;
109     // register all your parameters here, so Inkscape knows which parameters this effect has:
110     registerParameter( dynamic_cast<Parameter *>(&length_left) );
111     registerParameter( dynamic_cast<Parameter *>(&length_right) );
113     registerKnotHolderHandle(new PB::KnotHolderEntityLeftEnd(), _("Adjust the bisector's \"left\" end"));
114     registerKnotHolderHandle(new PB::KnotHolderEntityRightEnd(), _("Adjust the bisector's \"right\" end"));
117 LPEPerpBisector::~LPEPerpBisector()
121 void
122 LPEPerpBisector::doOnApply (SPLPEItem */*lpeitem*/)
124     /* make the path a straight line */
125     /**
126     SPCurve* curve = sp_path_get_curve_for_edit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()?
128     Geom::Point A(curve->first_point());
129     Geom::Point B(curve->last_point());
131     SPCurve *c = new SPCurve();
132     c->moveto(A);
133     c->lineto(B);
134     // TODO: Why doesn't sp_path_set_original_curve(SP_PATH(lpeitem), c, TRUE, true) work?
135     SP_PATH(lpeitem)->original_curve = c->ref();
136     c->unref();
137     **/
141 Geom::Piecewise<Geom::D2<Geom::SBasis> >
142 LPEPerpBisector::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
144     using namespace Geom;
146     Piecewise<D2<SBasis> > output;
148     A = pwd2_in.firstValue();
149     B = pwd2_in.lastValue();
150     M = (A + B)/2;
152     perp_dir = unit_vector((B - A).ccw());
154     C = M + perp_dir * length_left;
155     D = M - perp_dir * length_right;
157     output = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(C[X], D[X]), Linear(C[Y], D[Y])));
159     return output;
162 /* ######################## */
164 } //namespace LivePathEffect
165 } /* namespace Inkscape */
167 /*
168   Local Variables:
169   mode:c++
170   c-file-style:"stroustrup"
171   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
172   indent-tabs-mode:nil
173   fill-column:99
174   End:
175 */
176 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :