From a4ce97ec6835fb6ea8dfd3dbee11abe103b064e4 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 30 Jan 2014 14:18:11 +0100 Subject: Correct positioning of custom markers. Fixes #230491. (bzr r12986) --- src/marker.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/marker.cpp') diff --git a/src/marker.cpp b/src/marker.cpp index d145aadaf..b9464186d 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -654,7 +654,7 @@ sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destro delete view; } -const gchar *generate_marker(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine /*transform*/, Geom::Affine move) +const gchar *generate_marker(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Point center, Geom::Affine move) { Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr(); @@ -668,6 +668,8 @@ const gchar *generate_marker(GSList *reprs, Geom::Rect bounds, SPDocument *docum sp_repr_set_svg_double(repr, "markerWidth", bounds.dimensions()[Geom::X]); sp_repr_set_svg_double(repr, "markerHeight", bounds.dimensions()[Geom::Y]); + sp_repr_set_svg_double(repr, "refX", center[Geom::X]); + sp_repr_set_svg_double(repr, "refY", center[Geom::Y]); repr->setAttribute("orient", "auto"); @@ -676,7 +678,7 @@ const gchar *generate_marker(GSList *reprs, Geom::Rect bounds, SPDocument *docum SPObject *mark_object = document->getObjectById(mark_id); for (GSList *i = reprs; i != NULL; i = i->next) { - Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data); + Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data); SPItem *copy = SP_ITEM(mark_object->appendChildRepr(node)); Geom::Affine dup_transform; -- cgit v1.2.3 From 7dd239eed97761b22ef635b6896a8f65c4939462 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 6 Feb 2014 15:29:15 +0100 Subject: Added new base class to handle viewBox and preserveAspectRatio. Updated sp-root, sp-symbol, sp-image, sp-pattern, marker to use new class. Fixed some viewport issues when % used. (bzr r13002) --- src/marker.cpp | 257 ++++++--------------------------------------------------- 1 file changed, 23 insertions(+), 234 deletions(-) (limited to 'src/marker.cpp') diff --git a/src/marker.cpp b/src/marker.cpp index b9464186d..f6e55b3ec 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -47,18 +47,15 @@ namespace { bool markerRegistered = SPFactory::instance().registerObject("svg:marker", createMarker); } -SPMarker::SPMarker() : SPGroup() { - this->aspect_clip = 0; - this->aspect_align = 0; - this->aspect_set = 0; - this->markerUnits = 0; - this->orient_auto = 0; - this->markerUnits_set = 0; - this->orient_set = 0; - this->orient = 0; - - this->viewBox = Geom::OptRect(); - this->c2p.setIdentity(); +SPMarker::SPMarker() : SPGroup(), SPViewBox() { + + this->markerUnits = 0; + this->markerUnits_set = 0; + + this->orient_auto = 0; + this->orient_set = 0; + this->orient = 0; + this->views = NULL; } @@ -177,133 +174,14 @@ void SPMarker::set(unsigned int key, const gchar* value) { break; case SP_ATTR_VIEWBOX: - this->viewBox = Geom::OptRect(); - - if (value) { - double x, y, width, height; - char *eptr; - - /* fixme: We have to take original item affine into account */ - /* fixme: Think (Lauris) */ - eptr = (gchar *) value; - x = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } - - y = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } - - width = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } - - height = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } - - if ((width > 0) && (height > 0)) { - /* Set viewbox */ - this->viewBox = Geom::Rect(Geom::Point(x, y), Geom::Point(x + width, y + height)); - } - } - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; + set_viewBox( value ); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; case SP_ATTR_PRESERVEASPECTRATIO: - /* Do setup before, so we can use break to escape */ - this->aspect_set = FALSE; - this->aspect_align = SP_ASPECT_NONE; - this->aspect_clip = SP_ASPECT_MEET; - - this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - - if (value) { - int len; - gchar c[256]; - const gchar *p, *e; - unsigned int align, clip; - p = value; - - while (*p && *p == 32) { - p += 1; - } - - if (!*p) { - break; - } - - e = p; - - while (*e && *e != 32) { - e += 1; - } - - len = e - p; - - if (len > 8) { - break; - } - - memcpy (c, value, len); - - c[len] = 0; - - /* Now the actual part */ - if (!strcmp (c, "none")) { - align = SP_ASPECT_NONE; - } else if (!strcmp (c, "xMinYMin")) { - align = SP_ASPECT_XMIN_YMIN; - } else if (!strcmp (c, "xMidYMin")) { - align = SP_ASPECT_XMID_YMIN; - } else if (!strcmp (c, "xMaxYMin")) { - align = SP_ASPECT_XMAX_YMIN; - } else if (!strcmp (c, "xMinYMid")) { - align = SP_ASPECT_XMIN_YMID; - } else if (!strcmp (c, "xMidYMid")) { - align = SP_ASPECT_XMID_YMID; - } else if (!strcmp (c, "xMaxYMid")) { - align = SP_ASPECT_XMAX_YMID; - } else if (!strcmp (c, "xMinYMax")) { - align = SP_ASPECT_XMIN_YMAX; - } else if (!strcmp (c, "xMidYMax")) { - align = SP_ASPECT_XMID_YMAX; - } else if (!strcmp (c, "xMaxYMax")) { - align = SP_ASPECT_XMAX_YMAX; - } else { - break; - } - - clip = SP_ASPECT_MEET; - - while (*e && *e == 32) { - e += 1; - } - - if (*e) { - if (!strcmp (e, "meet")) { - clip = SP_ASPECT_MEET; - } else if (!strcmp (e, "slice")) { - clip = SP_ASPECT_SLICE; - } else { - break; - } - } - - this->aspect_set = TRUE; - this->aspect_align = align; - this->aspect_clip = clip; - } - break; + set_preserveAspectRatio( value ); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; default: SPGroup::set(key, value); @@ -312,112 +190,23 @@ void SPMarker::set(unsigned int key, const gchar* value) { } void SPMarker::update(SPCtx *ctx, guint flags) { - SPItemCtx rctx; - // fixme: We have to set up clip here too + SPItemCtx ictx; // Copy parent context - rctx.flags = ctx->flags; + ictx.flags = ctx->flags; // Initialize transformations - rctx.i2doc = Geom::identity(); - rctx.i2vp = Geom::identity(); + ictx.i2doc = Geom::identity(); + ictx.i2vp = Geom::identity(); // Set up viewport - rctx.viewport = Geom::Rect::from_xywh(0, 0, this->markerWidth.computed, this->markerHeight.computed); - - // Start with identity transform - this->c2p.setIdentity(); + ictx.viewport = Geom::Rect::from_xywh(0, 0, this->markerWidth.computed, this->markerHeight.computed); - // Viewbox is always present, either implicitly or explicitly - Geom::Rect vb; - if (this->viewBox) { - vb = *this->viewBox; - } else { - vb = rctx.viewport; - } + SPItemCtx rctx = get_rctx( &ictx ); - // Now set up viewbox transformation - - // Determine actual viewbox in viewport coordinates - // double x = 0; - // double y = 0; - double width = 0; - double height = 0; - - if (this->aspect_align == SP_ASPECT_NONE) { - // x = 0.0; - // y = 0.0; - width = rctx.viewport.width(); - height = rctx.viewport.height(); - } else { - double scalex, scaley, scale; - // Things are getting interesting - scalex = rctx.viewport.width() / (vb.width()); - scaley = rctx.viewport.height() / (vb.height()); - scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley); - width = (vb.width()) * scale; - height = (vb.height()) * scale; - - // Now place viewbox to requested position - /*switch (marker->aspect_align) { - case SP_ASPECT_XMIN_YMIN: - x = 0.0; - y = 0.0; - break; - case SP_ASPECT_XMID_YMIN: - x = 0.5 * (rctx.viewport.width() - width); - y = 0.0; - break; - case SP_ASPECT_XMAX_YMIN: - x = 1.0 * (rctx.viewport.width() - width); - y = 0.0; - break; - case SP_ASPECT_XMIN_YMID: - x = 0.0; - y = 0.5 * (rctx.viewport.height() - height); - break; - case SP_ASPECT_XMID_YMID: - x = 0.5 * (rctx.viewport.width() - width); - y = 0.5 * (rctx.viewport.height() - height); - break; - case SP_ASPECT_XMAX_YMID: - x = 1.0 * (rctx.viewport.width() - width); - y = 0.5 * (rctx.viewport.height() - height); - break; - case SP_ASPECT_XMIN_YMAX: - x = 0.0; - y = 1.0 * (rctx.viewport.height() - height); - break; - case SP_ASPECT_XMID_YMAX: - x = 0.5 * (rctx.viewport.width() - width); - y = 1.0 * (rctx.viewport.height() - height); - break; - case SP_ASPECT_XMAX_YMAX: - x = 1.0 * (rctx.viewport.width() - width); - y = 1.0 * (rctx.viewport.height() - height); - break; - default: - x = 0.0; - y = 0.0; - break; - }*/ - } - - // TODO fixme: all that work is done to figure out x and y, which are just ignored. Check why. - - // viewbox transformation and reference translation - this->c2p = Geom::Translate(-this->refX.computed, -this->refY.computed) * - Geom::Scale(width / vb.width(), height / vb.height()); - - rctx.i2doc = this->c2p * rctx.i2doc; - - // If viewBox is set reinitialize child viewport - // Otherwise it already correct - if (this->viewBox) { - rctx.viewport = *this->viewBox; - rctx.i2vp = Geom::identity(); - } + // Shift according to refX, refY + this->c2p = Geom::Translate(this->viewBox.left()-this->refX.computed, this->viewBox.top()-this->refY.computed) * this->c2p; // And invoke parent method SPGroup::update((SPCtx *) &rctx, flags); -- cgit v1.2.3 From 837c1a0ef4f2e0eb5000b4b993fd0b40d0a531db Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 6 Feb 2014 20:28:35 +0100 Subject: Markers are never shown directly, even if outside of section. (bzr r13003) --- src/marker.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/marker.cpp') diff --git a/src/marker.cpp b/src/marker.cpp index f6e55b3ec..900f8a2ca 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -283,8 +283,12 @@ Inkscape::XML::Node* SPMarker::write(Inkscape::XML::Document *xml_doc, Inkscape: } Inkscape::DrawingItem* SPMarker::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { - // CPPIFY: correct? - return SPGroup::show(drawing, key, flags); + // Markers in tree are never shown directly even if outside of . + return 0; +} + +Inkscape::DrawingItem* SPMarker::private_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { + return SPGroup::show(drawing, key, flags); } void SPMarker::hide(unsigned int key) { @@ -364,7 +368,7 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, } if (!v->items[pos]) { /* Parent class ::show method */ - v->items[pos] = marker->show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS); + v->items[pos] = marker->private_show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS); if (v->items[pos]) { /* fixme: Position (Lauris) */ -- cgit v1.2.3 From 2607adab8dd0fdecdc5dcf13073078b58407d5b0 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Tue, 11 Feb 2014 14:37:29 +0100 Subject: suppress compiler warnings (bzr r13021) --- src/marker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/marker.cpp') diff --git a/src/marker.cpp b/src/marker.cpp index 900f8a2ca..fb7b0fd21 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -282,7 +282,7 @@ Inkscape::XML::Node* SPMarker::write(Inkscape::XML::Document *xml_doc, Inkscape: return repr; } -Inkscape::DrawingItem* SPMarker::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { +Inkscape::DrawingItem* SPMarker::show(Inkscape::Drawing &/*drawing*/, unsigned int /*key*/, unsigned int /*flags*/) { // Markers in tree are never shown directly even if outside of . return 0; } -- cgit v1.2.3 From 266f00570bb353879343fe47d3f894b22301a993 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 4 Mar 2014 14:35:39 +0100 Subject: Fix for W3C test suite test filters-light-02-f.svg. Marker refX and refY defined in coordinate system of viewBox. (bzr r13113) --- src/marker.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/marker.cpp') diff --git a/src/marker.cpp b/src/marker.cpp index fb7b0fd21..7fee16ead 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -206,7 +206,9 @@ void SPMarker::update(SPCtx *ctx, guint flags) { SPItemCtx rctx = get_rctx( &ictx ); // Shift according to refX, refY - this->c2p = Geom::Translate(this->viewBox.left()-this->refX.computed, this->viewBox.top()-this->refY.computed) * this->c2p; + Geom::Point ref( this->refX.computed, this->refY.computed ); + ref *= c2p; + this->c2p = this->c2p * Geom::Translate( -ref ); // And invoke parent method SPGroup::update((SPCtx *) &rctx, flags); -- cgit v1.2.3