summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMenTaLguY <mental@rydia.net>2007-03-10 20:54:38 +0000
committermental <mental@users.sourceforge.net>2007-03-10 20:54:38 +0000
commita99764de718f7331615d3f9449e10a56dee62fb6 (patch)
treed60bc8389777a4384b8c931867a93c6491fffee5 /src
parentfix setting knot->pos for node handles, but remove coords updating - now done... (diff)
downloadinkscape-a99764de718f7331615d3f9449e10a56dee62fb6.tar.gz
inkscape-a99764de718f7331615d3f9449e10a56dee62fb6.zip
Merge further bbox work
(bzr r2596)
Diffstat (limited to 'src')
-rw-r--r--src/connector-context.cpp14
-rw-r--r--src/desktop.cpp14
-rw-r--r--src/dialogs/export.cpp34
-rw-r--r--src/document.cpp4
-rw-r--r--src/extension/internal/odf.cpp30
-rw-r--r--src/filter-chemistry.cpp13
-rw-r--r--src/gradient-drag.cpp18
-rw-r--r--src/graphlayout/graphlayout.cpp12
-rw-r--r--src/object-snapper.cpp4
-rw-r--r--src/removeoverlap/removeoverlap.cpp75
-rw-r--r--src/selcue.cpp58
-rw-r--r--src/selection-chemistry.cpp52
-rw-r--r--src/selection.cpp8
-rw-r--r--src/sp-item-transform.cpp11
-rw-r--r--src/sp-item.cpp10
-rw-r--r--src/sp-item.h2
-rw-r--r--src/sp-offset.cpp6
-rw-r--r--src/text-context.cpp10
-rw-r--r--src/ui/dialog/align-and-distribute.cpp90
-rw-r--r--src/ui/dialog/transformation.cpp24
-rw-r--r--src/ui/view/edit-widget.cpp10
-rw-r--r--src/widgets/desktop-widget.cpp8
22 files changed, 273 insertions, 234 deletions
diff --git a/src/connector-context.cpp b/src/connector-context.cpp
index 367917915..89d38bace 100644
--- a/src/connector-context.cpp
+++ b/src/connector-context.cpp
@@ -1145,12 +1145,14 @@ static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item)
}
- NR::Rect bbox = sp_item_bbox_desktop(cc->active_shape);
- NR::Point center = bbox.midpoint();
- sp_knot_set_position(cc->connpthandle, &center, 0);
-
- sp_knot_show(cc->connpthandle);
-
+ NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop(cc->active_shape);
+ if (bbox) {
+ NR::Point center = bbox->midpoint();
+ sp_knot_set_position(cc->connpthandle, &center, 0);
+ sp_knot_show(cc->connpthandle);
+ } else {
+ sp_knot_hide(cc->connpthandle);
+ }
}
diff --git a/src/desktop.cpp b/src/desktop.cpp
index e1cc23083..471ac2a19 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -430,8 +430,12 @@ bool SPDesktop::isLayer(SPObject *object) const {
bool SPDesktop::isWithinViewport (SPItem *item) const
{
NR::Rect const viewport = get_display_area();
- NR::Rect const bbox = sp_item_bbox_desktop(item);
- return viewport.contains(bbox);
+ NR::Maybe<NR::Rect> const bbox = sp_item_bbox_desktop(item);
+ if (bbox) {
+ return viewport.contains(*bbox);
+ } else {
+ return true;
+ }
}
///
@@ -881,16 +885,16 @@ SPDesktop::zoom_drawing()
SPItem *docitem = SP_ITEM (sp_document_root (doc()));
g_return_if_fail (docitem != NULL);
- NR::Rect d = sp_item_bbox_desktop(docitem);
+ NR::Maybe<NR::Rect> d = sp_item_bbox_desktop(docitem);
/* Note that the second condition here indicates that
** there are no items in the drawing.
*/
- if ( d.dimensions()[NR::X] < 1.0 || d.dimensions()[NR::Y] < 1.0 ) {
+ if ( !d || d->dimensions()[NR::X] < 1.0 || d->dimensions()[NR::Y] < 1.0 ) {
return;
}
- set_display_area(d, 10);
+ set_display_area(*d, 10);
}
/**
diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp
index 8c06f83cd..4dfdbbb5e 100644
--- a/src/dialogs/export.cpp
+++ b/src/dialogs/export.cpp
@@ -776,14 +776,12 @@ sp_export_selection_modified ( Inkscape::Application *inkscape,
if ( SP_ACTIVE_DESKTOP ) {
SPDocument *doc;
doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
- NR::Rect bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
-
- if (!(bbox.min()[NR::X] > bbox.max()[NR::X] &&
- bbox.min()[NR::Y] > bbox.max()[NR::Y])) {
- sp_export_set_area (base, bbox.min()[NR::X],
- bbox.min()[NR::Y],
- bbox.max()[NR::X],
- bbox.max()[NR::Y]);
+ NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
+ if (bbox) {
+ sp_export_set_area (base, bbox->min()[NR::X],
+ bbox->min()[NR::Y],
+ bbox->max()[NR::X],
+ bbox->max()[NR::Y]);
}
}
break;
@@ -837,7 +835,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
if ( SP_ACTIVE_DESKTOP )
{
SPDocument *doc;
- NR::Rect bbox;
+ NR::Maybe<NR::Rect> bbox;
doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
/* Notice how the switch is used to 'fall through' here to get
@@ -860,11 +858,9 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
* This returns wrong values if the document has a viewBox.
*/
bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
-
/* If the drawing is valid, then we'll use it and break
otherwise we drop through to the page settings */
- if (!(bbox.min()[NR::X] > bbox.max()[NR::X] &&
- bbox.min()[NR::Y] > bbox.max()[NR::Y])) {
+ if (bbox) {
// std::cout << "Using selection: DRAWING" << std::endl;
key = SELECTION_DRAWING;
break;
@@ -886,11 +882,11 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
prefs_set_string_attribute ( "dialogs.export.exportarea",
"value", selection_names[key]);
- if (key != SELECTION_CUSTOM) {
- sp_export_set_area (base, bbox.min()[NR::X],
- bbox.min()[NR::Y],
- bbox.max()[NR::X],
- bbox.max()[NR::Y]);
+ if ( key != SELECTION_CUSTOM && bbox ) {
+ sp_export_set_area (base, bbox->min()[NR::X],
+ bbox->min()[NR::Y],
+ bbox->max()[NR::X],
+ bbox->max()[NR::Y]);
}
} // end of if ( SP_ACTIVE_DESKTOP )
@@ -1417,10 +1413,10 @@ sp_export_detect_size(GtkObject * base) {
case SELECTION_DRAWING: {
SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
- NR::Rect bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
+ NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
// std::cout << "Drawing " << bbox2;
- if (sp_export_bbox_equal(bbox,current_bbox)) {
+ if ( bbox && sp_export_bbox_equal(*bbox,current_bbox) ) {
key = SELECTION_DRAWING;
}
break;
diff --git a/src/document.cpp b/src/document.cpp
index ab6003167..715bc2ec7 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -837,8 +837,8 @@ static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey,
s = find_items_in_area(s, SP_GROUP(o), dkey, area, test);
} else {
SPItem *child = SP_ITEM(o);
- NR::Rect box = sp_item_bbox_desktop(child);
- if (test(area, box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
+ NR::Maybe<NR::Rect> box = sp_item_bbox_desktop(child);
+ if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
s = g_slist_append(s, child);
}
}
diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp
index 48e217bd8..8645205f2 100644
--- a/src/extension/internal/odf.cpp
+++ b/src/extension/internal/odf.cpp
@@ -958,14 +958,16 @@ static NR::Matrix getODFTransform(const SPItem *item)
* Get the bounding box of an item, as mapped onto
* an ODF document, in cm.
*/
-static NR::Rect getODFBoundingBox(const SPItem *item)
+static NR::Maybe<NR::Rect> getODFBoundingBox(const SPItem *item)
{
- NR::Rect bbox = sp_item_bbox_desktop((SPItem *)item);
- double doc_height = sp_document_height(SP_ACTIVE_DOCUMENT);
- NR::Matrix doc2dt_tf = NR::Matrix(NR::scale(1.0, -1.0));
- doc2dt_tf = doc2dt_tf * NR::Matrix(NR::translate(0, doc_height));
- bbox = bbox * doc2dt_tf;
- bbox = bbox * NR::Matrix(NR::scale(pxToCm));
+ NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop((SPItem *)item);
+ if (bbox) {
+ double doc_height = sp_document_height(SP_ACTIVE_DOCUMENT);
+ NR::Matrix doc2dt_tf = NR::Matrix(NR::scale(1.0, -1.0));
+ doc2dt_tf = doc2dt_tf * NR::Matrix(NR::translate(0, doc_height));
+ bbox = *bbox * doc2dt_tf;
+ bbox = *bbox * NR::Matrix(NR::scale(pxToCm));
+ }
return bbox;
}
@@ -1866,11 +1868,15 @@ bool OdfOutput::writeTree(Writer &couts, Writer &souts,
NR::Matrix tf = getODFTransform(item);
//### Get ODF bounding box params for item
- NR::Rect bbox = getODFBoundingBox(item);
- double bbox_x = bbox.min()[NR::X];
- double bbox_y = bbox.min()[NR::Y];
- double bbox_width = bbox.max()[NR::X] - bbox.min()[NR::X];
- double bbox_height = bbox.max()[NR::Y] - bbox.min()[NR::Y];
+ NR::Maybe<NR::Rect> bbox = getODFBoundingBox(item);
+ if (!bbox) {
+ return true;
+ }
+
+ double bbox_x = bbox->min()[NR::X];
+ double bbox_y = bbox->min()[NR::Y];
+ double bbox_width = bbox->extent(NR::X);
+ double bbox_height = bbox->extent(NR::Y);
double rotate;
double xskew;
diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp
index 1a26b10ce..164a6594a 100644
--- a/src/filter-chemistry.cpp
+++ b/src/filter-chemistry.cpp
@@ -96,9 +96,16 @@ new_filter_gaussian_blur (SPDocument *document, gdouble radius, double expansion
SPFilter *
new_filter_gaussian_blur_from_item (SPDocument *document, SPItem *item, gdouble radius)
{
- NR::Rect const r = sp_item_bbox_desktop(item);
- double width = r.extent(NR::X);
- double height = r.extent(NR::Y);
+ NR::Maybe<NR::Rect> const r = sp_item_bbox_desktop(item);
+
+ double width;
+ double height;
+ if (r) {
+ width = r->extent(NR::X);
+ height= r->extent(NR::Y);
+ } else {
+ width = height = 0;
+ }
NR::Matrix i2d = sp_item_i2d_affine (item);
diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp
index c02190df8..4a8f7e8ed 100644
--- a/src/gradient-drag.cpp
+++ b/src/gradient-drag.cpp
@@ -1443,14 +1443,16 @@ GrDrag::updateLevels ()
for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) {
SPItem *item = SP_ITEM(i->data);
- NR::Rect rect = sp_item_bbox_desktop (item);
- // Remember the edges of the bbox and the center axis
- hor_levels.push_back(rect.min()[NR::Y]);
- hor_levels.push_back(rect.max()[NR::Y]);
- hor_levels.push_back(0.5 * (rect.min()[NR::Y] + rect.max()[NR::Y]));
- vert_levels.push_back(rect.min()[NR::X]);
- vert_levels.push_back(rect.max()[NR::X]);
- vert_levels.push_back(0.5 * (rect.min()[NR::X] + rect.max()[NR::X]));
+ NR::Maybe<NR::Rect> rect = sp_item_bbox_desktop (item);
+ if (rect) {
+ // Remember the edges of the bbox and the center axis
+ hor_levels.push_back(rect->min()[NR::Y]);
+ hor_levels.push_back(rect->max()[NR::Y]);
+ hor_levels.push_back(0.5 * (rect->min()[NR::Y] + rect->max()[NR::Y]));
+ vert_levels.push_back(rect->min()[NR::X]);
+ vert_levels.push_back(rect->max()[NR::X]);
+ vert_levels.push_back(0.5 * (rect->min()[NR::X] + rect->max()[NR::X]));
+ }
}
}
diff --git a/src/graphlayout/graphlayout.cpp b/src/graphlayout/graphlayout.cpp
index 30085a00f..780532718 100644
--- a/src/graphlayout/graphlayout.cpp
+++ b/src/graphlayout/graphlayout.cpp
@@ -93,9 +93,10 @@ void graphlayout(GSList const *const items) {
++i)
{
SPItem *u=*i;
- NR::Rect const item_box(sp_item_bbox_desktop(u));
- NR::Point ll(item_box.min());
- NR::Point ur(item_box.max());
+ NR::Maybe<NR::Rect> const item_box(sp_item_bbox_desktop(u));
+ g_assert(item_box);
+ NR::Point ll(item_box->min());
+ NR::Point ur(item_box->max());
nodelookup[u->id]=rs.size();
rs.push_back(new Rectangle(ll[0]-spacing,ur[0]+spacing,
ll[1]-spacing,ur[1]+spacing));
@@ -188,8 +189,9 @@ void graphlayout(GSList const *const items) {
SPItem *u=*it;
if(!isConnector(u)) {
Rectangle* r=rs[nodelookup[u->id]];
- NR::Rect const item_box(sp_item_bbox_desktop(u));
- NR::Point const curr(item_box.midpoint());
+ NR::Maybe<NR::Rect> item_box(sp_item_bbox_desktop(u));
+ g_assert(item_box);
+ NR::Point const curr(item_box->midpoint());
NR::Point const dest(r->getCentreX(),r->getCentreY());
sp_item_move_rel(u, NR::translate(dest - curr));
}
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 684700b3b..5492fc439 100644
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -53,8 +53,8 @@ void Inkscape::ObjectSnapper::_findCandidates(std::list<SPItem*>& c,
if (SP_IS_GROUP(o)) {
_findCandidates(c, o, it, p);
} else {
- NR::Rect const b = NR::expand(sp_item_bbox_desktop(SP_ITEM(o)), -getDistance());
- if (b.contains(p)) {
+ NR::Maybe<NR::Rect> b = sp_item_bbox_desktop(SP_ITEM(o));
+ if ( b && NR::expand(*b, -getDistance()).contains(p) ) {
c.push_back(SP_ITEM(o));
}
}
diff --git a/src/removeoverlap/removeoverlap.cpp b/src/removeoverlap/removeoverlap.cpp
index c640fb407..395d4fe0e 100644
--- a/src/removeoverlap/removeoverlap.cpp
+++ b/src/removeoverlap/removeoverlap.cpp
@@ -14,30 +14,33 @@
#include "sp-item-transform.h"
#include "libvpsc/generate-constraints.h"
#include "libvpsc/remove_rectangle_overlap.h"
+#include <utility>
using vpsc::Rectangle;
+namespace {
+ struct Record {
+ SPItem *item;
+ NR::Point midpoint;
+ Rectangle *vspc_rect;
+
+ Record() {}
+ Record(SPItem *i, NR::Point m, Rectangle *r)
+ : item(i), midpoint(m), vspc_rect(r) {}
+ };
+}
+
/**
* 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;
+ std::vector<Record> records;
+ std::vector<Rectangle *> rs;
NR::Point const gap(xGap, yGap);
for (std::list<SPItem *>::iterator it(selected.begin());
@@ -45,38 +48,26 @@ void removeoverlap(GSList const *const items, double const xGap, double const yG
++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];
- }
+ NR::Maybe<NR::Rect> item_box(sp_item_bbox_desktop(*it));
+ if (item_box) {
+ NR::Point min(item_box->min() - .5*gap);
+ NR::Point max(item_box->max() + .5*gap);
+ Rectangle *vspc_rect = new Rectangle(min[X], max[X], min[Y], max[Y]);
+ records.push_back(Record(*it, item_box->midpoint(), vspc_rect));
+ rs.push_back(vspc_rect);
}
- rs[i++] = new Rectangle(min[X], max[X],
- min[Y], max[Y]);
}
- removeRectangleOverlap(n, rs, 0.0, 0.0);
- i=0;
- for (std::list<SPItem *>::iterator it(selected.begin());
- it != selected.end();
- ++it)
+ if (!rs.empty()) {
+ removeRectangleOverlap(rs.size(), &rs[0], 0.0, 0.0);
+ }
+ for ( std::vector<Record>::iterator it = records.begin();
+ it != records.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;
+ NR::Point const curr = it->midpoint;
+ NR::Point const dest(it->vspc_rect->getCentreX(),
+ it->vspc_rect->getCentreY());
+ sp_item_move_rel(it->item, NR::translate(dest - curr));
+ delete it->vspc_rect;
}
- delete [] rs;
}
diff --git a/src/selcue.cpp b/src/selcue.cpp
index 6d3656592..a073f3493 100644
--- a/src/selcue.cpp
+++ b/src/selcue.cpp
@@ -78,38 +78,38 @@ void Inkscape::SelCue::_updateItemBboxes()
for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
SPItem *item = (SPItem *) l->data;
- NR::Rect const b = sp_item_bbox_desktop(item);
+ NR::Maybe<NR::Rect> const b = sp_item_bbox_desktop(item);
SPCanvasItem* box = NULL;
- if (mode == MARK) {
- box = sp_canvas_item_new(sp_desktop_controls(_desktop),
- SP_TYPE_CTRL,
- "mode", SP_CTRL_MODE_XOR,
- "shape", SP_CTRL_SHAPE_DIAMOND,
- "size", 5.0,
- "filled", TRUE,
- "fill_color", 0x000000ff,
- "stroked", FALSE,
- "stroke_color", 0x000000ff,
- NULL);
- sp_canvas_item_show(box);
- SP_CTRL(box)->moveto(NR::Point(b.min()[NR::X], b.max()[NR::Y]));
-
- sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
-
- } else if (mode == BBOX) {
- box = sp_canvas_item_new(
- sp_desktop_controls(_desktop),
- SP_TYPE_CTRLRECT,
- NULL
- );
-
- SP_CTRLRECT(box)->setRectangle(b);
- SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
- SP_CTRLRECT(box)->setDashed(true);
-
- sp_canvas_item_move_to_z(box, 0);
+ if (b) {
+ if (mode == MARK) {
+ box = sp_canvas_item_new(sp_desktop_controls(_desktop),
+ SP_TYPE_CTRL,
+ "mode", SP_CTRL_MODE_XOR,
+ "shape", SP_CTRL_SHAPE_DIAMOND,
+ "size", 5.0,
+ "filled", TRUE,
+ "fill_color", 0x000000ff,
+ "stroked", FALSE,
+ "stroke_color", 0x000000ff,
+ NULL);
+ sp_canvas_item_show(box);
+ SP_CTRL(box)->moveto(NR::Point(b->min()[NR::X], b->max()[NR::Y]));
+
+ sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots
+
+ } else if (mode == BBOX) {
+ box = sp_canvas_item_new(sp_desktop_controls(_desktop),
+ SP_TYPE_CTRLRECT,
+ NULL);
+
+ SP_CTRLRECT(box)->setRectangle(*b);
+ SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0);
+ SP_CTRLRECT(box)->setDashed(true);
+
+ sp_canvas_item_move_to_z(box, 0);
+ }
}
if (box) {
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index a65c9b290..171928865 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -654,13 +654,16 @@ sp_selection_raise()
// for each selected object, find the next sibling
for (SPObject *newref = child->next; newref; newref = newref->next) {
// if the sibling is an item AND overlaps our selection,
- if (SP_IS_ITEM(newref) && selected->intersects(sp_item_bbox_desktop(SP_ITEM(newref)))) {
- // AND if it's not one of our selected objects,
- if (!g_slist_find((GSList *) items, newref)) {
- // move the selected object after that sibling
- grepr->changeOrder(SP_OBJECT_REPR(child), SP_OBJECT_REPR(newref));
+ if (SP_IS_ITEM(newref)) {
+ NR::Maybe<NR::Rect> newref_bbox = sp_item_bbox_desktop(SP_ITEM(newref));
+ if ( newref_bbox && selected->intersects(*newref_bbox) ) {
+ // AND if it's not one of our selected objects,
+ if (!g_slist_find((GSList *) items, newref)) {
+ // move the selected object after that sibling
+ grepr->changeOrder(SP_OBJECT_REPR(child), SP_OBJECT_REPR(newref));
+ }
+ break;
}
- break;
}
}
rev = g_slist_remove(rev, child);
@@ -747,17 +750,20 @@ sp_selection_lower()
// for each selected object, find the prev sibling
for (SPObject *newref = prev_sibling(child); newref; newref = prev_sibling(newref)) {
// if the sibling is an item AND overlaps our selection,
- if (SP_IS_ITEM(newref) && selected->intersects(sp_item_bbox_desktop(SP_ITEM(newref)))) {
- // AND if it's not one of our selected objects,
- if (!g_slist_find((GSList *) items, newref)) {
- // move the selected object before that sibling
- SPObject *put_after = prev_sibling(newref);
- if (put_after)
- grepr->changeOrder(SP_OBJECT_REPR(child), SP_OBJECT_REPR(put_after));
- else
- SP_OBJECT_REPR(child)->setPosition(0);
+ if (SP_IS_ITEM(newref)) {
+ NR::Maybe<NR::Rect> ref_bbox = sp_item_bbox_desktop(SP_ITEM(newref));
+ if ( ref_bbox && selected->intersects(*ref_bbox) ) {
+ // AND if it's not one of our selected objects,
+ if (!g_slist_find((GSList *) items, newref)) {
+ // move the selected object before that sibling
+ SPObject *put_after = prev_sibling(newref);
+ if (put_after)
+ grepr->changeOrder(SP_OBJECT_REPR(child), SP_OBJECT_REPR(put_after));
+ else
+ SP_OBJECT_REPR(child)->setPosition(0);
+ }
+ break;
}
- break;
}
}
rev = g_slist_remove(rev, child);
@@ -1223,13 +1229,13 @@ void sp_selection_paste_size_separately (bool apply_x, bool apply_y)
for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
SPItem *item = SP_ITEM(l->data);
- NR::Rect current = sp_item_bbox_desktop(item);
- if (current.extent(NR::X) < 1e-6 || current.extent(NR::Y) < 1e-6) {
+ NR::Maybe<NR::Rect> current = sp_item_bbox_desktop(item);
+ if ( !current || current->extent(NR::X) < 1e-6 || current->extent(NR::Y) < 1e-6 ) {
continue;
}
- double scale_x = size_clipboard.extent(NR::X) / current.extent(NR::X);
- double scale_y = size_clipboard.extent(NR::Y) / current.extent(NR::Y);
+ double scale_x = size_clipboard.extent(NR::X) / current->extent(NR::X);
+ double scale_y = size_clipboard.extent(NR::Y) / current->extent(NR::Y);
sp_item_scale_rel (item,
NR::scale(
@@ -1985,10 +1991,10 @@ SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root,
void scroll_to_show_item(SPDesktop *desktop, SPItem *item)
{
NR::Rect dbox = desktop->get_display_area();
- NR::Rect sbox = sp_item_bbox_desktop(item);
+ NR::Maybe<NR::Rect> sbox = sp_item_bbox_desktop(item);
- if (dbox.contains(sbox) == false) {
- NR::Point const s_dt = sbox.midpoint();
+ if ( sbox && dbox.contains(*sbox) == false ) {
+ NR::Point const s_dt = sbox->midpoint();
NR::Point const s_w = desktop->d2w(s_dt);
NR::Point const d_dt = dbox.midpoint();
NR::Point const d_w = desktop->d2w(d_dt);
diff --git a/src/selection.cpp b/src/selection.cpp
index 49934cfd3..d39086e8c 100644
--- a/src/selection.cpp
+++ b/src/selection.cpp
@@ -421,9 +421,11 @@ std::vector<NR::Point> Selection::getBBoxPoints() const {
GSList const *items = const_cast<Selection *>(this)->itemList();
std::vector<NR::Point> p;
for (GSList const *iter = items; iter != NULL; iter = iter->next) {
- NR::Rect b = sp_item_bbox_desktop(SP_ITEM(iter->data));
- p.push_back(b.min());
- p.push_back(b.max());
+ NR::Maybe<NR::Rect> b = sp_item_bbox_desktop(SP_ITEM(iter->data));
+ if (b) {
+ p.push_back(b->min());
+ p.push_back(b->max());
+ }
}
return p;
diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp
index d62211245..105a91b4c 100644
--- a/src/sp-item-transform.cpp
+++ b/src/sp-item-transform.cpp
@@ -46,11 +46,12 @@ sp_item_rotate_rel(SPItem *item, NR::rotate const &rotation)
void
sp_item_scale_rel (SPItem *item, NR::scale const &scale)
{
- NR::translate const s(sp_item_bbox_desktop(item).midpoint()); // use getCenter?
-
- sp_item_set_i2d_affine(item,
- sp_item_i2d_affine(item) * inverse(s) * scale * s);
- sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
+ NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop(item);
+ if (bbox) {
+ NR::translate const s(bbox->midpoint()); // use getCenter?
+ sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * inverse(s) * scale * s);
+ sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
+ }
}
void
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 0f6ea3839..eb3abce16 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -798,17 +798,11 @@ sp_item_bbox_desktop(SPItem *item, NRRect *bbox)
sp_item_invoke_bbox(item, bbox, sp_item_i2d_affine(item), TRUE);
}
-NR::Rect sp_item_bbox_desktop(SPItem *item)
+NR::Maybe<NR::Rect> sp_item_bbox_desktop(SPItem *item)
{
NRRect ret;
sp_item_invoke_bbox(item, &ret, sp_item_i2d_affine(item), TRUE);
- NR::Maybe<NR::Rect> result = ret.upgrade();
- if (result) {
- return *result;
- } else {
- // FIXME
- return NR::Rect(NR::Point(0, 0), NR::Point(0, 0));
- }
+ return ret.upgrade();
}
static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p)
diff --git a/src/sp-item.h b/src/sp-item.h
index 3b5e64b11..eb7043096 100644
--- a/src/sp-item.h
+++ b/src/sp-item.h
@@ -240,7 +240,7 @@ gint sp_item_event (SPItem *item, SPEvent *event);
NRArenaItem *sp_item_get_arenaitem(SPItem *item, unsigned int key);
void sp_item_bbox_desktop(SPItem *item, NRRect *bbox) __attribute__ ((deprecated));
-NR::Rect sp_item_bbox_desktop(SPItem *item);
+NR::Maybe<NR::Rect> sp_item_bbox_desktop(SPItem *item);
NR::Matrix i2anc_affine(SPObject const *item, SPObject const *ancestor);
NR::Matrix i2i_affine(SPObject const *src, SPObject const *dest);
diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp
index 74382b768..e682f394b 100644
--- a/src/sp-offset.cpp
+++ b/src/sp-offset.cpp
@@ -584,9 +584,9 @@ sp_offset_set_shape(SPShape *shape)
theRes->ConvertToForme (orig, 1, originaux);
SPItem *item = shape;
- NR::Rect bbox = sp_item_bbox_desktop (item);
- if (!bbox.isEmpty()) {
- gdouble size = L2(bbox.dimensions());
+ NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop (item);
+ if ( bbox && !bbox->isEmpty() ) {
+ gdouble size = L2(bbox->dimensions());
gdouble const exp = NR::expansion(item->transform);
if (exp != 0)
size /= exp;
diff --git a/src/text-context.cpp b/src/text-context.cpp
index b65bcf19f..6a527e544 100644
--- a/src/text-context.cpp
+++ b/src/text-context.cpp
@@ -436,7 +436,10 @@ sp_text_context_item_handler(SPEventContext *ec, SPItem *item, GdkEvent *event)
item_ungrouped = desktop->item_at_point(NR::Point(event->button.x, event->button.y), TRUE);
if (SP_IS_TEXT(item_ungrouped) || SP_IS_FLOWTEXT(item_ungrouped)) {
sp_canvas_item_show(tc->indicator);
- SP_CTRLRECT(tc->indicator)->setRectangle(sp_item_bbox_desktop(item_ungrouped));
+ NR::Maybe<NR::Rect> ibbox = sp_item_bbox_desktop(item_ungrouped);
+ if (ibbox) {
+ SP_CTRLRECT(tc->indicator)->setRectangle(*ibbox);
+ }
ec->cursor_shape = cursor_text_insert_xpm;
ec->hot_x = 7;
@@ -1458,7 +1461,10 @@ sp_text_context_update_cursor(SPTextContext *tc, bool scroll_to_see)
SPItem *frame = SP_FLOWTEXT(tc->text)->get_frame (NULL); // first frame only
if (frame) {
sp_canvas_item_show(tc->frame);
- SP_CTRLRECT(tc->frame)->setRectangle(sp_item_bbox_desktop(frame));
+ NR::Maybe<NR::Rect> frame_bbox = sp_item_bbox_desktop(frame);
+ if (frame_bbox) {
+ SP_CTRLRECT(tc->frame)->setRectangle(*frame_bbox);
+ }
}
SP_EVENT_CONTEXT(tc)->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Type flowed text; <b>Enter</b> to start new paragraph."));
} else {
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index b8f840520..c1f4a10a1 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -153,9 +153,13 @@ private :
SPItem * thing = *master;
selected.erase(master);
//Compute the anchor point
- NR::Rect b = sp_item_bbox_desktop (thing);
- mp = NR::Point(a.mx0 * b.min()[NR::X] + a.mx1 * b.max()[NR::X],
- a.my0 * b.min()[NR::Y] + a.my1 * b.max()[NR::Y]);
+ NR::Maybe<NR::Rect> b = sp_item_bbox_desktop (thing);
+ if (b) {
+ mp = NR::Point(a.mx0 * b->min()[NR::X] + a.mx1 * b->max()[NR::X],
+ a.my0 * b->min()[NR::Y] + a.my1 * b->max()[NR::Y]);
+ } else {
+ return;
+ }
break;
}
@@ -166,10 +170,14 @@ private :
case AlignAndDistribute::DRAWING:
{
- NR::Rect b = sp_item_bbox_desktop
+ NR::Maybe<NR::Rect> b = sp_item_bbox_desktop
( (SPItem *) sp_document_root (sp_desktop_document (desktop)) );
- mp = NR::Point(a.mx0 * b.min()[NR::X] + a.mx1 * b.max()[NR::X],
- a.my0 * b.min()[NR::Y] + a.my1 * b.max()[NR::Y]);
+ if (b) {
+ mp = NR::Point(a.mx0 * b->min()[NR::X] + a.mx1 * b->max()[NR::X],
+ a.my0 * b->min()[NR::Y] + a.my1 * b->max()[NR::Y]);
+ } else {
+ return;
+ }
break;
}
@@ -202,13 +210,15 @@ private :
it++)
{
sp_document_ensure_up_to_date(sp_desktop_document (desktop));
- NR::Rect b = sp_item_bbox_desktop (*it);
- NR::Point const sp(a.sx0 * b.min()[NR::X] + a.sx1 * b.max()[NR::X],
- a.sy0 * b.min()[NR::Y] + a.sy1 * b.max()[NR::Y]);
- NR::Point const mp_rel( mp - sp );
- if (LInfty(mp_rel) > 1e-9) {
- sp_item_move_rel(*it, NR::translate(mp_rel));
- changed = true;
+ NR::Maybe<NR::Rect> b = sp_item_bbox_desktop (*it);
+ if (b) {
+ NR::Point const sp(a.sx0 * b->min()[NR::X] + a.sx1 * b->max()[NR::X],
+ a.sy0 * b->min()[NR::Y] + a.sy1 * b->max()[NR::Y]);
+ NR::Point const mp_rel( mp - sp );
+ if (LInfty(mp_rel) > 1e-9) {
+ sp_item_move_rel(*it, NR::translate(mp_rel));
+ changed = true;
+ }
}
}
@@ -246,9 +256,9 @@ struct BBoxSort
SPItem *item;
float anchor;
NR::Rect bbox;
- BBoxSort(SPItem *pItem, NR::Dim2 orientation, double kBegin, double kEnd) :
+ BBoxSort(SPItem *pItem, NR::Rect bounds, NR::Dim2 orientation, double kBegin, double kEnd) :
item(pItem),
- bbox (sp_item_bbox_desktop (pItem))
+ bbox (bounds)
{
anchor = kBegin * bbox.min()[orientation] + kEnd * bbox.max()[orientation];
}
@@ -308,8 +318,10 @@ private :
it != selected.end();
++it)
{
- BBoxSort b (*it, _orientation, _kBegin, _kEnd);
- sorted.push_back(b);
+ NR::Maybe<NR::Rect> bbox = sp_item_bbox_desktop(*it);
+ if (bbox) {
+ sorted.push_back(BBoxSort(*it, *bbox, _orientation, _kBegin, _kEnd));
+ }
}
//sort bbox by anchors
std::sort(sorted.begin(), sorted.end());
@@ -595,15 +607,17 @@ private :
++it)
{
sp_document_ensure_up_to_date(sp_desktop_document (desktop));
- NR::Rect item_box = sp_item_bbox_desktop (*it);
- // find new center, staying within bbox
- double x = _dialog.randomize_bbox.min()[NR::X] + item_box.extent(NR::X)/2 +
- g_random_double_range (0, _dialog.randomize_bbox.extent(NR::X) - item_box.extent(NR::X));
- double y = _dialog.randomize_bbox.min()[NR::Y] + item_box.extent(NR::Y)/2 +
- g_random_double_range (0, _dialog.randomize_bbox.extent(NR::Y) - item_box.extent(NR::Y));
- // displacement is the new center minus old:
- NR::Point t = NR::Point (x, y) - 0.5*(item_box.max() + item_box.min());
- sp_item_move_rel(*it, NR::translate(t));
+ NR::Maybe<NR::Rect> item_box = sp_item_bbox_desktop (*it);
+ if (item_box) {
+ // find new center, staying within bbox
+ double x = _dialog.randomize_bbox.min()[NR::X] + item_box->extent(NR::X)/2 +
+ g_random_double_range (0, _dialog.randomize_bbox.extent(NR::X) - item_box->extent(NR::X));
+ double y = _dialog.randomize_bbox.min()[NR::Y] + item_box->extent(NR::Y)/2 +
+ g_random_double_range (0, _dialog.randomize_bbox.extent(NR::Y) - item_box->extent(NR::Y));
+ // displacement is the new center minus old:
+ NR::Point t = NR::Point (x, y) - 0.5*(item_box->max() + item_box->min());
+ sp_item_move_rel(*it, NR::translate(t));
+ }
}
// restore compensation setting
@@ -1054,11 +1068,13 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
{
gdouble max = -1e18;
for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) {
- NR::Rect b = sp_item_bbox_desktop (*it);
- gdouble dim = b.extent(horizontal ? NR::X : NR::Y);
- if (dim > max) {
- max = dim;
- master = it;
+ NR::Maybe<NR::Rect> b = sp_item_bbox_desktop (*it);
+ if (b) {
+ gdouble dim = b->extent(horizontal ? NR::X : NR::Y);
+ if (dim > max) {
+ max = dim;
+ master = it;
+ }
}
}
return master;
@@ -1069,11 +1085,13 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
{
gdouble max = 1e18;
for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) {
- NR::Rect b = sp_item_bbox_desktop (*it);
- gdouble dim = b.extent(horizontal ? NR::X : NR::Y);
- if (dim < max) {
- max = dim;
- master = it;
+ NR::Maybe<NR::Rect> b = sp_item_bbox_desktop (*it);
+ if (b) {
+ gdouble dim = b->extent(horizontal ? NR::X : NR::Y);
+ if (dim < max) {
+ max = dim;
+ master = it;
+ }
}
}
return master;
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index 99ac56cbd..90cac7425 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -604,15 +604,17 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
if (prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1) == 1) {
for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
SPItem *item = SP_ITEM(l->data);
- NR::Rect bbox (sp_item_bbox_desktop(item));
NR::scale scale (0,0);
// the values are increments!
if (_units_scale.isAbsolute()) {
- double new_width = bbox.extent(NR::X) + scaleX;
- if (new_width < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object
- double new_height = bbox.extent(NR::Y) + scaleY;
- if (new_height < 1e-6) new_height = 1e-6;
- scale = NR::scale(new_width / bbox.extent(NR::X), new_height / bbox.extent(NR::Y));
+ NR::Maybe<NR::Rect> bbox(sp_item_bbox_desktop(item));
+ if (bbox) {
+ double new_width = bbox->extent(NR::X) + scaleX;
+ if (new_width < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object
+ double new_height = bbox->extent(NR::Y) + scaleY;
+ if (new_height < 1e-6) new_height = 1e-6;
+ scale = NR::scale(new_width / bbox->extent(NR::X), new_height / bbox->extent(NR::Y));
+ }
} else {
double new_width = 100 + scaleX;
if (new_width < 1e-6) new_width = 1e-6;
@@ -686,10 +688,12 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
} else { // absolute displacement
double skewX = _scalar_skew_horizontal.getValue("px");
double skewY = _scalar_skew_vertical.getValue("px");
- NR::Rect bbox(sp_item_bbox_desktop(item));
- double width = bbox.dimensions()[NR::X];
- double height = bbox.dimensions()[NR::Y];
- sp_item_skew_rel (item, skewX/height, skewY/width);
+ NR::Maybe<NR::Rect> bbox(sp_item_bbox_desktop(item));
+ if (bbox) {
+ double width = bbox->dimensions()[NR::X];
+ double height = bbox->dimensions()[NR::Y];
+ sp_item_skew_rel (item, skewX/height, skewY/width);
+ }
}
}
} else { // transform whole selection
diff --git a/src/ui/view/edit-widget.cpp b/src/ui/view/edit-widget.cpp
index f386aefcc..99fd2fb80 100644
--- a/src/ui/view/edit-widget.cpp
+++ b/src/ui/view/edit-widget.cpp
@@ -1380,11 +1380,11 @@ EditWidget::updateScrollbars (double scale)
/* The desktop region we always show unconditionally */
SPDocument *doc = _desktop->doc();
- NR::Rect const r = sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)));
- NR::Rect darea(NR::Point(MIN(r.min()[NR::X], -sp_document_width(doc)),
- MIN(r.min()[NR::Y], -sp_document_height(doc))),
- NR::Point(MAX(r.max()[NR::X], 2 * sp_document_width(doc)),
- MAX(r.max()[NR::Y], 2 * sp_document_height(doc))));
+ NR::Rect darea = NR::Rect(NR::Point(-sp_document_width(doc),
+ -sp_document_height(doc)),
+ NR::Point(2 * sp_document_width(doc),
+ 2 * sp_document_height(doc)));
+ darea = NR::union_bounds(darea, sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc))));
/* Canvas region we always show unconditionally */
NR::Rect carea(NR::Point(darea.min()[NR::X] * scale - 64,
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp
index 76313f771..237e4c8e9 100644
--- a/src/widgets/desktop-widget.cpp
+++ b/src/widgets/desktop-widget.cpp
@@ -1274,11 +1274,9 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale)
/* The desktop region we always show unconditionally */
SPDocument *doc = dtw->desktop->doc();
- NR::Rect const r = sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc)));
- NR::Rect darea(NR::Point(MIN(r.min()[NR::X], -sp_document_width(doc)),
- MIN(r.min()[NR::Y], -sp_document_height(doc))),
- NR::Point(MAX(r.max()[NR::X], 2 * sp_document_width(doc)),
- MAX(r.max()[NR::Y], 2 * sp_document_height(doc))));
+ NR::Rect darea(NR::Point(-sp_document_width(doc), -sp_document_height(doc)),
+ NR::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc)));
+ darea = NR::union_bounds(darea, sp_item_bbox_desktop(SP_ITEM(SP_DOCUMENT_ROOT(doc))));
/* Canvas region we always show unconditionally */
NR::Rect carea(NR::Point(darea.min()[NR::X] * scale - 64,