Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / sp-root.cpp
index 6ad5ff6385798398609a62eb89c2c6b993c5ba15..5f868539b1eab0449e7366d1342fca5f615a751e 100644 (file)
@@ -1,11 +1,11 @@
-#define __SP_ROOT_C__
-
 /** \file
  * SVG \<svg\> implementation.
  */
 /*
  * Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 1999-2002 Lauris Kaplinski
  * Copyright (C) 2000-2001 Ximian, Inc.
@@ -34,7 +34,7 @@
 #include <libnr/nr-translate-scale-ops.h>
 #include <xml/repr.h>
 #include "svg/stringstream.h"
-#include "inkscape_version.h"
+#include "inkscape-version.h"
 
 class SPDesktop;
 
@@ -48,10 +48,9 @@ static void sp_root_child_added(SPObject *object, Inkscape::XML::Node *child, In
 static void sp_root_remove_child(SPObject *object, Inkscape::XML::Node *child);
 static void sp_root_update(SPObject *object, SPCtx *ctx, guint flags);
 static void sp_root_modified(SPObject *object, guint flags);
-static Inkscape::XML::Node *sp_root_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
+static Inkscape::XML::Node *sp_root_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
 
 static NRArenaItem *sp_root_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
-static void sp_root_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags);
 static void sp_root_print(SPItem *item, SPPrintContext *ctx);
 
 static SPGroupClass *parent_class;
@@ -106,7 +105,6 @@ sp_root_class_init(SPRootClass *klass)
     sp_object_class->write = sp_root_write;
 
     sp_item_class->show = sp_root_show;
-    sp_item_class->bbox = sp_root_bbox;
     sp_item_class->print = sp_root_print;
 }
 
@@ -119,19 +117,20 @@ sp_root_init(SPRoot *root)
     static Inkscape::Version const zero_version(0, 0);
 
     sp_version_from_string(SVG_VERSION, &root->original.svg);
-    root->version.svg = root->original.svg;
-    root->version.inkscape = root->original.inkscape =
-        root->version.sodipodi = root->original.sodipodi = zero_version;
+    root->version.svg = zero_version;
+    root->original.svg = zero_version;
+    root->version.inkscape = zero_version;
+    root->original.inkscape = zero_version;
 
     root->x.unset();
     root->y.unset();
     root->width.unset(SVGLength::PERCENT, 1.0, 1.0);
     root->height.unset(SVGLength::PERCENT, 1.0, 1.0);
 
-    /* nr_matrix_set_identity(&root->viewbox); */
+    /* root->viewbox.set_identity(); */
     root->viewBox_set = FALSE;
 
-    root->c2p.set_identity();
+    root->c2p.setIdentity();
 
     root->defs = NULL;
 }
@@ -147,27 +146,27 @@ sp_root_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
     SPGroup *group = (SPGroup *) object;
     SPRoot *root = (SPRoot *) object;
 
-    if (repr->attribute("sodipodi:docname") || repr->attribute("SP-DOCNAME")) {
-        /* so we have a nonzero initial version */
-        root->original.sodipodi.major = 0;
-        root->original.sodipodi.minor = 1;
+    //XML Tree being used directly here while it shouldn't be.
+    if ( !object->getRepr()->attribute("version") ) {
+        repr->setAttribute("version", SVG_VERSION);
     }
-    sp_object_read_attr(object, "version");
-    sp_object_read_attr(object, "sodipodi:version");
-    sp_object_read_attr(object, "inkscape:version");
+
+    object->readAttr( "version" );
+    object->readAttr( "inkscape:version" );
     /* It is important to parse these here, so objects will have viewport build-time */
-    sp_object_read_attr(object, "x");
-    sp_object_read_attr(object, "y");
-    sp_object_read_attr(object, "width");
-    sp_object_read_attr(object, "height");
-    sp_object_read_attr(object, "viewBox");
-    sp_object_read_attr(object, "preserveAspectRatio");
+    object->readAttr( "x" );
+    object->readAttr( "y" );
+    object->readAttr( "width" );
+    object->readAttr( "height" );
+    object->readAttr( "viewBox" );
+    object->readAttr( "preserveAspectRatio" );
+    object->readAttr( "onload" );
 
     if (((SPObjectClass *) parent_class)->build)
         (* ((SPObjectClass *) parent_class)->build) (object, document, repr);
 
-    /* Search for first <defs> node */
-    for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL; o = SP_OBJECT_NEXT(o) ) {
+    // Search for first <defs> node
+    for (SPObject *o = group->firstChild() ; o ; o = o->getNext() ) {
         if (SP_IS_DEFS(o)) {
             root->defs = SP_DEFS(o);
             break;
@@ -175,7 +174,7 @@ sp_root_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
     }
 
     // clear transform, if any was read in - SVG does not allow transform= on <svg>
-    SP_ITEM(object)->transform = NR::identity();
+    SP_ITEM(object)->transform = Geom::identity();
 }
 
 /**
@@ -206,10 +205,6 @@ sp_root_set(SPObject *object, unsigned int key, gchar const *value)
                 root->version.svg = root->original.svg;
             }
             break;
-        case SP_ATTR_SODIPODI_VERSION:
-            if (!sp_version_from_string(value, &root->version.sodipodi)) {
-                root->version.sodipodi = root->original.sodipodi;
-            }
         case SP_ATTR_INKSCAPE_VERSION:
             if (!sp_version_from_string(value, &root->version.inkscape)) {
                 root->version.inkscape = root->original.inkscape;
@@ -308,7 +303,7 @@ sp_root_set(SPObject *object, unsigned int key, gchar const *value)
                     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;
@@ -321,7 +316,7 @@ sp_root_set(SPObject *object, unsigned int key, gchar const *value)
                 }
                 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")) {
@@ -335,6 +330,9 @@ sp_root_set(SPObject *object, unsigned int key, gchar const *value)
                 root->aspect_clip = clip;
             }
             break;
+        case SP_ATTR_ONLOAD:
+            root->onload = (char *) value;
+            break;
         default:
             /* Pass the set event to the parent */
             if (((SPObjectClass *) parent_class)->set) {
@@ -348,22 +346,21 @@ sp_root_set(SPObject *object, unsigned int key, gchar const *value)
  * This routine is for adding a child SVG object to an SPRoot object.
  * The SPRoot object is taken to be an SPGroup.
  */
-static void
-sp_root_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
+static void sp_root_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
 {
     SPRoot *root = (SPRoot *) object;
     SPGroup *group = (SPGroup *) object;
 
-    if (((SPObjectClass *) (parent_class))->child_added)
+    if (((SPObjectClass *) (parent_class))->child_added) {
         (* ((SPObjectClass *) (parent_class))->child_added)(object, child, ref);
+    }
 
     SPObject *co = object->document->getObjectByRepr(child);
     g_assert (co != NULL || !strcmp("comment", child->name())); // comment repr node has no object
 
     if (co && SP_IS_DEFS(co)) {
-        SPObject *c;
-        /* We search for first <defs> node - it is not beautiful, but works */
-        for (c = sp_object_first_child(SP_OBJECT(group)) ; c != NULL; c = SP_OBJECT_NEXT(c) ) {
+        // We search for first <defs> node - it is not beautiful, but works
+        for (SPObject *c = group->firstChild() ; c ; c = c->getNext() ) {
             if (SP_IS_DEFS(c)) {
                 root->defs = SP_DEFS(c);
                 break;
@@ -380,9 +377,9 @@ static void sp_root_remove_child(SPObject *object, Inkscape::XML::Node *child)
     SPRoot *root = (SPRoot *) object;
 
     if ( root->defs && SP_OBJECT_REPR(root->defs) == child ) {
-        SPObject *iter;
-        /* We search for first remaining <defs> node - it is not beautiful, but works */
-        for ( iter = sp_object_first_child(object) ; iter ; iter = SP_OBJECT_NEXT(iter) ) {
+        SPObject *iter = 0;
+        // We search for first remaining <defs> node - it is not beautiful, but works
+        for ( iter = object->firstChild() ; iter ; iter = iter->getNext() ) {
             if ( SP_IS_DEFS(iter) && (SPDefs *)iter != root->defs ) {
                 root->defs = (SPDefs *)iter;
                 break;
@@ -394,8 +391,9 @@ static void sp_root_remove_child(SPObject *object, Inkscape::XML::Node *child)
         }
     }
 
-    if (((SPObjectClass *) (parent_class))->remove_child)
+    if (((SPObjectClass *) (parent_class))->remove_child) {
         (* ((SPObjectClass *) (parent_class))->remove_child)(object, child);
+    }
 }
 
 /**
@@ -430,7 +428,7 @@ sp_root_update(SPObject *object, SPCtx *ctx, guint flags)
     SPItemCtx rctx = *ictx;
 
     /* Calculate child to parent transformation */
-    root->c2p.set_identity();
+    root->c2p.setIdentity();
 
     if (object->parent) {
         /*
@@ -440,8 +438,8 @@ sp_root_update(SPObject *object, SPCtx *ctx, guint flags)
          * fixme: height seems natural, as this makes the inner svg element
          * fixme: self-contained. The spec is vague here.
          */
-        root->c2p = NR::Matrix(NR::translate(root->x.computed,
-                                             root->y.computed));
+        root->c2p = Geom::Matrix(Geom::Translate(root->x.computed,
+                                                 root->y.computed));
     }
 
     if (root->viewBox_set) {
@@ -508,17 +506,17 @@ sp_root_update(SPObject *object, SPCtx *ctx, guint flags)
         }
 
         /* Compose additional transformation from scale and position */
-        NR::Point const viewBox_min(root->viewBox.x0,
+        Geom::Point const viewBox_min(root->viewBox.x0,
                                     root->viewBox.y0);
-        NR::Point const viewBox_max(root->viewBox.x1,
+        Geom::Point const viewBox_max(root->viewBox.x1,
                                     root->viewBox.y1);
-        NR::scale const viewBox_length( viewBox_max - viewBox_min );
-        NR::scale const new_length(width, height);
+        Geom::Scale const viewBox_length( viewBox_max - viewBox_min );
+        Geom::Scale const new_length(width, height);
 
         /* Append viewbox transformation */
         /* TODO: The below looks suspicious to me (pjrm): I wonder whether the RHS
            expression should have c2p at the beginning rather than at the end.  Test it. */
-        root->c2p = NR::translate(-viewBox_min) * ( new_length / viewBox_length ) * NR::translate(x, y) * root->c2p;
+        root->c2p = Geom::Translate(-viewBox_min) * ( new_length * viewBox_length.inverse() ) * Geom::Translate(x, y) * root->c2p;
     }
 
     rctx.i2doc = root->c2p * rctx.i2doc;
@@ -542,7 +540,7 @@ sp_root_update(SPObject *object, SPCtx *ctx, guint flags)
         rctx.vp.y1 = root->height.computed;
     }
 
-    rctx.i2vp = NR::identity();
+    rctx.i2vp = Geom::identity();
 
     /* And invoke parent method */
     if (((SPObjectClass *) (parent_class))->update)
@@ -569,7 +567,7 @@ sp_root_modified(SPObject *object, guint flags)
 
     /* fixme: (Lauris) */
     if (!object->parent && (flags & SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) {
-        sp_document_resized_signal_emit (SP_OBJECT_DOCUMENT(root), root->width.computed, root->height.computed);
+        SP_OBJECT_DOCUMENT(root)->emitResizedSignal(root->width.computed, root->height.computed);
     }
 }
 
@@ -577,21 +575,21 @@ sp_root_modified(SPObject *object, guint flags)
  * Writes the object into the repr object, then calls the parent's write routine.
  */
 static Inkscape::XML::Node *
-sp_root_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
+sp_root_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
 {
     SPRoot *root = SP_ROOT(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:svg");
     }
 
     if (flags & SP_OBJECT_WRITE_EXT) {
-        repr->setAttribute("sodipodi:version", SODIPODI_VERSION);
-        repr->setAttribute("inkscape:version", INKSCAPE_VERSION);
+        repr->setAttribute("inkscape:version", Inkscape::version_string);
     }
 
-    repr->setAttribute("version", SVG_VERSION);
+    if ( !repr->attribute("version") ) {
+        repr->setAttribute("version", sp_version_to_string(root->version.svg));
+    }
 
     if (fabs(root->x.computed) > 1e-9)
         sp_repr_set_svg_double(repr, "x", root->x.computed);
@@ -611,7 +609,7 @@ sp_root_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
     }
 
     if (((SPObjectClass *) (parent_class))->write)
-        ((SPObjectClass *) (parent_class))->write(object, repr, flags);
+        ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags);
 
     return repr;
 }
@@ -637,22 +635,6 @@ sp_root_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags)
     return ai;
 }
 
-/**
- * Virtual bbox callback.
- */
-static void
-sp_root_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags)
-{
-    SPRoot const *root = SP_ROOT(item);
-
-    if (((SPItemClass *) (parent_class))->bbox) {
-        NR::Matrix const product( root->c2p * transform );
-        ((SPItemClass *) (parent_class))->bbox(item, bbox,
-                                               product,
-                                               flags);
-    }
-}
-
 /**
  * Virtual print callback.
  */
@@ -680,4 +662,4 @@ sp_root_print(SPItem *item, SPPrintContext *ctx)
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :