summaryrefslogtreecommitdiffstats
path: root/src/sp-shape.cpp
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2008-07-07 12:29:23 +0000
committerjohanengelen <johanengelen@users.sourceforge.net>2008-07-07 12:29:23 +0000
commite2a4ff772b2ac0a00018b6d405a717e6f08a7ea1 (patch)
tree8f260938ca9ed2eac4d8ce6a23b1052b579b1e2c /src/sp-shape.cpp
parentchange part of calligraphic/eraser code to 2geom. (diff)
downloadinkscape-e2a4ff772b2ac0a00018b6d405a717e6f08a7ea1.tar.gz
inkscape-e2a4ff772b2ac0a00018b6d405a717e6f08a7ea1.zip
fix orientation of markers
(bzr r6205)
Diffstat (limited to 'src/sp-shape.cpp')
-rw-r--r--src/sp-shape.cpp78
1 files changed, 40 insertions, 38 deletions
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index 5fee7cc48..39c1f87a4 100644
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
@@ -588,11 +588,6 @@ sp_shape_marker_get_transform(SPShape const *shape, NArtBpath const *bp)
*
* \see sp_shape_marker_update_marker_view.
*
- * \param p Point where the marker should be placed.
- * \param t1 Tangent of end of curvesegment before marker
- * \param t2 Tangent of start of curvesegment after marker
- * \return Transform matrix.
- *
* From SVG spec:
* The axes of the temporary new user coordinate system are aligned according to the orient attribute on the 'marker'
* element and the slope of the curve at the given vertex. (Note: if there is a discontinuity at a vertex, the slope
@@ -600,10 +595,16 @@ sp_shape_marker_get_transform(SPShape const *shape, NArtBpath const *bp)
* determined, the slope is assumed to be zero.)
*/
Geom::Matrix
-sp_shape_marker_get_transform(Geom::Point & p, Geom::Point & t1, Geom::Point & t2)
+sp_shape_marker_get_transform(Geom::Curve const & c1, Geom::Curve const & c2)
{
- double const angle1 = Geom::atan2(t1);
- double const angle2 = Geom::atan2(t2);
+ Geom::Point p = c1.pointAt(1);
+ Geom::Curve * c1_reverse = c1.reverse();
+ Geom::Point tang1 = - c1_reverse->unitTangentAt(0);
+ delete c1_reverse;
+ Geom::Point tang2 = c2.unitTangentAt(0);
+
+ double const angle1 = Geom::atan2(tang1);
+ double const angle2 = Geom::atan2(tang2);
double ret_angle;
ret_angle = .5 * (angle1 + angle2);
@@ -620,6 +621,28 @@ sp_shape_marker_get_transform(Geom::Point & p, Geom::Point & t1, Geom::Point & t
return Geom::Rotate(ret_angle) * Geom::Translate(p);
}
+Geom::Matrix
+sp_shape_marker_get_transform_at_start(Geom::Curve const & c)
+{
+ Geom::Point p = c.pointAt(0);
+ Geom::Point tang = c.unitTangentAt(0);
+
+ double const angle = Geom::atan2(tang);
+
+ return Geom::Rotate(angle) * Geom::Translate(p);
+}
+Geom::Matrix
+sp_shape_marker_get_transform_at_end(Geom::Curve const & c)
+{
+ Geom::Point p = c.pointAt(1);
+ Geom::Curve * c_reverse = c.reverse();
+ Geom::Point tang = - c_reverse->unitTangentAt(0);
+ delete c_reverse;
+
+ double const angle = Geom::atan2(tang);
+
+ return Geom::Rotate(angle) * Geom::Translate(p);
+}
/**
* Updates the instances (views) of a given marker in a shape.
@@ -643,9 +666,7 @@ sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai)
Geom::PathVector const & pathv = shape->curve->get_pathvector();
for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
if ( shape->marker[SP_MARKER_LOC_START] ) {
- Geom::Point p = path_it->front().pointAt(0);
- Geom::Point tang = path_it->front().unitTangentAt(0);
- Geom::Matrix const m (sp_shape_marker_get_transform(p, tang, tang));
+ Geom::Matrix const m (sp_shape_marker_get_transform_at_start(path_it->front()));
sp_marker_show_instance ((SPMarker* ) shape->marker[SP_MARKER_LOC_START], ai,
NR_ARENA_ITEM_GET_KEY(ai) + SP_MARKER_LOC_START, start_pos, m,
style->stroke_width.computed);
@@ -661,10 +682,7 @@ sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai)
* Loop to end_default (so including closing segment), because when a path is closed,
* there should be a midpoint marker between last segment and closing straight line segment
*/
- Geom::Point p = curve_it1->pointAt(1);
- Geom::Point tang1 = curve_it1->unitTangentAt(1);
- Geom::Point tang2 = curve_it2->unitTangentAt(0);
- Geom::Matrix const m (sp_shape_marker_get_transform(p, tang1, tang2));
+ Geom::Matrix const m (sp_shape_marker_get_transform(*curve_it1, *curve_it2));
sp_marker_show_instance ((SPMarker* ) shape->marker[SP_MARKER_LOC_MID], ai,
NR_ARENA_ITEM_GET_KEY(ai) + SP_MARKER_LOC_MID, mid_pos, m,
style->stroke_width.computed);
@@ -676,9 +694,7 @@ sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai)
}
if ( shape->marker[SP_MARKER_LOC_END] ) {
- Geom::Point p = path_it->back_default().pointAt(1);
- Geom::Point tang = path_it->back_default().unitTangentAt(1);
- Geom::Matrix const m (sp_shape_marker_get_transform(p, tang, tang));
+ Geom::Matrix const m (sp_shape_marker_get_transform_at_end(path_it->back_default()));
sp_marker_show_instance ((SPMarker* ) shape->marker[SP_MARKER_LOC_END], ai,
NR_ARENA_ITEM_GET_KEY(ai) + SP_MARKER_LOC_END, end_pos, m,
style->stroke_width.computed);
@@ -749,9 +765,7 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &tr
SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_START]);
SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_START]));
- Geom::Point p = path_it->front().pointAt(0);
- Geom::Point tang = path_it->front().unitTangentAt(0);
- NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(p, tang, tang)));
+ NR::Matrix tr(from_2geom(sp_shape_marker_get_transform_at_start(path_it->front())));
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
@@ -779,10 +793,7 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &tr
SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_MID]);
SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_MID]));
- Geom::Point p = curve_it1->pointAt(1);
- Geom::Point tang1 = curve_it1->unitTangentAt(1);
- Geom::Point tang2 = curve_it2->unitTangentAt(0);
- NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(p, tang1, tang2)));
+ NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(*curve_it1, *curve_it2)));
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
@@ -806,9 +817,7 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &tr
SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_END]);
SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_END]));
- Geom::Point p = path_it->back_default().pointAt(1);
- Geom::Point tang = path_it->back_default().unitTangentAt(1);
- NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(p, tang, tang)));
+ NR::Matrix tr(from_2geom(sp_shape_marker_get_transform_at_end(path_it->back_default())));
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
@@ -885,9 +894,7 @@ sp_shape_print (SPItem *item, SPPrintContext *ctx)
SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_START]);
SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_START]));
- Geom::Point p = path_it->front().pointAt(0);
- Geom::Point tang = path_it->front().unitTangentAt(0);
- NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(p, tang, tang)));
+ NR::Matrix tr(from_2geom(sp_shape_marker_get_transform_at_start(path_it->front())));
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
@@ -913,10 +920,7 @@ sp_shape_print (SPItem *item, SPPrintContext *ctx)
SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_MID]);
SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_MID]));
- Geom::Point p = curve_it1->pointAt(1);
- Geom::Point tang1 = curve_it1->unitTangentAt(1);
- Geom::Point tang2 = curve_it2->unitTangentAt(0);
- NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(p, tang1, tang2)));
+ NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(*curve_it1, *curve_it2)));
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
@@ -938,9 +942,7 @@ sp_shape_print (SPItem *item, SPPrintContext *ctx)
SPMarker* marker = SP_MARKER (shape->marker[SP_MARKER_LOC_END]);
SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[SP_MARKER_LOC_END]));
- Geom::Point p = path_it->back_default().pointAt(1);
- Geom::Point tang = path_it->back_default().unitTangentAt(1);
- NR::Matrix tr(from_2geom(sp_shape_marker_get_transform(p, tang, tang)));
+ NR::Matrix tr(from_2geom(sp_shape_marker_get_transform_at_end(path_it->back_default())));
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;