diff --git a/src/marker.cpp b/src/marker.cpp
index 08f1b5fad1cdf66ce030b44b6bffe8f6f54fa69b..37cb8223cfdebca8f6cb96b2baf0731bd846dba8 100644 (file)
--- a/src/marker.cpp
+++ b/src/marker.cpp
*
* Copyright (C) 1999-2003 Lauris Kaplinski
* 2004-2006 Bryce Harrington
+ * 2008 Johan Engelen
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#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-rotate-fns.h"
+#include "libnr/nr-translate-matrix-ops.h"
+#include "libnr/nr-convert2geom.h"
+#include <2geom/matrix.h>
#include "svg/svg.h"
#include "display/nr-arena-group.h"
#include "xml/repr.h"
struct SPMarkerView {
SPMarkerView *next;
unsigned int key;
- unsigned int size;
- NRArenaItem *items[1];
+ std::vector<NRArenaItem *> items;
};
static void sp_marker_class_init (SPMarkerClass *klass);
@@ -44,11 +47,11 @@ static void sp_marker_build (SPObject *object, SPDocument *document, Inkscape::X
static void sp_marker_release (SPObject *object);
static void sp_marker_set (SPObject *object, unsigned int key, const gchar *value);
static void sp_marker_update (SPObject *object, SPCtx *ctx, guint flags);
-static Inkscape::XML::Node *sp_marker_write (SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static Inkscape::XML::Node *sp_marker_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static NRArenaItem *sp_marker_private_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
static void sp_marker_private_hide (SPItem *item, unsigned int key);
-static void sp_marker_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags);
+static void sp_marker_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const flags);
static void sp_marker_print (SPItem *item, SPPrintContext *ctx);
static void sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems);
{
marker->viewBox_set = FALSE;
- nr_matrix_set_identity (&marker->c2p);
+ marker->c2p.setIdentity();
}
/**
SPItemCtx rctx;
NRRect *vb;
double x, y, width, height;
- NRMatrix q;
SPMarkerView *v;
item = SP_ITEM (object);
rctx.vp.y1 = marker->markerHeight.computed;
/* Start with identity transform */
- nr_matrix_set_identity (&marker->c2p);
+ marker->c2p.setIdentity();
/* Viewbox is always present, either implicitly or explicitly */
if (marker->viewBox_set) {
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);
+ {
+ Geom::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 = Geom::Translate(-marker->refX.computed, -marker->refY.computed) * marker->c2p;
rctx.i2doc = marker->c2p * rctx.i2doc;
/* If viewBox is set reinitialize child viewport */
/* Otherwise it already correct */
if (marker->viewBox_set) {
- rctx.vp.x0 = marker->viewBox.x0;
- rctx.vp.y0 = marker->viewBox.y0;
- rctx.vp.x1 = marker->viewBox.x1;
- rctx.vp.y1 = marker->viewBox.y1;
- rctx.i2vp = NR::identity();
+ rctx.vp.x0 = marker->viewBox.x0;
+ rctx.vp.y0 = marker->viewBox.y0;
+ rctx.vp.x1 = marker->viewBox.x1;
+ rctx.vp.y1 = marker->viewBox.y1;
+ rctx.i2vp = Geom::identity();
}
/* And invoke parent method */
/* As last step set additional transform of arena group */
for (v = marker->views; v != NULL; v = v->next) {
- for (unsigned i = 0 ; i < v->size ; i++) {
- if (v->items[i]) {
- nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->items[i]), &marker->c2p);
- }
- }
+ for (unsigned i = 0 ; i < v->items.size() ; i++) {
+ if (v->items[i]) {
+ Geom::Matrix tmp = marker->c2p;
+ nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->items[i]), &tmp);
+ }
+ }
}
}
* Writes the object's properties into its repr object.
*/
static Inkscape::XML::Node *
-sp_marker_write (SPObject *object, Inkscape::XML::Node *repr, guint flags)
+sp_marker_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
SPMarker *marker;
marker = SP_MARKER (object);
if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
- Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_OBJECT_DOCUMENT(object));
repr = xml_doc->createElement("svg:marker");
}
repr->setAttribute("preserveAspectRatio", object->repr->attribute("preserveAspectRatio"));
if (((SPObjectClass *) (parent_class))->write)
- ((SPObjectClass *) (parent_class))->write (object, repr, flags);
+ ((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
return repr;
}
* This routine is disabled to break propagation.
*/
static void
-sp_marker_bbox(SPItem const *, NRRect *, NR::Matrix const &, unsigned const)
+sp_marker_bbox(SPItem const *, NRRect *, Geom::Matrix const &, unsigned const)
{
/* Break propagation */
}
@@ -604,7 +608,7 @@ sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size)
for (view = marker->views; view != NULL; view = view->next) {
if (view->key == key) break;
}
- if (view && (view->size != size)) {
+ if (view && (view->items.size() != size)) {
/* Free old view and allocate new */
/* Parent class ::hide method */
((SPItemClass *) parent_class)->hide ((SPItem *) marker, key);
@@ -612,12 +616,15 @@ sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size)
view = NULL;
}
if (!view) {
- view = (SPMarkerView *)g_malloc (sizeof (SPMarkerView) + (size) * sizeof (NRArenaItem *));
- for (i = 0; i < size; i++) view->items[i] = NULL;
+ view = (SPMarkerView *) g_new (SPMarkerView, 1);
+ new (&view->items) std::vector<NRArenaItem *>;
+ view->items.clear();
+ for (i = 0; i < size; i++) {
+ view->items.push_back(NULL);
+ }
view->next = marker->views;
marker->views = view;
view->key = key;
- view->size = size;
}
}
@@ -626,47 +633,48 @@ sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size)
* show and transform a child item in the arena for all views with the given key.
*/
NRArenaItem *
-sp_marker_show_instance (SPMarker *marker, NRArenaItem *parent,
- unsigned int key, unsigned int pos,
- NR::Matrix const &base, float linewidth)
+sp_marker_show_instance ( SPMarker *marker, NRArenaItem *parent,
+ unsigned int key, unsigned int pos,
+ Geom::Matrix const &base, float linewidth)
{
- for (SPMarkerView *v = marker->views; v != NULL; v = v->next) {
- if (v->key == key) {
- if (pos >= v->size) {
- return NULL;
- }
- if (!v->items[pos]) {
- /* Parent class ::show method */
- v->items[pos] = ((SPItemClass *) parent_class)->show ((SPItem *) marker,
- parent->arena, key,
- SP_ITEM_REFERENCE_FLAGS);
- if (v->items[pos]) {
- /* fixme: Position (Lauris) */
- nr_arena_item_add_child (parent, v->items[pos], NULL);
- /* nr_arena_item_unref (v->items[pos]); */
- nr_arena_group_set_child_transform((NRArenaGroup *) v->items[pos], &marker->c2p);
- }
- }
- if (v->items[pos]) {
- NR::Matrix m;
- if (marker->orient_auto) {
- m = base;
- } else {
- /* fixme: Orient units (Lauris) */
- m = NR::Matrix(rotate_degrees(marker->orient));
- m *= get_translation(base);
- }
- if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
- m = NR::scale(linewidth) * m;
- }
-
- nr_arena_item_set_transform(v->items[pos], m);
- }
- return v->items[pos];
- }
- }
+ for (SPMarkerView *v = marker->views; v != NULL; v = v->next) {
+ if (v->key == key) {
+ if (pos >= v->items.size()) {
+ return NULL;
+ }
+ if (!v->items[pos]) {
+ /* Parent class ::show method */
+ v->items[pos] = ((SPItemClass *) parent_class)->show ((SPItem *) marker,
+ parent->arena, key,
+ SP_ITEM_REFERENCE_FLAGS);
+ if (v->items[pos]) {
+ /* fixme: Position (Lauris) */
+ nr_arena_item_add_child (parent, v->items[pos], NULL);
+ /* nr_arena_item_unref (v->items[pos]); */
+ Geom::Matrix tmp = marker->c2p;
+ nr_arena_group_set_child_transform((NRArenaGroup *) v->items[pos], &tmp);
+ }
+ }
+ if (v->items[pos]) {
+ Geom::Matrix m;
+ if (marker->orient_auto) {
+ m = base;
+ } else {
+ /* fixme: Orient units (Lauris) */
+ m = Geom::Matrix(Geom::Rotate::from_degrees(marker->orient));
+ m *= Geom::Translate(base[4], base[5]); // TODO: this was NR::get_translation() originally; should it be extracted into a new 2geom function?
+ }
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ m = Geom::Scale(linewidth) * m;
+ }
+
+ nr_arena_item_set_transform(v->items[pos], m);
+ }
+ return v->items[pos];
+ }
+ }
- return NULL;
+ return NULL;
}
/**
@@ -709,16 +717,17 @@ sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destro
v->next = view->next;
}
if (destroyitems) {
- for (i = 0; i < view->size; i++) {
+ for (i = 0; i < view->items.size(); i++) {
/* We have to walk through the whole array because there may be hidden items */
if (view->items[i]) nr_arena_item_unref (view->items[i]);
}
}
+ view->items.clear();
g_free (view);
}
const gchar *
-generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matrix /*transform*/, NR::Matrix move)
+generate_marker (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Matrix /*transform*/, Geom::Matrix move)
{
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document));
@@ -730,8 +739,8 @@ generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matri
// 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));
+ sp_repr_set_svg_double(repr, "markerWidth", bounds.dimensions()[Geom::X]);
+ sp_repr_set_svg_double(repr, "markerHeight", bounds.dimensions()[Geom::Y]);
repr->setAttribute("orient", "auto");
@@ -743,9 +752,9 @@ generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matri
Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data);
SPItem *copy = SP_ITEM(mark_object->appendChildRepr(node));
- NR::Matrix dup_transform;
+ Geom::Matrix dup_transform;
if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform))
- dup_transform = NR::identity();
+ dup_transform = Geom::identity();
dup_transform *= move;
sp_item_write_transform(copy, SP_OBJECT_REPR(copy), dup_transform);
@@ -754,3 +763,14 @@ generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matri
Inkscape::GC::release(repr);
return mark_id;
}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :