diff options
| author | Sebastian Wüst <sebi@timewaster.de> | 2013-10-20 15:32:08 +0000 |
|---|---|---|
| committer | Sebastian Wüst <sebi@timewaster.de> | 2013-10-20 15:32:08 +0000 |
| commit | 82908f949129e1fcbf62002799ee7b1b77986eed (patch) | |
| tree | c02098dd7720cdf424f2793ecd3ddac2ea86b969 /src/sp-root.cpp | |
| parent | changed text (diff) | |
| parent | Fix build errors with clang 3.3 and c++11 enabled. (diff) | |
| download | inkscape-82908f949129e1fcbf62002799ee7b1b77986eed.tar.gz inkscape-82908f949129e1fcbf62002799ee7b1b77986eed.zip | |
merge from trunk
(bzr r12417.1.24)
Diffstat (limited to 'src/sp-root.cpp')
| -rw-r--r-- | src/sp-root.cpp | 744 |
1 files changed, 366 insertions, 378 deletions
diff --git a/src/sp-root.cpp b/src/sp-root.cpp index e9ae6dff4..c87c8397d 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -31,353 +31,357 @@ #include "svg/svg.h" #include "xml/repr.h" -static void sp_root_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void sp_root_release(SPObject *object); -static void sp_root_set(SPObject *object, unsigned int key, gchar const *value); -static void sp_root_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); -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::Document *doc, Inkscape::XML::Node *repr, guint flags); - -static Inkscape::DrawingItem *sp_root_show(SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); -static void sp_root_print(SPItem *item, SPPrintContext *ctx); - -G_DEFINE_TYPE(SPRoot, sp_root, SP_TYPE_GROUP); - -/** - * Initializes an SPRootClass object by setting its class and parent class objects, and registering - * function pointers (i.e.\ gobject-style virtual functions) for various operations. - */ -static void sp_root_class_init(SPRootClass *klass) +#include "sp-factory.h" + +namespace { +SPObject *createRoot() { - SPObjectClass *sp_object_class = reinterpret_cast<SPObjectClass *>(klass); - SPItemClass *sp_item_class = reinterpret_cast<SPItemClass *>(klass); - - sp_object_class->build = sp_root_build; - sp_object_class->release = sp_root_release; - sp_object_class->set = sp_root_set; - sp_object_class->child_added = sp_root_child_added; - sp_object_class->remove_child = sp_root_remove_child; - sp_object_class->update = sp_root_update; - sp_object_class->modified = sp_root_modified; - sp_object_class->write = sp_root_write; - - sp_item_class->show = sp_root_show; - sp_item_class->print = sp_root_print; + return new SPRoot(); } -/** - * Initializes an SPRoot object by setting its default parameter values. - */ -static void sp_root_init(SPRoot *root) +bool rootRegistered = SPFactory::instance().registerObject("svg:svg", createRoot); +} + +SPRoot::SPRoot() : SPGroup() { + this->aspect_set = 0; + this->aspect_align = 0; + this->onload = NULL; + this->aspect_clip = 0; + static Inkscape::Version const zero_version(0, 0); - sp_version_from_string(SVG_VERSION, &root->original.svg); - root->version.svg = zero_version; - root->original.svg = zero_version; - root->version.inkscape = zero_version; - root->original.inkscape = zero_version; + sp_version_from_string(SVG_VERSION, &this->original.svg); + this->version.svg = zero_version; + this->original.svg = zero_version; + this->version.inkscape = zero_version; + this->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); + this->x.unset(); + this->y.unset(); + this->width.unset(SVGLength::PERCENT, 1.0, 1.0); + this->height.unset(SVGLength::PERCENT, 1.0, 1.0); - root->viewBox_set = FALSE; + this->viewBox_set = FALSE; - root->c2p.setIdentity(); + this->c2p.setIdentity(); - root->defs = NULL; + this->defs = NULL; } -/** - * Fills in the data for an SPObject from its Inkscape::XML::Node object. - * It fills in data such as version, x, y, width, height, etc. - * It then calls the object's parent class object's build function. - */ -static void sp_root_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +SPRoot::~SPRoot() { - SPGroup *group = (SPGroup *) object; - SPRoot *root = (SPRoot *) object; +} +void SPRoot::build(SPDocument *document, Inkscape::XML::Node *repr) +{ //XML Tree being used directly here while it shouldn't be. - if ( !object->getRepr()->attribute("version") ) { + if (!this->getRepr()->attribute("version")) { repr->setAttribute("version", SVG_VERSION); } - object->readAttr( "version" ); - object->readAttr( "inkscape:version" ); + this->readAttr("version"); + this->readAttr("inkscape:version"); /* It is important to parse these here, so objects will have viewport build-time */ - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "width" ); - object->readAttr( "height" ); - object->readAttr( "viewBox" ); - object->readAttr( "preserveAspectRatio" ); - object->readAttr( "onload" ); + this->readAttr("x"); + this->readAttr("y"); + this->readAttr("width"); + this->readAttr("height"); + this->readAttr("viewBox"); + this->readAttr("preserveAspectRatio"); + this->readAttr("onload"); - if (((SPObjectClass *) sp_root_parent_class)->build) - (* ((SPObjectClass *) sp_root_parent_class)->build) (object, document, repr); + SPGroup::build(document, repr); // Search for first <defs> node - for (SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { + for (SPObject *o = this->firstChild() ; o ; o = o->getNext()) { if (SP_IS_DEFS(o)) { - root->defs = SP_DEFS(o); + this->defs = SP_DEFS(o); break; } } // clear transform, if any was read in - SVG does not allow transform= on <svg> - SP_ITEM(object)->transform = Geom::identity(); + SP_ITEM(this)->transform = Geom::identity(); } -/** - * This is a destructor routine for SPRoot objects. It de-references any \<def\> items and calls - * the parent class destructor. - */ -static void sp_root_release(SPObject *object) +void SPRoot::release() { - SPRoot *root = (SPRoot *) object; - root->defs = NULL; + this->defs = NULL; - if (((SPObjectClass *) sp_root_parent_class)->release) - ((SPObjectClass *) sp_root_parent_class)->release(object); + SPGroup::release(); } -/** - * Sets the attribute given by key for SPRoot objects to the value specified by value. - */ -static void sp_root_set(SPObject *object, unsigned int key, gchar const *value) -{ - SPRoot *root = SP_ROOT(object); +void SPRoot::set(unsigned int key, const gchar *value) +{ switch (key) { - case SP_ATTR_VERSION: - if (!sp_version_from_string(value, &root->version.svg)) { - root->version.svg = root->original.svg; + case SP_ATTR_VERSION: + if (!sp_version_from_string(value, &this->version.svg)) { + this->version.svg = this->original.svg; + } + break; + + case SP_ATTR_INKSCAPE_VERSION: + if (!sp_version_from_string(value, &this->version.inkscape)) { + this->version.inkscape = this->original.inkscape; + } + break; + + case SP_ATTR_X: + if (!this->x.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->x.unset(); + } + + /* fixme: I am almost sure these do not require viewport flag (Lauris) */ + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + + case SP_ATTR_Y: + if (!this->y.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->y.unset(); + } + + /* fixme: I am almost sure these do not require viewport flag (Lauris) */ + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + + case SP_ATTR_WIDTH: + if (!this->width.readAbsolute(value) || !(this->width.computed > 0.0)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->width.unset(SVGLength::PERCENT, 1.0, 1.0); + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + + case SP_ATTR_HEIGHT: + if (!this->height.readAbsolute(value) || !(this->height.computed > 0.0)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + this->height.unset(SVGLength::PERCENT, 1.0, 1.0); + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + + case SP_ATTR_VIEWBOX: + 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++; } - break; - case SP_ATTR_INKSCAPE_VERSION: - if (!sp_version_from_string(value, &root->version.inkscape)) { - root->version.inkscape = root->original.inkscape; + + y = g_ascii_strtod(eptr, &eptr); + + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; } - break; - case SP_ATTR_X: - if (!root->x.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - root->x.unset(); + + width = g_ascii_strtod(eptr, &eptr); + + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; } - /* fixme: I am almost sure these do not require viewport flag (Lauris) */ - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; - case SP_ATTR_Y: - if (!root->y.readAbsolute(value)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - root->y.unset(); + + height = g_ascii_strtod(eptr, &eptr); + + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; } - /* fixme: I am almost sure these do not require viewport flag (Lauris) */ - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; - case SP_ATTR_WIDTH: - if (!root->width.readAbsolute(value) || !(root->width.computed > 0.0)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - root->width.unset(SVGLength::PERCENT, 1.0, 1.0); + + if ((width > 0) && (height > 0)) { + /* Set viewbox */ + this->viewBox = Geom::Rect::from_xywh(x, y, width, height); + this->viewBox_set = TRUE; + } else { + this->viewBox_set = FALSE; } - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; - case SP_ATTR_HEIGHT: - if (!root->height.readAbsolute(value) || !(root->height.computed > 0.0)) { - /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ - root->height.unset(SVGLength::PERCENT, 1.0, 1.0); + } else { + this->viewBox_set = FALSE; + } + + 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_XMID_YMID; + this->aspect_clip = SP_ASPECT_MEET; + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + + if (value) { + int len; + gchar c[256]; + gchar const *p, *e; + unsigned int align, clip; + p = value; + + while (*p && *p == 32) { + p += 1; } - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; - case SP_ATTR_VIEWBOX: - 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 */ - root->viewBox = Geom::Rect::from_xywh(x, y, width, height); - root->viewBox_set = TRUE; - } else { - root->viewBox_set = FALSE; - } + + 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 { - root->viewBox_set = FALSE; + break; } - object->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 */ - root->aspect_set = FALSE; - root->aspect_align = SP_ASPECT_XMID_YMID; - root->aspect_clip = SP_ASPECT_MEET; - object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - if (value) { - int len; - gchar c[256]; - gchar const *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; + + 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; } - 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; - } - } - root->aspect_set = TRUE; - root->aspect_align = align; - root->aspect_clip = clip; - } - break; - case SP_ATTR_ONLOAD: - root->onload = (char *) value; - break; - default: - /* Pass the set event to the parent */ - if (((SPObjectClass *) sp_root_parent_class)->set) { - ((SPObjectClass *) sp_root_parent_class)->set(object, key, value); } - break; + + this->aspect_set = TRUE; + this->aspect_align = align; + this->aspect_clip = clip; + } + break; + + case SP_ATTR_ONLOAD: + this->onload = (char *) value; + break; + + default: + /* Pass the set event to the parent */ + SPGroup::set(key, value); + break; } } -/** - * 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) +void SPRoot::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { - SPRoot *root = (SPRoot *) object; - SPGroup *group = (SPGroup *) object; + SPGroup::child_added(child, ref); - if (((SPObjectClass *) (sp_root_parent_class))->child_added) { - (* ((SPObjectClass *) (sp_root_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 + SPObject *co = this->document->getObjectByRepr(child); + // NOTE: some XML nodes do not have corresponding SP objects, + // for instance inkscape:clipboard used in the clipboard code. + // See LP bug #1227827 + //g_assert (co != NULL || !strcmp("comment", child->name())); // comment repr node has no object if (co && SP_IS_DEFS(co)) { // We search for first <defs> node - it is not beautiful, but works - for (SPObject *c = group->firstChild() ; c ; c = c->getNext() ) { + for (SPObject *c = this->firstChild() ; c ; c = c->getNext()) { if (SP_IS_DEFS(c)) { - root->defs = SP_DEFS(c); + this->defs = SP_DEFS(c); break; } } } } -/** - * Removes the given child from this SPRoot object. - */ -static void sp_root_remove_child(SPObject *object, Inkscape::XML::Node *child) +void SPRoot::remove_child(Inkscape::XML::Node *child) { - SPRoot *root = (SPRoot *) object; - - if ( root->defs && (root->defs->getRepr() == child) ) { + if (this->defs && (this->defs->getRepr() == child)) { 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; + for (iter = this->firstChild() ; iter ; iter = iter->getNext()) { + if (SP_IS_DEFS(iter) && (SPDefs *)iter != this->defs) { + this->defs = (SPDefs *)iter; break; } } + if (!iter) { /* we should probably create a new <defs> here? */ - root->defs = NULL; + this->defs = NULL; } } - if (((SPObjectClass *) (sp_root_parent_class))->remove_child) { - (* ((SPObjectClass *) (sp_root_parent_class))->remove_child)(object, child); - } + SPGroup::remove_child(child); } -/** - * This callback routine updates the SPRoot object when its attributes have been changed. - */ -static void sp_root_update(SPObject *object, SPCtx *ctx, guint flags) +void SPRoot::update(SPCtx *ctx, guint flags) { - SPRoot *root = SP_ROOT(object); SPItemCtx *ictx = (SPItemCtx *) ctx; /* fixme: This will be invoked too often (Lauris) */ /* fixme: We should calculate only if parent viewport has changed (Lauris) */ /* If position is specified as percentage, calculate actual values */ - if (root->x.unit == SVGLength::PERCENT) { - root->x.computed = root->x.value * ictx->viewport.width(); + if (this->x.unit == SVGLength::PERCENT) { + this->x.computed = this->x.value * ictx->viewport.width(); } - if (root->y.unit == SVGLength::PERCENT) { - root->y.computed = root->y.value * ictx->viewport.height(); + + if (this->y.unit == SVGLength::PERCENT) { + this->y.computed = this->y.value * ictx->viewport.height(); } - if (root->width.unit == SVGLength::PERCENT) { - root->width.computed = root->width.value * ictx->viewport.width(); + + if (this->width.unit == SVGLength::PERCENT) { + this->width.computed = this->width.value * ictx->viewport.width(); } - if (root->height.unit == SVGLength::PERCENT) { - root->height.computed = root->height.value * ictx->viewport.height(); + + if (this->height.unit == SVGLength::PERCENT) { + this->height.computed = this->height.value * ictx->viewport.height(); } /* Create copy of item context */ SPItemCtx rctx = *ictx; /* Calculate child to parent transformation */ - root->c2p.setIdentity(); + this->c2p.setIdentity(); - if (object->parent) { + if (this->parent) { /* * fixme: I am not sure whether setting x and y does or does not * fixme: translate the content of inner SVG. @@ -385,136 +389,132 @@ static void 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 = Geom::Affine(Geom::Translate(root->x.computed, - root->y.computed)); + this->c2p = Geom::Affine(Geom::Translate(this->x.computed, this->y.computed)); } - if (root->viewBox_set) { + if (this->viewBox_set) { double x, y, width, height; /* Determine actual viewbox in viewport coordinates */ - if (root->aspect_align == SP_ASPECT_NONE) { + if (this->aspect_align == SP_ASPECT_NONE) { x = 0.0; y = 0.0; - width = root->width.computed; - height = root->height.computed; + width = this->width.computed; + height = this->height.computed; } else { double scalex, scaley, scale; /* Things are getting interesting */ - scalex = root->width.computed / root->viewBox.width(); - scaley = root->height.computed / root->viewBox.height(); - scale = (root->aspect_clip == SP_ASPECT_MEET) ? MIN(scalex, scaley) : MAX(scalex, scaley); - width = root->viewBox.width() * scale; - height = root->viewBox.height() * scale; + scalex = this->width.computed / this->viewBox.width(); + scaley = this->height.computed / this->viewBox.height(); + scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN(scalex, scaley) : MAX(scalex, scaley); + width = this->viewBox.width() * scale; + height = this->viewBox.height() * scale; + /* Now place viewbox to requested position */ /* todo: Use an array lookup to find the 0.0/0.5/1.0 coefficients, as is done for dialogs/align.cpp. */ - switch (root->aspect_align) { - case SP_ASPECT_XMIN_YMIN: - x = 0.0; - y = 0.0; - break; - case SP_ASPECT_XMID_YMIN: - x = 0.5 * (root->width.computed - width); - y = 0.0; - break; - case SP_ASPECT_XMAX_YMIN: - x = 1.0 * (root->width.computed - width); - y = 0.0; - break; - case SP_ASPECT_XMIN_YMID: - x = 0.0; - y = 0.5 * (root->height.computed - height); - break; - case SP_ASPECT_XMID_YMID: - x = 0.5 * (root->width.computed - width); - y = 0.5 * (root->height.computed - height); - break; - case SP_ASPECT_XMAX_YMID: - x = 1.0 * (root->width.computed - width); - y = 0.5 * (root->height.computed - height); - break; - case SP_ASPECT_XMIN_YMAX: - x = 0.0; - y = 1.0 * (root->height.computed - height); - break; - case SP_ASPECT_XMID_YMAX: - x = 0.5 * (root->width.computed - width); - y = 1.0 * (root->height.computed - height); - break; - case SP_ASPECT_XMAX_YMAX: - x = 1.0 * (root->width.computed - width); - y = 1.0 * (root->height.computed - height); - break; - default: - x = 0.0; - y = 0.0; - break; + switch (this->aspect_align) { + case SP_ASPECT_XMIN_YMIN: + x = 0.0; + y = 0.0; + break; + + case SP_ASPECT_XMID_YMIN: + x = 0.5 * (this->width.computed - width); + y = 0.0; + break; + + case SP_ASPECT_XMAX_YMIN: + x = 1.0 * (this->width.computed - width); + y = 0.0; + break; + + case SP_ASPECT_XMIN_YMID: + x = 0.0; + y = 0.5 * (this->height.computed - height); + break; + + case SP_ASPECT_XMID_YMID: + x = 0.5 * (this->width.computed - width); + y = 0.5 * (this->height.computed - height); + break; + + case SP_ASPECT_XMAX_YMID: + x = 1.0 * (this->width.computed - width); + y = 0.5 * (this->height.computed - height); + break; + + case SP_ASPECT_XMIN_YMAX: + x = 0.0; + y = 1.0 * (this->height.computed - height); + break; + + case SP_ASPECT_XMID_YMAX: + x = 0.5 * (this->width.computed - width); + y = 1.0 * (this->height.computed - height); + break; + + case SP_ASPECT_XMAX_YMAX: + x = 1.0 * (this->width.computed - width); + y = 1.0 * (this->height.computed - height); + break; + + default: + x = 0.0; + y = 0.0; + break; } } /* Compose additional transformation from scale and position */ - Geom::Scale const viewBox_length( root->viewBox.dimensions() ); + Geom::Scale const viewBox_length(this->viewBox.dimensions()); 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 = Geom::Translate(-root->viewBox.min()) * ( new_length * viewBox_length.inverse() ) * Geom::Translate(x, y) * root->c2p; + this->c2p = Geom::Translate(-this->viewBox.min()) * (new_length * viewBox_length.inverse()) * Geom::Translate(x, y) * this->c2p; } - rctx.i2doc = root->c2p * rctx.i2doc; + rctx.i2doc = this->c2p * rctx.i2doc; /* Initialize child viewport */ - if (root->viewBox_set) { - rctx.viewport = root->viewBox; + if (this->viewBox_set) { + rctx.viewport = this->viewBox; } else { /* fixme: I wonder whether this logic is correct (Lauris) */ - Geom::Point minp(0,0); - if (object->parent) { - minp = Geom::Point(root->x.computed, root->y.computed); + Geom::Point minp(0, 0); + if (this->parent) { + minp = Geom::Point(this->x.computed, this->y.computed); } - rctx.viewport = Geom::Rect::from_xywh(minp[Geom::X], minp[Geom::Y], root->width.computed, root->height.computed); + + rctx.viewport = Geom::Rect::from_xywh(minp[Geom::X], minp[Geom::Y], this->width.computed, this->height.computed); } rctx.i2vp = Geom::identity(); /* And invoke parent method */ - if (((SPObjectClass *) (sp_root_parent_class))->update) - ((SPObjectClass *) (sp_root_parent_class))->update(object, (SPCtx *) &rctx, flags); + SPGroup::update((SPCtx *) &rctx, flags); /* As last step set additional transform of drawing group */ - for (SPItemView *v = root->display; v != NULL; v = v->next) { + for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); - g->setChildTransform(root->c2p); + g->setChildTransform(this->c2p); } } -/** - * Calls the <tt>modified</tt> routine of the SPRoot object's parent class. - * Also, if the viewport has been modified, it sets the document size to the new - * height and width. - */ -static void sp_root_modified(SPObject *object, guint flags) +void SPRoot::modified(unsigned int flags) { - SPRoot *root = SP_ROOT(object); - - if (((SPObjectClass *) (sp_root_parent_class))->modified) - (* ((SPObjectClass *) (sp_root_parent_class))->modified)(object, flags); + SPGroup::modified(flags); /* fixme: (Lauris) */ - if (!object->parent && (flags & SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { - root->document->emitResizedSignal(root->width.computed, root->height.computed); + if (!this->parent && (flags & SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + this->document->emitResizedSignal(this->width.computed, this->height.computed); } } -/** - * 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::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - SPRoot *root = SP_ROOT(object); +Inkscape::XML::Node *SPRoot::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:svg"); } @@ -523,70 +523,58 @@ sp_root_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML: repr->setAttribute("inkscape:version", Inkscape::version_string); } - if ( !repr->attribute("version") ) { - gchar* myversion = sp_version_to_string(root->version.svg); + if (!repr->attribute("version")) { + gchar *myversion = sp_version_to_string(this->version.svg); repr->setAttribute("version", myversion); g_free(myversion); } - if (fabs(root->x.computed) > 1e-9) - sp_repr_set_svg_double(repr, "x", root->x.computed); - if (fabs(root->y.computed) > 1e-9) - sp_repr_set_svg_double(repr, "y", root->y.computed); + if (fabs(this->x.computed) > 1e-9) { + sp_repr_set_svg_double(repr, "x", this->x.computed); + } + + if (fabs(this->y.computed) > 1e-9) { + sp_repr_set_svg_double(repr, "y", this->y.computed); + } /* Unlike all other SPObject, here we want to preserve absolute units too (and only here, * according to the recommendation in http://www.w3.org/TR/SVG11/coords.html#Units). */ - repr->setAttribute("width", sp_svg_length_write_with_units(root->width).c_str()); - repr->setAttribute("height", sp_svg_length_write_with_units(root->height).c_str()); + repr->setAttribute("width", sp_svg_length_write_with_units(this->width).c_str()); + repr->setAttribute("height", sp_svg_length_write_with_units(this->height).c_str()); - if (root->viewBox_set) { + if (this->viewBox_set) { Inkscape::SVGOStringStream os; - os << root->viewBox.left() << " " << root->viewBox.top() << " " - << root->viewBox.width() << " " << root->viewBox.height(); + os << this->viewBox.left() << " " << this->viewBox.top() << " " + << this->viewBox.width() << " " << this->viewBox.height(); + repr->setAttribute("viewBox", os.str().c_str()); } - if (((SPObjectClass *) (sp_root_parent_class))->write) - ((SPObjectClass *) (sp_root_parent_class))->write(object, xml_doc, repr, flags); + SPGroup::write(xml_doc, repr, flags); return repr; } -/** - * Displays the SPRoot item on the drawing. - */ -static Inkscape::DrawingItem * -sp_root_show(SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) +Inkscape::DrawingItem *SPRoot::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { - SPRoot *root = SP_ROOT(item); - - Inkscape::DrawingItem *ai; - if (((SPItemClass *) (sp_root_parent_class))->show) { - ai = ((SPItemClass *) (sp_root_parent_class))->show(item, drawing, key, flags); - if (ai) { - Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(ai); - g->setChildTransform(root->c2p); - } - } else { - ai = NULL; + Inkscape::DrawingItem *ai = 0; + + ai = SPGroup::show(drawing, key, flags); + + if (ai) { + Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(ai); + g->setChildTransform(this->c2p); } return ai; } -/** - * Virtual print callback. - */ -static void sp_root_print(SPItem *item, SPPrintContext *ctx) +void SPRoot::print(SPPrintContext *ctx) { - SPRoot *root = SP_ROOT(item); + sp_print_bind(ctx, this->c2p, 1.0); - sp_print_bind(ctx, root->c2p, 1.0); - - if (((SPItemClass *) (sp_root_parent_class))->print) { - ((SPItemClass *) (sp_root_parent_class))->print(item, ctx); - } + SPGroup::print(ctx); sp_print_release(ctx); } |
