summaryrefslogtreecommitdiffstats
path: root/src/removeoverlap/removeoverlap.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/removeoverlap/removeoverlap.cpp
downloadinkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz
inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/removeoverlap/removeoverlap.cpp')
-rw-r--r--src/removeoverlap/removeoverlap.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/removeoverlap/removeoverlap.cpp b/src/removeoverlap/removeoverlap.cpp
new file mode 100644
index 000000000..9d7beb45f
--- /dev/null
+++ b/src/removeoverlap/removeoverlap.cpp
@@ -0,0 +1,80 @@
+/** \file
+ * Interface between Inkscape code (SPItem) and remove-overlaps function.
+ */
+/*
+* Authors:
+* Tim Dwyer <tgdwyer@gmail.com>
+*
+* Copyright (C) 2005 Authors
+*
+* Released under GNU GPL. Read the file 'COPYING' for more information.
+*/
+#include "util/glib-list-iterators.h"
+#include "sp-item.h"
+#include "sp-item-transform.h"
+#include "removeoverlap/generate-constraints.h"
+#include "removeoverlap/remove_rectangle_overlap.h"
+
+/**
+* Takes a list of inkscape items and moves them as little as possible
+* such that rectangular bounding boxes are separated by at least xGap
+* horizontally and yGap vertically
+*/
+void removeoverlap(GSList const *const items, double const xGap, double const yGap) {
+ if(!items) {
+ return;
+ }
+
+ using Inkscape::Util::GSListConstIterator;
+ std::list<SPItem *> selected;
+ selected.insert<GSListConstIterator<SPItem *> >(selected.end(), items, NULL);
+ if (selected.empty()) return;
+ int n=selected.size();
+
+ //Check 2 or more selected objects
+ if (n < 2) return;
+
+ Rectangle **rs = new Rectangle*[n];
+ int i=0;
+
+ NR::Point const gap(xGap, yGap);
+ for (std::list<SPItem *>::iterator it(selected.begin());
+ it != selected.end();
+ ++it)
+ {
+ using NR::X; using NR::Y;
+ NR::Rect const item_box(sp_item_bbox_desktop(*it));
+
+ /* The current algorithm requires widths & heights to be strictly positive. */
+ NR::Point min(item_box.min());
+ NR::Point max(item_box.max());
+ for (unsigned d = 0; d < 2; ++d) {
+ double const minsize = 1; // arbitrary positive number
+ if (max[d] - min[d] + gap[d] < minsize) {
+ double const mid = .5 * (min[d] + max[d]);
+ min[d] = mid - .5*minsize;
+ max[d] = mid + .5*minsize;
+ } else {
+ min[d] -= .5*gap[d];
+ max[d] += .5*gap[d];
+ }
+ }
+ rs[i++] = new Rectangle(min[X], max[X],
+ min[Y], max[Y]);
+ }
+ removeRectangleOverlap(rs, n, 0.0, 0.0);
+ i=0;
+ for (std::list<SPItem *>::iterator it(selected.begin());
+ it != selected.end();
+ ++it)
+ {
+ NR::Rect const item_box(sp_item_bbox_desktop(*it));
+ Rectangle *r = rs[i++];
+ NR::Point const curr(item_box.midpoint());
+ NR::Point const dest(r->getCentreX(),
+ r->getCentreY());
+ sp_item_move_rel(*it, NR::translate(dest - curr));
+ delete r;
+ }
+ delete [] rs;
+}