summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6a14468)
raw | patch | inline | side by side (parent: 6a14468)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Fri, 8 Aug 2008 21:26:52 +0000 (21:26 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Fri, 8 Aug 2008 21:26:52 +0000 (21:26 +0000) |
src/extension/internal/cairo-renderer.cpp | patch | blob | history | |
src/sp-shape.cpp | patch | blob | history | |
src/splivarot.cpp | patch | blob | history |
index 3a4748b8aebd14fa3550a5f473c02cf50995c157..914a543f2846e2fea35a0f5defc6b0259163f8f8 100644 (file)
marker_item->transform = old_tr;
}
- if ( shape->marker[SP_MARKER_LOC_MID] ) {
+ if ( shape->marker[SP_MARKER_LOC_MID] && (path_it->size_default() > 1) ) {
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())
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]));
- NR::Matrix tr(sp_shape_marker_get_transform_at_end(path_it->back_default()));
+ /* Get reference to last curve in the path.
+ * For moveto-only path, this returns the "closing line segment". */
+ unsigned int index = path_it->size_default();
+ if (index > 0) {
+ index--;
+ }
+ Geom::Curve const &lastcurve = (*path_it)[index];
+
+ NR::Matrix tr = sp_shape_marker_get_transform_at_end(lastcurve);
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index 96b52fd46aff2f19573562578fb59a24412d4dfc..7c1cd20eae45dfda33a7206a22367c69257d4f71 100644 (file)
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
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);
+ Geom::Matrix ret = Geom::Translate(p);
+
+ if ( !c.isDegenerate() ) {
+ Geom::Point tang = c.unitTangentAt(0);
+ double const angle = Geom::atan2(tang);
+ ret = Geom::Rotate(angle) * Geom::Translate(p);
+ } else {
+ /* FIXME: the svg spec says to search for a better alternative than zero angle directionality:
+ * http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes */
+ }
- return Geom::Rotate(angle) * Geom::Translate(p);
+ return ret;
}
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);
+ Geom::Matrix ret = Geom::Translate(p);
+
+ if ( !c.isDegenerate() ) {
+ Geom::Curve * c_reverse = c.reverse();
+ Geom::Point tang = - c_reverse->unitTangentAt(0);
+ delete c_reverse;
+ double const angle = Geom::atan2(tang);
+ ret = Geom::Rotate(angle) * Geom::Translate(p);
+ } else {
+ /* FIXME: the svg spec says to search for a better alternative than zero angle directionality:
+ * http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes */
+ }
- return Geom::Rotate(angle) * Geom::Translate(p);
+ return ret;
}
/**
start_pos++;
}
- if ( shape->marker[SP_MARKER_LOC_MID] ) {
+ if ( shape->marker[SP_MARKER_LOC_MID] && (path_it->size_default() > 1) ) {
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())
}
if ( shape->marker[SP_MARKER_LOC_END] ) {
- Geom::Matrix const m (sp_shape_marker_get_transform_at_end(path_it->back_default()));
+ /* Get reference to last curve in the path.
+ * For moveto-only path, this returns the "closing line segment". */
+ unsigned int index = path_it->size_default();
+ if (index > 0) {
+ index--;
+ }
+ Geom::Curve const &lastcurve = (*path_it)[index];
+
+ Geom::Matrix const m = sp_shape_marker_get_transform_at_end(lastcurve);
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);
@@ -518,7 +540,7 @@ static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &tr
nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
}
- if ( shape->marker[SP_MARKER_LOC_MID] ) {
+ if ( shape->marker[SP_MARKER_LOC_MID] && (path_it->size_default() > 1) ) {
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())
@@ -554,7 +576,15 @@ 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]));
- NR::Matrix tr(sp_shape_marker_get_transform_at_end(path_it->back_default()));
+ /* Get reference to last curve in the path.
+ * For moveto-only path, this returns the "closing line segment". */
+ unsigned int index = path_it->size_default();
+ if (index > 0) {
+ index--;
+ }
+ Geom::Curve const &lastcurve = (*path_it)[index];
+
+ NR::Matrix tr = sp_shape_marker_get_transform_at_end(lastcurve);
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
marker_item->transform = old_tr;
}
- if ( shape->marker[SP_MARKER_LOC_MID] ) {
+ if ( shape->marker[SP_MARKER_LOC_MID] && (path_it->size_default() > 1) ) {
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())
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]));
- NR::Matrix tr(sp_shape_marker_get_transform_at_end(path_it->back_default()));
+ /* Get reference to last curve in the path.
+ * For moveto-only path, this returns the "closing line segment". */
+ unsigned int index = path_it->size_default();
+ if (index > 0) {
+ index--;
+ }
+ Geom::Curve const &lastcurve = (*path_it)[index];
+
+ NR::Matrix tr = sp_shape_marker_get_transform_at_end(lastcurve);
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
tr = NR::scale(style->stroke_width.computed) * tr;
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index 47051be2be132a954340c3d8ee223dccc8e1b068..e66bc6a689581a95f436b44f5e56683f1eabfc0d 100644 (file)
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
g_repr, xml_doc, doc );
}
- if ( SPObject *marker_obj = shape->marker[SP_MARKER_LOC_MID] ) {
+ SPObject *midmarker_obj = shape->marker[SP_MARKER_LOC_MID];
+ if ( midmarker_obj && (path_it->size_default() > 1) ) {
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())
* there should be a midpoint marker between last segment and closing straight line segment
*/
Geom::Matrix const m (sp_shape_marker_get_transform(*curve_it1, *curve_it2));
- sp_selected_path_outline_add_marker( marker_obj, m,
+ sp_selected_path_outline_add_marker( midmarker_obj, m,
NR::scale(i_style->stroke_width.computed), transform,
g_repr, xml_doc, doc );
}
if ( SPObject *marker_obj = shape->marker[SP_MARKER_LOC_END] ) {
- Geom::Matrix const m (sp_shape_marker_get_transform_at_end(path_it->back_default()));
+ /* Get reference to last curve in the path.
+ * For moveto-only path, this returns the "closing line segment". */
+ unsigned int index = path_it->size_default();
+ if (index > 0) {
+ index--;
+ }
+ Geom::Curve const &lastcurve = (*path_it)[index];
+
+ Geom::Matrix const m = sp_shape_marker_get_transform_at_end(lastcurve);
sp_selected_path_outline_add_marker( marker_obj, m,
NR::scale(i_style->stroke_width.computed), transform,
g_repr, xml_doc, doc );