summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 54e660c)
raw | patch | inline | side by side (parent: 54e660c)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Fri, 20 Jun 2008 23:31:48 +0000 (23:31 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Fri, 20 Jun 2008 23:31:48 +0000 (23:31 +0000) |
src/sp-shape.cpp | patch | blob | history |
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index 56589bab974cea8827daf415f226addc2b9ebfe6..c01f8535dd08b04d974d58e908ce98713fbfe392 100644 (file)
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
@@ -742,14 +742,47 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &tr
// Union with bboxes of the markers, if any
if (sp_shape_has_markers (shape)) {
- for (NArtBpath const* bp = SP_CURVE_BPATH(shape->curve); bp->code != NR_END; bp++) {
- for (int m = SP_MARKER_LOC_START; m < SP_MARKER_LOC_QTY; m++) {
- if (sp_shape_marker_required (shape, m, bp)) {
+ /* TODO: make code prettier: lots of variables can be taken out of the loop! */
+ 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] ) {
+ 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)));
+
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = NR::scale(style->stroke_width.computed) * tr;
+ }
+
+ // total marker transform
+ tr = marker_item->transform * marker->c2p * tr * transform;
+
+ // get bbox of the marker with that transform
+ NRRect marker_bbox;
+ sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true);
+ // union it with the shape bbox
+ nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
+ }
- SPMarker* marker = SP_MARKER (shape->marker[m]);
- SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[m]));
+ if ( shape->marker[SP_MARKER_LOC_MID] ) {
+ Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
+ while (curve_it2 != path_it->end_default())
+ {
+ /* Put marker between curve_it1 and curve_it2.
+ * 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 */
- NR::Matrix tr(sp_shape_marker_get_transform(shape, bp));
+ 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)));
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
@@ -763,8 +796,33 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &tr
sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true);
// union it with the shape bbox
nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
+
+ ++curve_it1;
+ ++curve_it2;
}
}
+
+ if ( shape->marker[SP_MARKER_LOC_END] ) {
+ 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)));
+
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = NR::scale(style->stroke_width.computed) * tr;
+ }
+
+ // total marker transform
+ tr = marker_item->transform * marker->c2p * tr * transform;
+
+ // get bbox of the marker with that transform
+ NRRect marker_bbox;
+ sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true);
+ // union it with the shape bbox
+ nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
+ }
}
}
}
sp_print_stroke (ctx, &bp, &i2d, style, &pbox, &dbox, &bbox);
}
- for (NArtBpath const* bp = SP_CURVE_BPATH(shape->curve); bp->code != NR_END; bp++) {
- for (int m = SP_MARKER_LOC_START; m < SP_MARKER_LOC_QTY; m++) {
- if (sp_shape_marker_required (shape, m, bp)) {
+ /* TODO: make code prettier: lots of variables can be taken out of the loop! */
+ 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] ) {
+ 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)));
- SPMarker* marker = SP_MARKER (shape->marker[m]);
- SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[m]));
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = NR::scale(style->stroke_width.computed) * tr;
+ }
- NR::Matrix tr(sp_shape_marker_get_transform(shape, bp));
+ tr = marker_item->transform * marker->c2p * tr;
- if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
- tr = NR::scale(style->stroke_width.computed) * tr;
- }
+ NR::Matrix old_tr = marker_item->transform;
+ marker_item->transform = tr;
+ sp_item_invoke_print (marker_item, ctx);
+ marker_item->transform = old_tr;
+ }
+
+ if ( shape->marker[SP_MARKER_LOC_MID] ) {
+ Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
+ while (curve_it2 != path_it->end_default())
+ {
+ /* Put marker between curve_it1 and curve_it2.
+ * 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 */
- tr = marker_item->transform * marker->c2p * 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]));
- NR::Matrix old_tr = marker_item->transform;
- marker_item->transform = tr;
- sp_item_invoke_print (marker_item, ctx);
- marker_item->transform = old_tr;
+ 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)));
+
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = NR::scale(style->stroke_width.computed) * tr;
}
+
+ tr = marker_item->transform * marker->c2p * tr;
+
+ NR::Matrix old_tr = marker_item->transform;
+ marker_item->transform = tr;
+ sp_item_invoke_print (marker_item, ctx);
+ marker_item->transform = old_tr;
+
+ ++curve_it1;
+ ++curve_it2;
+ }
+ }
+
+ if ( shape->marker[SP_MARKER_LOC_END] ) {
+ 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)));
+
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = NR::scale(style->stroke_width.computed) * tr;
}
+
+ tr = marker_item->transform * marker->c2p * tr;
+
+ NR::Matrix old_tr = marker_item->transform;
+ marker_item->transform = tr;
+ sp_item_invoke_print (marker_item, ctx);
+ marker_item->transform = old_tr;
}
+ }
if (add_comments) {
gchar * comment = g_strdup_printf("end '%s'",