summaryrefslogtreecommitdiffstats
path: root/src/sp-flowregion.cpp
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2006-01-16 02:36:01 +0000
committermental <mental@users.sourceforge.net>2006-01-16 02:36:01 +0000
commit179fa413b047bede6e32109e2ce82437c5fb8d34 (patch)
treea5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/sp-flowregion.cpp
downloadinkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz
inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/sp-flowregion.cpp')
-rw-r--r--src/sp-flowregion.cpp544
1 files changed, 544 insertions, 0 deletions
diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp
new file mode 100644
index 000000000..4071e4d92
--- /dev/null
+++ b/src/sp-flowregion.cpp
@@ -0,0 +1,544 @@
+#define __SP_FLOWREGION_C__
+
+/*
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <glibmm/i18n.h>
+
+#include <xml/repr.h>
+#include "display/curve.h"
+#include "sp-shape.h"
+#include "sp-text.h"
+#include "sp-use.h"
+#include "style.h"
+
+#include "sp-flowregion.h"
+
+#include "display/canvas-bpath.h"
+
+
+#include "livarot/Path.h"
+#include "livarot/Shape.h"
+
+static void sp_flowregion_class_init (SPFlowregionClass *klass);
+static void sp_flowregion_init (SPFlowregion *group);
+static void sp_flowregion_dispose (GObject *object);
+
+static void sp_flowregion_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref);
+static void sp_flowregion_remove_child (SPObject * object, Inkscape::XML::Node * child);
+static void sp_flowregion_update (SPObject *object, SPCtx *ctx, guint flags);
+static void sp_flowregion_modified (SPObject *object, guint flags);
+static Inkscape::XML::Node *sp_flowregion_write (SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static gchar * sp_flowregion_description (SPItem * item);
+
+static SPItemClass * flowregion_parent_class;
+
+static void sp_flowregionexclude_class_init (SPFlowregionExcludeClass *klass);
+static void sp_flowregionexclude_init (SPFlowregionExclude *group);
+static void sp_flowregionexclude_dispose (GObject *object);
+
+static void sp_flowregionexclude_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref);
+static void sp_flowregionexclude_remove_child (SPObject * object, Inkscape::XML::Node * child);
+static void sp_flowregionexclude_update (SPObject *object, SPCtx *ctx, guint flags);
+static void sp_flowregionexclude_modified (SPObject *object, guint flags);
+static Inkscape::XML::Node *sp_flowregionexclude_write (SPObject *object, Inkscape::XML::Node *repr, guint flags);
+
+static gchar * sp_flowregionexclude_description (SPItem * item);
+
+static SPItemClass * flowregionexclude_parent_class;
+
+
+static void GetDest(SPObject* child,Shape **computed,NR::Matrix itr_mat);
+
+GType
+sp_flowregion_get_type (void)
+{
+ static GType group_type = 0;
+ if (!group_type) {
+ GTypeInfo group_info = {
+ sizeof (SPFlowregionClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) sp_flowregion_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (SPFlowregion),
+ 16, /* n_preallocs */
+ (GInstanceInitFunc) sp_flowregion_init,
+ NULL, /* value_table */
+ };
+ group_type = g_type_register_static (SP_TYPE_ITEM, "SPFlowregion", &group_info, (GTypeFlags)0);
+ }
+ return group_type;
+}
+
+static void
+sp_flowregion_class_init (SPFlowregionClass *klass)
+{
+ GObjectClass * object_class;
+ SPObjectClass * sp_object_class;
+ SPItemClass * item_class;
+
+ object_class = (GObjectClass *) klass;
+ sp_object_class = (SPObjectClass *) klass;
+ item_class = (SPItemClass *) klass;
+
+ flowregion_parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM);
+
+ object_class->dispose = sp_flowregion_dispose;
+
+ sp_object_class->child_added = sp_flowregion_child_added;
+ sp_object_class->remove_child = sp_flowregion_remove_child;
+ sp_object_class->update = sp_flowregion_update;
+ sp_object_class->modified = sp_flowregion_modified;
+ sp_object_class->write = sp_flowregion_write;
+
+ item_class->description = sp_flowregion_description;
+}
+
+static void
+sp_flowregion_init (SPFlowregion *group)
+{
+ new (&group->computed) std::vector<Shape*>;
+}
+
+static void
+sp_flowregion_dispose(GObject *object)
+{
+ SPFlowregion *group=(SPFlowregion *)object;
+ for (std::vector<Shape*>::iterator it = group->computed.begin() ; it != group->computed.end() ; it++)
+ delete *it;
+ group->computed.~vector<Shape*>();
+}
+
+static void
+sp_flowregion_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
+{
+ SPItem *item;
+
+ item = SP_ITEM (object);
+
+ if (((SPObjectClass *) (flowregion_parent_class))->child_added)
+ (* ((SPObjectClass *) (flowregion_parent_class))->child_added) (object, child, ref);
+
+ object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+/* fixme: hide (Lauris) */
+
+static void
+sp_flowregion_remove_child (SPObject * object, Inkscape::XML::Node * child)
+{
+ if (((SPObjectClass *) (flowregion_parent_class))->remove_child)
+ (* ((SPObjectClass *) (flowregion_parent_class))->remove_child) (object, child);
+
+ object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+
+static void
+sp_flowregion_update (SPObject *object, SPCtx *ctx, unsigned int flags)
+{
+ SPFlowregion *group;
+ SPObject *child;
+ SPItemCtx *ictx, cctx;
+ GSList *l;
+
+ group = SP_FLOWREGION (object);
+ ictx = (SPItemCtx *) ctx;
+ cctx = *ictx;
+
+ if (((SPObjectClass *) (flowregion_parent_class))->update)
+ ((SPObjectClass *) (flowregion_parent_class))->update (object, ctx, flags);
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
+
+ l = NULL;
+ for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
+ g_object_ref (G_OBJECT (child));
+ l = g_slist_prepend (l, child);
+ }
+ l = g_slist_reverse (l);
+ while (l) {
+ child = SP_OBJECT (l->data);
+ l = g_slist_remove (l, child);
+ if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ if (SP_IS_ITEM (child)) {
+ SPItem const &chi = *SP_ITEM(child);
+ cctx.i2doc = chi.transform * ictx->i2doc;
+ cctx.i2vp = chi.transform * ictx->i2vp;
+ child->updateDisplay((SPCtx *)&cctx, flags);
+ } else {
+ child->updateDisplay(ctx, flags);
+ }
+ }
+ g_object_unref (G_OBJECT (child));
+ }
+
+ group->UpdateComputed();
+}
+
+void SPFlowregion::UpdateComputed(void)
+{
+ SPObject* object=SP_OBJECT(this);
+
+ NR::Matrix itr_mat=sp_item_i2root_affine (SP_ITEM(object));
+ itr_mat=itr_mat.inverse();
+
+ for (std::vector<Shape*>::iterator it = computed.begin() ; it != computed.end() ; it++)
+ delete *it;
+ computed.clear();
+
+ for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
+ Shape *shape = NULL;
+ GetDest(child,&shape,itr_mat);
+ computed.push_back(shape);
+ }
+}
+
+static void
+sp_flowregion_modified (SPObject *object, guint flags)
+{
+ SPFlowregion *group;
+ SPObject *child;
+ GSList *l;
+
+ group = SP_FLOWREGION (object);
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
+
+ l = NULL;
+ for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
+ g_object_ref (G_OBJECT (child));
+ l = g_slist_prepend (l, child);
+ }
+ l = g_slist_reverse (l);
+ while (l) {
+ child = SP_OBJECT (l->data);
+ l = g_slist_remove (l, child);
+ if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ child->emitModified(flags);
+ }
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+static Inkscape::XML::Node *
+sp_flowregion_write (SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+ if (flags & SP_OBJECT_WRITE_BUILD) {
+ if ( repr == NULL ) repr = sp_repr_new ("svg:flowRegion");
+
+ GSList *l = NULL;
+ for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ Inkscape::XML::Node *crepr = child->updateRepr(NULL, flags);
+ if (crepr) l = g_slist_prepend(l, crepr);
+ }
+
+ while (l) {
+ repr->addChild((Inkscape::XML::Node *) l->data, NULL);
+ Inkscape::GC::release((Inkscape::XML::Node *) l->data);
+ l = g_slist_remove(l, l->data);
+ }
+
+ } else {
+ for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ child->updateRepr(flags);
+ }
+ }
+
+ if (((SPObjectClass *) (flowregion_parent_class))->write)
+ ((SPObjectClass *) (flowregion_parent_class))->write (object, repr, flags);
+
+ return repr;
+}
+
+
+static gchar *sp_flowregion_description(SPItem *item)
+{
+ // TRANSLATORS: "Flow region" is an area where text is allowed to flow
+ return g_strdup_printf(_("Flow region"));
+}
+
+/*
+ *
+ */
+
+GType
+sp_flowregionexclude_get_type (void)
+{
+ static GType group_type = 0;
+ if (!group_type) {
+ GTypeInfo group_info = {
+ sizeof (SPFlowregionExcludeClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) sp_flowregionexclude_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (SPFlowregionExclude),
+ 16, /* n_preallocs */
+ (GInstanceInitFunc) sp_flowregionexclude_init,
+ NULL, /* value_table */
+ };
+ group_type = g_type_register_static (SP_TYPE_ITEM, "SPFlowregionExclude", &group_info, (GTypeFlags)0);
+ }
+ return group_type;
+}
+
+static void
+sp_flowregionexclude_class_init (SPFlowregionExcludeClass *klass)
+{
+ GObjectClass * object_class;
+ SPObjectClass * sp_object_class;
+ SPItemClass * item_class;
+
+ object_class = (GObjectClass *) klass;
+ sp_object_class = (SPObjectClass *) klass;
+ item_class = (SPItemClass *) klass;
+
+ flowregionexclude_parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM);
+
+ object_class->dispose = sp_flowregionexclude_dispose;
+
+ sp_object_class->child_added = sp_flowregionexclude_child_added;
+ sp_object_class->remove_child = sp_flowregionexclude_remove_child;
+ sp_object_class->update = sp_flowregionexclude_update;
+ sp_object_class->modified = sp_flowregionexclude_modified;
+ sp_object_class->write = sp_flowregionexclude_write;
+
+ item_class->description = sp_flowregionexclude_description;
+}
+
+static void
+sp_flowregionexclude_init (SPFlowregionExclude *group)
+{
+ group->computed = NULL;
+}
+
+static void
+sp_flowregionexclude_dispose(GObject *object)
+{
+ SPFlowregionExclude *group=(SPFlowregionExclude *)object;
+ if (group->computed) {
+ delete group->computed;
+ group->computed = NULL;
+ }
+}
+
+static void
+sp_flowregionexclude_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
+{
+ SPItem *item;
+
+ item = SP_ITEM (object);
+
+ if (((SPObjectClass *) (flowregionexclude_parent_class))->child_added)
+ (* ((SPObjectClass *) (flowregionexclude_parent_class))->child_added) (object, child, ref);
+
+ object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+/* fixme: hide (Lauris) */
+
+static void
+sp_flowregionexclude_remove_child (SPObject * object, Inkscape::XML::Node * child)
+{
+ if (((SPObjectClass *) (flowregionexclude_parent_class))->remove_child)
+ (* ((SPObjectClass *) (flowregionexclude_parent_class))->remove_child) (object, child);
+
+ object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+}
+
+
+static void
+sp_flowregionexclude_update (SPObject *object, SPCtx *ctx, unsigned int flags)
+{
+ SPFlowregionExclude *group;
+ SPObject *child;
+ SPItemCtx *ictx, cctx;
+ GSList *l;
+
+ group = SP_FLOWREGIONEXCLUDE (object);
+ ictx = (SPItemCtx *) ctx;
+ cctx = *ictx;
+
+ if (((SPObjectClass *) (flowregionexclude_parent_class))->update)
+ ((SPObjectClass *) (flowregionexclude_parent_class))->update (object, ctx, flags);
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
+
+ l = NULL;
+ for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
+ g_object_ref (G_OBJECT (child));
+ l = g_slist_prepend (l, child);
+ }
+ l = g_slist_reverse (l);
+ while (l) {
+ child = SP_OBJECT (l->data);
+ l = g_slist_remove (l, child);
+ if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ if (SP_IS_ITEM (child)) {
+ SPItem const &chi = *SP_ITEM(child);
+ cctx.i2doc = chi.transform * ictx->i2doc;
+ cctx.i2vp = chi.transform * ictx->i2vp;
+ child->updateDisplay((SPCtx *)&cctx, flags);
+ } else {
+ child->updateDisplay(ctx, flags);
+ }
+ }
+ g_object_unref (G_OBJECT (child));
+ }
+
+ group->UpdateComputed();
+}
+void SPFlowregionExclude::UpdateComputed(void)
+{
+ SPObject* object=SP_OBJECT(this);
+
+ if (computed) {
+ delete computed;
+ computed = NULL;
+ }
+ NR::Matrix itr_mat=sp_item_i2root_affine (SP_ITEM(object));
+ itr_mat=itr_mat.inverse();
+
+ for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
+ GetDest(child,&computed,itr_mat);
+ }
+}
+
+static void
+sp_flowregionexclude_modified (SPObject *object, guint flags)
+{
+ SPFlowregionExclude *group;
+ SPObject *child;
+ GSList *l;
+
+ group = SP_FLOWREGIONEXCLUDE (object);
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
+
+ l = NULL;
+ for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
+ g_object_ref (G_OBJECT (child));
+ l = g_slist_prepend (l, child);
+ }
+ l = g_slist_reverse (l);
+ while (l) {
+ child = SP_OBJECT (l->data);
+ l = g_slist_remove (l, child);
+ if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ child->emitModified(flags);
+ }
+ g_object_unref (G_OBJECT (child));
+ }
+}
+
+static Inkscape::XML::Node *
+sp_flowregionexclude_write (SPObject *object, Inkscape::XML::Node *repr, guint flags)
+{
+ if (flags & SP_OBJECT_WRITE_BUILD) {
+ if ( repr == NULL ) repr = sp_repr_new ("svg:flowRegionExclude");
+
+ GSList *l = NULL;
+ for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ Inkscape::XML::Node *crepr = child->updateRepr(NULL, flags);
+ if (crepr) l = g_slist_prepend(l, crepr);
+ }
+
+ while (l) {
+ repr->addChild((Inkscape::XML::Node *) l->data, NULL);
+ Inkscape::GC::release((Inkscape::XML::Node *) l->data);
+ l = g_slist_remove(l, l->data);
+ }
+
+ } else {
+ for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ child->updateRepr(flags);
+ }
+ }
+
+ if (((SPObjectClass *) (flowregionexclude_parent_class))->write)
+ ((SPObjectClass *) (flowregionexclude_parent_class))->write (object, repr, flags);
+
+ return repr;
+}
+
+
+static gchar *sp_flowregionexclude_description(SPItem *item)
+{
+ /* TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the
+ * flow excluded region. flowRegionExclude in SVG 1.2: see
+ * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and
+ * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. */
+ return g_strdup_printf(_("Flow excluded region"));
+}
+
+/*
+ *
+ */
+
+static void UnionShape(Shape **base_shape, Shape const *add_shape)
+{
+ if (*base_shape == NULL)
+ *base_shape = new Shape;
+ if ( (*base_shape)->hasEdges() == false ) {
+ (*base_shape)->Copy(const_cast<Shape*>(add_shape));
+ } else if ( add_shape->hasEdges() ) {
+ Shape* temp=new Shape;
+ temp->Booleen(const_cast<Shape*>(add_shape), *base_shape, bool_op_union);
+ delete *base_shape;
+ *base_shape = temp;
+ }
+}
+
+static void GetDest(SPObject* child,Shape **computed,NR::Matrix itr_mat)
+{
+ if ( child == NULL ) return;
+
+ SPCurve *curve=NULL;
+
+ SPObject* u_child=child;
+ if ( SP_IS_USE(u_child) ) {
+ u_child=SP_USE(u_child)->child;
+ }
+ if ( SP_IS_SHAPE (u_child) ) {
+ curve = sp_shape_get_curve (SP_SHAPE (u_child));
+ } else if ( SP_IS_TEXT (u_child) ) {
+ curve = SP_TEXT (u_child)->getNormalizedBpath ();
+ }
+
+ if ( curve ) {
+ Path* temp=new Path;
+ NR::Matrix tr_mat=sp_item_i2root_affine (SP_ITEM(u_child));
+ tr_mat=itr_mat*tr_mat;
+ temp->LoadArtBPath(curve->bpath,tr_mat,true);
+ Shape* n_shp=new Shape;
+ temp->Convert(0.25);
+ temp->Fill(n_shp,0);
+ Shape* uncross=new Shape;
+ SPStyle* style=SP_OBJECT_STYLE(u_child);
+ if ( style && style->fill_rule.computed == SP_WIND_RULE_EVENODD ) {
+ uncross->ConvertToShape(n_shp,fill_oddEven);
+ } else {
+ uncross->ConvertToShape(n_shp,fill_nonZero);
+ }
+ UnionShape(computed, uncross);
+ delete uncross;
+ delete n_shp;
+ delete temp;
+ sp_curve_unref(curve);
+ } else {
+// printf("no curve\n");
+ }
+}
+