summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiam P. White <inkscapebronyat-signgmaildotcom>2014-05-12 23:59:28 +0000
committerLiam P. White <inkscapebronyat-signgmaildotcom>2014-05-12 23:59:28 +0000
commit8e303a547b23758ec6c1accee912185f25718c03 (patch)
tree91c7d93b4a23d02550674675afdbbbb24a47e9d5 /src
parentRename "Tags" to "Selection sets" to avoid confusion with a global tagging sy... (diff)
downloadinkscape-8e303a547b23758ec6c1accee912185f25718c03.tar.gz
inkscape-8e303a547b23758ec6c1accee912185f25718c03.zip
Commit patch for "leaned" cap. Thanks Jabiertxof!
(bzr r13090.1.78)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-jointype.cpp24
-rwxr-xr-xsrc/live_effects/lpe-jointype.h2
-rw-r--r--src/live_effects/pathoutlineprovider.cpp92
-rw-r--r--src/live_effects/pathoutlineprovider.h14
4 files changed, 105 insertions, 27 deletions
diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp
index 0c1813970..b0a6e845b 100644
--- a/src/live_effects/lpe-jointype.cpp
+++ b/src/live_effects/lpe-jointype.cpp
@@ -41,10 +41,11 @@ static const Util::EnumData<unsigned> JoinTypeData[] = {
};
static const Util::EnumData<unsigned> CapTypeData[] = {
- {butt_straight, N_("Butt"), "butt"},
- {butt_round, N_("Rounded"), "round"},
- {butt_square, N_("Square"), "square"},
- {butt_pointy, N_("Peak"), "peak"}
+ {BUTT_STRAIGHT, N_("Butt"), "butt"},
+ {BUTT_ROUND, N_("Rounded"), "round"},
+ {BUTT_SQUARE, N_("Square"), "square"},
+ {BUTT_POINTY, N_("Peak"), "peak"},
+ {BUTT_LEANED, N_("Leaned"), "leaned"}
};
static const Util::EnumDataConverter<unsigned> CapTypeConverter(CapTypeData, sizeof(CapTypeData)/sizeof(*CapTypeData));
@@ -55,6 +56,8 @@ LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) :
line_width(_("Line width"), _("Thickness of the stroke"), "line_width", &wr, this, 1.),
linecap_type(_("Line cap"), _("The end shape of the stroke"), "linecap_type", CapTypeConverter, &wr, this, butt_straight),
linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED),
+ start_lean(_("Start path lean"), _("Start path lean"), "start_lean", &wr, this, 0.),
+ end_lean(_("End path lean"), _("End path lean"), "end_lean", &wr, this, 0.),
miter_limit(_("Miter limit:"), _("Maximum length of the miter join (in units of stroke width)"), "miter_limit", &wr, this, 100.),
attempt_force_join(_("Force miter"), _("Overrides the miter limit and forces a join."), "attempt_force_join", &wr, this, true)
{
@@ -62,9 +65,17 @@ LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) :
registerParameter( dynamic_cast<Parameter *>(&linecap_type) );
registerParameter( dynamic_cast<Parameter *>(&line_width) );
registerParameter( dynamic_cast<Parameter *>(&linejoin_type) );
+ registerParameter( dynamic_cast<Parameter *>(&start_lean) );
+ registerParameter( dynamic_cast<Parameter *>(&end_lean) );
registerParameter( dynamic_cast<Parameter *>(&miter_limit) );
registerParameter( dynamic_cast<Parameter *>(&attempt_force_join) );
was_initialized = false;
+ start_lean.param_set_range(-1,1);
+ start_lean.param_set_increments(0.1, 0.1);
+ start_lean.param_set_digits(4);
+ end_lean.param_set_range(-1,1);
+ end_lean.param_set_increments(0.1, 0.1);
+ end_lean.param_set_digits(4);
}
LPEJoinType::~LPEJoinType()
@@ -163,9 +174,10 @@ void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem)
//wrapper around it.
std::vector<Geom::Path> LPEJoinType::doEffect_path(std::vector<Geom::Path> const & path_in)
{
- return Outline::PathVectorOutline(path_in, line_width, static_cast<ButtType>(linecap_type.get_value()),
+ return Outline::PathVectorOutline(path_in, line_width, static_cast<ButtTypeMod>(linecap_type.get_value()),
static_cast<LineJoinType>(linejoin_type.get_value()),
- (attempt_force_join ? std::numeric_limits<double>::max() : miter_limit));
+ (attempt_force_join ? std::numeric_limits<double>::max() : miter_limit),
+ start_lean/2 ,end_lean/2);
}
} //namespace LivePathEffect
diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h
index db113c66a..7ebce1c7e 100755
--- a/src/live_effects/lpe-jointype.h
+++ b/src/live_effects/lpe-jointype.h
@@ -32,6 +32,8 @@ private:
ScalarParam line_width;
EnumParam<unsigned> linecap_type;
EnumParam<unsigned> linejoin_type;
+ ScalarParam start_lean;
+ ScalarParam end_lean;
ScalarParam miter_limit;
BoolParam attempt_force_join;
bool was_initialized;
diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp
index 9ff896f84..d6e0ce7ea 100644
--- a/src/live_effects/pathoutlineprovider.cpp
+++ b/src/live_effects/pathoutlineprovider.cpp
@@ -586,7 +586,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double
}
Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join,
- ButtType butt, double miter_lim, bool extrapolate)
+ ButtTypeMod butt, double miter_lim, bool extrapolate, double start_lean, double end_lean)
{
Geom::PathVector path_out;
@@ -610,13 +610,13 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
//add in our line caps
if (!path_in[i].closed()) {
switch (butt) {
- case butt_straight:
+ case BUTT_STRAIGHT:
pb.lineTo(against_direction.initialPoint());
break;
- case butt_round:
+ case BUTT_ROUND:
pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, against_direction.initialPoint() );
break;
- case butt_pointy: {
+ case BUTT_POINTY: {
Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.);
double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
Geom::Point midpoint = 0.5 * (with_direction.finalPoint() + against_direction.initialPoint()) + radius*end_deriv;
@@ -624,7 +624,7 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
pb.lineTo(against_direction.initialPoint());
break;
}
- case butt_square: {
+ case BUTT_SQUARE: {
Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.);
double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
pb.lineTo(with_direction.finalPoint() + radius*end_deriv);
@@ -632,6 +632,15 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
pb.lineTo(against_direction.initialPoint());
break;
}
+ case BUTT_LEANED: {
+ Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.);
+ double maxRadius = (end_lean+0.5) * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
+ double minRadius = ((end_lean*-1)+0.5) * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint());
+ pb.lineTo(with_direction.finalPoint() + maxRadius*end_deriv);
+ pb.lineTo(against_direction.initialPoint() + minRadius*end_deriv);
+ pb.lineTo(against_direction.initialPoint());
+ break;
+ }
}
} else {
pb.moveTo(against_direction.initialPoint());
@@ -642,13 +651,13 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
//cap (if necessary)
if (!path_in[i].closed()) {
switch (butt) {
- case butt_straight:
+ case BUTT_STRAIGHT:
pb.lineTo(with_direction.initialPoint());
break;
- case butt_round:
+ case BUTT_ROUND:
pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, with_direction.initialPoint() );
break;
- case butt_pointy: {
+ case BUTT_POINTY: {
Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.);
double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
Geom::Point midpoint = 0.5 * (against_direction.finalPoint() + with_direction.initialPoint()) + radius*end_deriv;
@@ -656,7 +665,7 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
pb.lineTo(with_direction.initialPoint());
break;
}
- case butt_square: {
+ case BUTT_SQUARE: {
Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.);
double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
pb.lineTo(against_direction.finalPoint() + radius*end_deriv);
@@ -664,6 +673,15 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
pb.lineTo(with_direction.initialPoint());
break;
}
+ case BUTT_LEANED: {
+ Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.);
+ double maxRadius = (start_lean+0.5) * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
+ double minRadius = ((start_lean*-1)+0.5) * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint());
+ pb.lineTo(against_direction.finalPoint() + minRadius*end_deriv);
+ pb.lineTo(with_direction.initialPoint() + maxRadius*end_deriv);
+ pb.lineTo(with_direction.initialPoint());
+ break;
+ }
}
}
pb.flush();
@@ -674,9 +692,29 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
} else {
Path p = Path();
Path outlinepath = Path();
-
+ ButtType original_butt;
+ switch (butt) {
+ case BUTT_STRAIGHT:
+ original_butt = butt_straight;
+ break;
+ case BUTT_ROUND:
+ original_butt = butt_round;
+ break;
+ case butt_pointy: {
+ original_butt = butt_pointy;
+ break;
+ }
+ case BUTT_SQUARE: {
+ original_butt = butt_square;
+ break;
+ }
+ case BUTT_LEANED: {
+ original_butt = butt_straight;
+ break;
+ }
+ }
p.LoadPath(path_in[i], Geom::Affine(), false, false);
- p.Outline(&outlinepath, line_width / 2, static_cast<join_typ>(join), butt, miter_lim);
+ p.Outline(&outlinepath, line_width / 2, static_cast<join_typ>(join), original_butt, miter_lim);
Geom::PathVector *pv_p = outlinepath.MakePathVector();
//somewhat hack-ish
path_out.push_back( (*pv_p)[0].reverse() );
@@ -686,8 +724,8 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width,
return path_out;
}
-Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtType linecap_type,
- LineJoinType linejoin_type, double miter_limit)
+Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtTypeMod linecap_type,
+ LineJoinType linejoin_type, double miter_limit, double start_lean, double end_lean)
{
std::vector<Geom::Path> path_out = std::vector<Geom::Path>();
if (path_in.empty()) {
@@ -702,9 +740,30 @@ Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line
#define miter_lim fabs(line_width * miter_limit)
//magic!
+ ButtType original_butt;
+ switch (linecap_type) {
+ case BUTT_STRAIGHT:
+ original_butt = butt_straight;
+ break;
+ case BUTT_ROUND:
+ original_butt = butt_round;
+ break;
+ case butt_pointy: {
+ original_butt = butt_pointy;
+ break;
+ }
+ case BUTT_SQUARE: {
+ original_butt = butt_square;
+ break;
+ }
+ case BUTT_LEANED: {
+ original_butt = butt_straight;
+ break;
+ }
+ }
if (linejoin_type <= 2) {
p.Outline(&outlinepath, line_width / 2, static_cast<join_typ>(linejoin_type),
- linecap_type, miter_lim);
+ original_butt, miter_lim);
//fix memory leak
std::vector<Geom::Path> *pv_p = outlinepath.MakePathVector();
path_out = *pv_p;
@@ -713,12 +772,11 @@ Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line
} else if (linejoin_type == 3) {
//reflected arc join
path_out = outlinePath(path_in, line_width, static_cast<LineJoinType>(linejoin_type),
- linecap_type , miter_lim, false);
+ linecap_type , miter_lim, false, start_lean, end_lean);
} else if (linejoin_type == 4) {
//extrapolated arc join
- path_out = outlinePath(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim, true);
-
+ path_out = outlinePath(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim, true, start_lean, end_lean);
}
#undef miter_lim
diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h
index 0ee0f261e..272c93a49 100644
--- a/src/live_effects/pathoutlineprovider.h
+++ b/src/live_effects/pathoutlineprovider.h
@@ -11,7 +11,13 @@ enum LineJoinType {
LINEJOIN_REFLECTED,
LINEJOIN_EXTRAPOLATED
};
-
+enum ButtTypeMod {
+ BUTT_STRAIGHT,
+ BUTT_ROUND,
+ BUTT_SQUARE,
+ BUTT_POINTY,
+ BUTT_LEANED
+};
namespace Geom
{
Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in);
@@ -21,11 +27,11 @@ namespace Geom
namespace Outline
{
unsigned bezierOrder (const Geom::Curve* curve_in);
- std::vector<Geom::Path> PathVectorOutline(std::vector<Geom::Path> const & path_in, double line_width, ButtType linecap_type,
- LineJoinType linejoin_type, double miter_limit);
+ std::vector<Geom::Path> PathVectorOutline(std::vector<Geom::Path> const & path_in, double line_width, ButtTypeMod linecap_type,
+ LineJoinType linejoin_type, double miter_limit, double start_lean = 0, double end_lean = 0);
/*Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join,
- ButtType butt, double miter_lim, bool extrapolate = false);*/
+ ButtTypeMod butt, double miter_lim, bool extrapolate = false);*/
Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit);
}