diff options
| author | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-05-12 23:59:28 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-05-12 23:59:28 +0000 |
| commit | 8e303a547b23758ec6c1accee912185f25718c03 (patch) | |
| tree | 91c7d93b4a23d02550674675afdbbbb24a47e9d5 /src | |
| parent | Rename "Tags" to "Selection sets" to avoid confusion with a global tagging sy... (diff) | |
| download | inkscape-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.cpp | 24 | ||||
| -rwxr-xr-x | src/live_effects/lpe-jointype.h | 2 | ||||
| -rw-r--r-- | src/live_effects/pathoutlineprovider.cpp | 92 | ||||
| -rw-r--r-- | src/live_effects/pathoutlineprovider.h | 14 |
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); } |
