diff --git a/src/marker.cpp b/src/marker.cpp
index fded90c4afc6dc2c1e3b0728c8e70d5104f0bec7..0ec92a1ff2147b00573ad9703e86d10a7628083c 100644 (file)
--- a/src/marker.cpp
+++ b/src/marker.cpp
-#define __MARKER_C__
-
/*
* SVG <marker> implementation
*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* Bryce Harrington <bryce@bryceharrington.org>
+ * Abhishek Sharma
*
* Copyright (C) 1999-2003 Lauris Kaplinski
* 2004-2006 Bryce Harrington
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);
static void
sp_marker_init (SPMarker *marker)
{
- marker->viewBox_set = FALSE;
-
- marker->c2p.setIdentity();
+ marker->viewBox = Geom::OptRect();
+ marker->c2p.setIdentity();
+ marker->views = NULL;
}
/**
@@ -142,14 +140,14 @@ sp_marker_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *re
group = (SPGroup *) object;
marker = (SPMarker *) object;
- sp_object_read_attr (object, "markerUnits");
- sp_object_read_attr (object, "refX");
- sp_object_read_attr (object, "refY");
- sp_object_read_attr (object, "markerWidth");
- sp_object_read_attr (object, "markerHeight");
- sp_object_read_attr (object, "orient");
- sp_object_read_attr (object, "viewBox");
- sp_object_read_attr (object, "preserveAspectRatio");
+ object->readAttr( "markerUnits" );
+ object->readAttr( "refX" );
+ object->readAttr( "refY" );
+ object->readAttr( "markerWidth" );
+ object->readAttr( "markerHeight" );
+ object->readAttr( "orient" );
+ object->readAttr( "viewBox" );
+ object->readAttr( "preserveAspectRatio" );
if (((SPObjectClass *) parent_class)->build)
((SPObjectClass *) parent_class)->build (object, document, repr);
object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
break;
case SP_ATTR_VIEWBOX:
- marker->viewBox_set = FALSE;
+ marker->viewBox = Geom::OptRect();
if (value) {
double x, y, width, height;
char *eptr;
while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++;
if ((width > 0) && (height > 0)) {
/* Set viewbox */
- marker->viewBox.x0 = x;
- marker->viewBox.y0 = y;
- marker->viewBox.x1 = x + width;
- marker->viewBox.y1 = y + height;
- marker->viewBox_set = TRUE;
+ marker->viewBox = Geom::Rect( Geom::Point(x,y),
+ Geom::Point(x + width, y + height) );
}
}
object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
align = SP_ASPECT_XMIN_YMID;
} else if (!strcmp (c, "xMidYMid")) {
align = SP_ASPECT_XMID_YMID;
- } else if (!strcmp (c, "xMaxYMin")) {
+ } else if (!strcmp (c, "xMaxYMid")) {
align = SP_ASPECT_XMAX_YMID;
} else if (!strcmp (c, "xMinYMax")) {
align = SP_ASPECT_XMIN_YMAX;
}
clip = SP_ASPECT_MEET;
while (*e && *e == 32) e += 1;
- if (e) {
+ if (*e) {
if (!strcmp (e, "meet")) {
clip = SP_ASPECT_MEET;
} else if (!strcmp (e, "slice")) {
SPItem *item;
SPMarker *marker;
SPItemCtx rctx;
- NRRect *vb;
+ Geom::Rect vb;
double x, y, width, height;
SPMarkerView *v;
/* Copy parent context */
rctx.ctx = *ctx;
/* Initialize tranformations */
- rctx.i2doc = NR::identity();
- rctx.i2vp = NR::identity();
+ rctx.i2doc = Geom::identity();
+ rctx.i2vp = Geom::identity();
/* Set up viewport */
rctx.vp.x0 = 0.0;
rctx.vp.y0 = 0.0;
marker->c2p.setIdentity();
/* Viewbox is always present, either implicitly or explicitly */
- if (marker->viewBox_set) {
- vb = &marker->viewBox;
+ if (marker->viewBox) {
+ vb = *marker->viewBox;
} else {
- vb = &rctx.vp;
+ vb = *(rctx.vp.upgrade_2geom());
}
/* Now set up viewbox transformation */
/* Determine actual viewbox in viewport coordinates */
} else {
double scalex, scaley, scale;
/* Things are getting interesting */
- scalex = (rctx.vp.x1 - rctx.vp.x0) / (vb->x1 - vb->x0);
- scaley = (rctx.vp.y1 - rctx.vp.y0) / (vb->y1 - vb->y0);
+ scalex = (rctx.vp.x1 - rctx.vp.x0) / (vb.width());
+ scaley = (rctx.vp.y1 - rctx.vp.y0) / (vb.height());
scale = (marker->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley);
- width = (vb->x1 - vb->x0) * scale;
- height = (vb->y1 - vb->y0) * scale;
+ width = (vb.width()) * scale;
+ height = (vb.height()) * scale;
/* Now place viewbox to requested position */
switch (marker->aspect_align) {
case SP_ASPECT_XMIN_YMIN:
}
}
- {
- 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) */
- marker->c2p = Geom::Translate(-marker->refX.computed, -marker->refY.computed) * marker->c2p;
+ // viewbox transformation and reference translation
+ marker->c2p = Geom::Translate(-marker->refX.computed, -marker->refY.computed) *
+ Geom::Scale(width / vb.width(), height / vb.height());
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;
+ if (marker->viewBox) {
+ rctx.vp.x0 = marker->viewBox->min()[Geom::X];
+ rctx.vp.y0 = marker->viewBox->min()[Geom::Y];
+ rctx.vp.x1 = marker->viewBox->max()[Geom::X];
+ rctx.vp.y1 = marker->viewBox->max()[Geom::Y];
rctx.i2vp = Geom::identity();
}
/* 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++) {
+ 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);
}
- }
+ }
}
}
@@ -541,8 +523,10 @@ sp_marker_write (SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::X
repr->setAttribute("orient", NULL);
}
/* fixme: */
- repr->setAttribute("viewBox", object->repr->attribute("viewBox"));
- repr->setAttribute("preserveAspectRatio", object->repr->attribute("preserveAspectRatio"));
+ //XML Tree being used directly here while it shouldn't be....
+ repr->setAttribute("viewBox", object->getRepr()->attribute("viewBox"));
+ //XML Tree being used directly here while it shouldn't be....
+ repr->setAttribute("preserveAspectRatio", object->getRepr()->attribute("preserveAspectRatio"));
if (((SPObjectClass *) (parent_class))->write)
((SPObjectClass *) (parent_class))->write (object, xml_doc, repr, flags);
void
sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size)
{
- SPMarkerView *view;
- unsigned int i;
+ SPMarkerView *view;
+ unsigned int i;
- for (view = marker->views; view != NULL; view = view->next) {
- if (view->key == key) break;
- }
- if (view && (view->size != size)) {
- /* Free old view and allocate new */
- /* Parent class ::hide method */
- ((SPItemClass *) parent_class)->hide ((SPItem *) marker, key);
- sp_marker_view_remove (marker, view, TRUE);
- view = NULL;
- }
- if (!view) {
- view = (SPMarkerView *)g_malloc (sizeof (SPMarkerView) + (size) * sizeof (NRArenaItem *));
- for (i = 0; i < size; i++) view->items[i] = NULL;
- view->next = marker->views;
- marker->views = view;
- view->key = key;
- view->size = size;
- }
+ for (view = marker->views; view != NULL; view = view->next) {
+ if (view->key == key) break;
+ }
+ if (view && (view->items.size() != size)) {
+ /* Free old view and allocate new */
+ /* Parent class ::hide method */
+ ((SPItemClass *) parent_class)->hide ((SPItem *) marker, key);
+ sp_marker_view_remove (marker, view, TRUE);
+ view = NULL;
+ }
+ if (!view) {
+ view = new SPMarkerView();
+ view->items.clear();
+ for (i = 0; i < size; i++) {
+ view->items.push_back(NULL);
+ }
+ view->next = marker->views;
+ marker->views = view;
+ view->key = key;
+ }
}
/**
{
for (SPMarkerView *v = marker->views; v != NULL; v = v->next) {
if (v->key == key) {
- if (pos >= v->size) {
+ if (pos >= v->items.size()) {
return NULL;
}
if (!v->items[pos]) {
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?
+ m = Geom::Rotate::from_degrees(marker->orient);
+ m *= Geom::Translate(base.translation());
}
if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
m = Geom::Scale(linewidth) * m;
@@ -715,19 +701,19 @@ 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]);
}
}
- g_free (view);
+ view->items.clear();
+ delete view;
}
-const gchar *
-generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, Geom::Matrix /*transform*/, Geom::Matrix move)
+const gchar *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));
+ Inkscape::XML::Document *xml_doc = document->getReprDoc();
+ Inkscape::XML::Node *defsrepr = SP_DOCUMENT_DEFS(document)->getRepr();
Inkscape::XML::Node *repr = xml_doc->createElement("svg:marker");
@@ -736,8 +722,8 @@ generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, Geom::Mat
// 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");
@@ -754,7 +740,7 @@ generate_marker (GSList *reprs, NR::Rect bounds, SPDocument *document, Geom::Mat
dup_transform = Geom::identity();
dup_transform *= move;
- sp_item_write_transform(copy, SP_OBJECT_REPR(copy), dup_transform);
+ copy->doWriteTransform(SP_OBJECT_REPR(copy), dup_transform);
}
Inkscape::GC::release(repr);