Code

changes to use RegisteredTransformedPoint as widget for LPE point. not complete
[inkscape.git] / src / marker.cpp
index 65ed3789fde1126979e36ee93135494a70bba660..aacbee87531af918f955c9392d2ae67de25af2bb 100644 (file)
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
+#include <cstring>
+#include <string>
 #include "config.h"
 
 
 #include "libnr/nr-matrix-fns.h"
 #include "libnr/nr-matrix-ops.h"
+#include "libnr/nr-matrix-translate-ops.h"
 #include "libnr/nr-scale-matrix-ops.h"
+#include "libnr/nr-translate-matrix-ops.h"
 #include "libnr/nr-rotate-fns.h"
 #include "svg/svg.h"
 #include "display/nr-arena-group.h"
 #include "xml/repr.h"
 #include "attributes.h"
 #include "marker.h"
+#include "document.h"
+#include "document-private.h"
 
 struct SPMarkerView {
        SPMarkerView *next;
@@ -75,7 +81,7 @@ sp_marker_get_type (void)
 }
 
 /**
- * Initializes a SPMarkerClass object.  Establishes the function pointers to the class' 
+ * Initializes a SPMarkerClass object.  Establishes the function pointers to the class'
  * member routines in the class vtable, and sets pointers to parent classes.
  */
 static void
@@ -112,7 +118,7 @@ sp_marker_init (SPMarker *marker)
 {
        marker->viewBox_set = FALSE;
 
-       nr_matrix_set_identity (&marker->c2p);
+       marker->c2p.set_identity();
 }
 
 /**
@@ -120,7 +126,7 @@ sp_marker_init (SPMarker *marker)
  *
  * This is to be invoked immediately after creation of an SPMarker.  This
  * method fills an SPMarker object with its SVG attributes, and calls the
- * parent class' build routine to attach the object to its document and 
+ * parent class' build routine to attach the object to its document and
  * repr.  The result will be creation of the whole document tree.
  *
  * \see sp_object_build()
@@ -349,7 +355,6 @@ sp_marker_update (SPObject *object, SPCtx *ctx, guint flags)
        SPItemCtx rctx;
        NRRect *vb;
        double x, y, width, height;
-       NRMatrix q;
        SPMarkerView *v;
 
        item = SP_ITEM (object);
@@ -369,7 +374,7 @@ sp_marker_update (SPObject *object, SPCtx *ctx, guint flags)
        rctx.vp.y1 = marker->markerHeight.computed;
 
        /* Start with identity transform */
-       nr_matrix_set_identity (&marker->c2p);
+       marker->c2p.set_identity();
 
        /* Viewbox is always present, either implicitly or explicitly */
        if (marker->viewBox_set) {
@@ -436,21 +441,23 @@ sp_marker_update (SPObject *object, SPCtx *ctx, guint flags)
                        break;
                }
        }
-       /* Compose additional transformation from scale and position */
-       q.c[0] = width / (vb->x1 - vb->x0);
-       q.c[1] = 0.0;
-       q.c[2] = 0.0;
-       q.c[3] = height / (vb->y1 - vb->y0);
-       q.c[4] = -vb->x0 * q.c[0] + x;
-       q.c[5] = -vb->y0 * q.c[3] + y;
-       /* Append viewbox transformation */
-       nr_matrix_multiply (&marker->c2p, &q, &marker->c2p);
 
+    {
+        NR::Matrix q;
+           /* Compose additional transformation from scale and position */
+           q[0] = width / (vb->x1 - vb->x0);
+           q[1] = 0.0;
+           q[2] = 0.0;
+           q[3] = height / (vb->y1 - vb->y0);
+           q[4] = -vb->x0 * q[0] + x;
+           q[5] = -vb->y0 * q[3] + y;
+           /* Append viewbox transformation */
+           marker->c2p = q * marker->c2p;
+    }
 
        /* Append reference translation */
        /* fixme: lala (Lauris) */
-       nr_matrix_set_translate (&q, -marker->refX.computed, -marker->refY.computed);
-       nr_matrix_multiply (&marker->c2p, &q, &marker->c2p);
+    marker->c2p = NR::translate(-marker->refX.computed, -marker->refY.computed) * marker->c2p;
 
        rctx.i2doc = marker->c2p * rctx.i2doc;
 
@@ -478,7 +485,7 @@ sp_marker_update (SPObject *object, SPCtx *ctx, guint flags)
        }
 }
 
-/** 
+/**
  * Writes the object's properties into its repr object.
  */
 static Inkscape::XML::Node *
@@ -489,7 +496,8 @@ sp_marker_write (SPObject *object, Inkscape::XML::Node *repr, guint flags)
        marker = SP_MARKER (object);
 
        if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
-               repr = sp_repr_new ("svg:marker");
+               Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
+               repr = xml_doc->createElement("svg:marker");
        }
 
        if (marker->markerUnits_set) {
@@ -544,19 +552,19 @@ sp_marker_write (SPObject *object, Inkscape::XML::Node *repr, guint flags)
  * This routine is disabled to break propagation.
  */
 static NRArenaItem *
-sp_marker_private_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags)
+sp_marker_private_show (SPItem */*item*/, NRArena */*arena*/, unsigned int /*key*/, unsigned int /*flags*/)
 {
-       /* Break propagation */
-       return NULL;
+    /* Break propagation */
+    return NULL;
 }
 
 /**
  * This routine is disabled to break propagation.
  */
 static void
-sp_marker_private_hide (SPItem *item, unsigned int key)
+sp_marker_private_hide (SPItem */*item*/, unsigned int /*key*/)
 {
-       /* Break propagation */
+    /* Break propagation */
 }
 
 /**
@@ -572,9 +580,9 @@ sp_marker_bbox(SPItem const *, NRRect *, NR::Matrix const &, unsigned const)
  * This routine is disabled to break propagation.
  */
 static void
-sp_marker_print (SPItem *item, SPPrintContext *ctx)
+sp_marker_print (SPItem */*item*/, SPPrintContext */*ctx*/)
 {
-       /* Break propagation */
+    /* Break propagation */
 }
 
 /* fixme: Remove link if zero-sized (Lauris) */
@@ -585,7 +593,7 @@ sp_marker_print (SPItem *item, SPPrintContext *ctx)
  * This is called from sp_shape_update() for shapes that have markers.  It
  * removes the old view of the marker and establishes a new one, registering
  * it with the marker's list of views for future updates.
- * 
+ *
  * \param marker Marker to create views in.
  * \param key Key to give each SPMarkerView.
  * \param size Number of NRArenaItems to put in the SPMarkerView.
@@ -616,7 +624,7 @@ sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size)
        }
 }
 
-/** 
+/**
  * Shows an instance of a marker.  This is called during sp_shape_update_marker_view()
  * show and transform a child item in the arena for all views with the given key.
  */
@@ -689,7 +697,7 @@ sp_marker_hide (SPMarker *marker, unsigned int key)
 }
 
 /**
- * Removes a given view.  Also will destroy sub-items in the view if destroyitems 
+ * Removes a given view.  Also will destroy sub-items in the view if destroyitems
  * is set to a non-zero value.
  */
 static void
@@ -711,3 +719,41 @@ sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destro
        }
        g_free (view);
 }
+
+const gchar *
+generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matrix /*transform*/, NR::Matrix move)
+{
+    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
+    Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document));
+
+    Inkscape::XML::Node *repr = xml_doc->createElement("svg:marker");
+
+    // Uncommenting this will make the marker fixed-size independent of stroke width.
+    // Commented out for consistency with standard markers which scale when you change
+    // stroke width:
+    //repr->setAttribute("markerUnits", "userSpaceOnUse");
+
+    sp_repr_set_svg_double(repr, "markerWidth", bounds.extent(NR::X));
+    sp_repr_set_svg_double(repr, "markerHeight", bounds.extent(NR::Y));
+
+    repr->setAttribute("orient", "auto");
+
+    defsrepr->appendChild(repr);
+    const gchar *mark_id = repr->attribute("id");
+    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);
+        SPItem *copy = SP_ITEM(mark_object->appendChildRepr(node));
+
+        NR::Matrix dup_transform;
+        if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform))
+            dup_transform = NR::identity();
+        dup_transform *= move;
+
+        sp_item_write_transform(copy, SP_OBJECT_REPR(copy), dup_transform);
+    }
+
+    Inkscape::GC::release(repr);
+    return mark_id;
+}