summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-08-27 09:04:37 +0000
committerKrzysztof Kosinski <tweenk.pl@gmail.com>2011-08-27 09:04:37 +0000
commit72cc39b9f0b340548f395c7f61ca9662b34aea09 (patch)
tree34a0853cff6c6040bc2a0572dfa365280fce2601
parentFix "snap guides" toggle (diff)
downloadinkscape-72cc39b9f0b340548f395c7f61ca9662b34aea09.tar.gz
inkscape-72cc39b9f0b340548f395c7f61ca9662b34aea09.zip
Refactor SPItem bounding box methods: remove NRRect usage and make code
using them more obvious. Fix filter region computation. (bzr r10582.1.1)
Diffstat (limited to '')
-rw-r--r--src/conn-avoid-ref.cpp2
-rw-r--r--src/desktop.cpp14
-rw-r--r--src/dialogs/clonetiler.cpp7
-rw-r--r--src/dialogs/export.cpp29
-rw-r--r--src/dialogs/spellcheck.cpp4
-rw-r--r--src/display/nr-filter-image.cpp2
-rw-r--r--src/document.cpp2
-rw-r--r--src/eraser-context.cpp4
-rw-r--r--src/extension/dbus/document-interface.cpp10
-rw-r--r--src/extension/internal/bitmap/crop.cpp2
-rw-r--r--src/extension/internal/cairo-render-context.cpp101
-rw-r--r--src/extension/internal/cairo-render-context.h26
-rw-r--r--src/extension/internal/cairo-renderer.cpp86
-rw-r--r--src/extension/internal/emf-win32-print.cpp19
-rw-r--r--src/extension/internal/grid.cpp2
-rw-r--r--src/extension/internal/latex-text-renderer.cpp26
-rw-r--r--src/extension/internal/odf.cpp15
-rw-r--r--src/file.cpp2
-rw-r--r--src/filter-chemistry.cpp4
-rw-r--r--src/flood-context.cpp2
-rw-r--r--src/gradient-chemistry.cpp6
-rw-r--r--src/gradient-drag.cpp6
-rw-r--r--src/graphlayout.cpp6
-rw-r--r--src/interface.cpp2
-rw-r--r--src/libnrtype/Layout-TNG-Output.cpp32
-rw-r--r--src/libnrtype/Layout-TNG.h6
-rw-r--r--src/live_effects/lpe-extrude.cpp6
-rw-r--r--src/live_effects/lpe-mirror_symmetry.cpp4
-rw-r--r--src/live_effects/lpe-rough-hatches.cpp2
-rw-r--r--src/live_effects/lpegroupbbox.cpp2
-rw-r--r--src/main.cpp9
-rw-r--r--src/marker.cpp9
-rw-r--r--src/object-snapper.cpp20
-rw-r--r--src/print.cpp10
-rw-r--r--src/print.h4
-rw-r--r--src/removeoverlap.cpp2
-rw-r--r--src/selcue.cpp10
-rw-r--r--src/selection-chemistry.cpp44
-rw-r--r--src/selection.cpp46
-rw-r--r--src/selection.h23
-rw-r--r--src/seltrans.cpp22
-rw-r--r--src/seltrans.h2
-rw-r--r--src/sp-clippath.cpp53
-rw-r--r--src/sp-clippath.h4
-rw-r--r--src/sp-flowtext.cpp65
-rw-r--r--src/sp-image.cpp23
-rw-r--r--src/sp-item-group.cpp19
-rw-r--r--src/sp-item-group.h2
-rw-r--r--src/sp-item-transform.cpp2
-rw-r--r--src/sp-item.cpp321
-rw-r--r--src/sp-item.h25
-rw-r--r--src/sp-mask.cpp32
-rw-r--r--src/sp-mask.h15
-rw-r--r--src/sp-offset.cpp2
-rw-r--r--src/sp-shape.cpp337
-rw-r--r--src/sp-shape.h2
-rw-r--r--src/sp-symbol.cpp8
-rw-r--r--src/sp-text.cpp55
-rw-r--r--src/sp-tref.cpp32
-rw-r--r--src/sp-tspan.cpp31
-rw-r--r--src/sp-use.cpp17
-rw-r--r--src/splivarot.cpp4
-rw-r--r--src/spray-context.cpp6
-rw-r--r--src/text-chemistry.cpp3
-rw-r--r--src/text-context.cpp4
-rw-r--r--src/tweak-context.cpp20
-rw-r--r--src/ui/clipboard.cpp8
-rw-r--r--src/ui/dialog/align-and-distribute.cpp22
-rw-r--r--src/ui/dialog/align-and-distribute.h2
-rw-r--r--src/ui/dialog/filedialogimpl-win32.cpp4
-rw-r--r--src/ui/dialog/tile.cpp16
-rw-r--r--src/ui/dialog/transformation.cpp26
-rw-r--r--src/ui/widget/style-subject.cpp2
-rw-r--r--src/ui/widget/style-subject.h6
-rw-r--r--src/unclump.cpp4
-rw-r--r--src/verbs.cpp2
-rw-r--r--src/widgets/desktop-widget.cpp2
-rw-r--r--src/widgets/icon.cpp3
-rw-r--r--src/widgets/select-toolbar.cpp12
-rw-r--r--src/widgets/stroke-style.cpp3
-rw-r--r--src/widgets/toolbox.cpp5
81 files changed, 789 insertions, 1042 deletions
diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp
index fad11bb89..331865254 100644
--- a/src/conn-avoid-ref.cpp
+++ b/src/conn-avoid-ref.cpp
@@ -394,7 +394,7 @@ Geom::Point SPAvoidRef::getConnectionPointPos(const int type, const int id)
if ( type == ConnPointDefault )
{
// For now, just default to the centre of the item
- Geom::OptRect bbox = item->getBounds(item->i2doc_affine());
+ Geom::OptRect bbox = item->documentVisualBounds();
pos = (bbox) ? bbox->midpoint() : Geom::Point(0, 0);
}
else
diff --git a/src/desktop.cpp b/src/desktop.cpp
index ca5fdc63b..b622d1080 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -577,16 +577,16 @@ bool SPDesktop::isLayer(SPObject *object) const {
}
/**
- * True if desktop viewport fully contains \a item's bbox.
+ * True if desktop viewport intersects \a item's bbox.
*/
bool SPDesktop::isWithinViewport (SPItem *item) const
{
Geom::Rect const viewport = get_display_area();
- Geom::OptRect const bbox = item->getBboxDesktop();
+ Geom::OptRect const bbox = item->desktopVisualBounds();
if (bbox) {
- return viewport.contains(*bbox);
+ return viewport.intersects(*bbox);
} else {
- return true;
+ return false;
}
}
@@ -957,7 +957,7 @@ SPDesktop::zoom_quick (bool enable)
}
if (!zoomed) {
- Geom::OptRect const d = selection->bounds();
+ Geom::OptRect const d = selection->visualBounds();
if (d && d->area() * 2.0 < _quick_zoom_stored_area.area()) {
set_display_area(*d, true);
zoomed = true;
@@ -1109,7 +1109,7 @@ SPDesktop::zoom_page_width()
void
SPDesktop::zoom_selection()
{
- Geom::OptRect const d = selection->bounds();
+ Geom::OptRect const d = selection->visualBounds();
if ( !d || d->minExtent() < 0.1 ) {
return;
@@ -1137,7 +1137,7 @@ SPDesktop::zoom_drawing()
SPItem *docitem = doc()->getRoot();
g_return_if_fail (docitem != NULL);
- Geom::OptRect d = docitem->getBboxDesktop();
+ Geom::OptRect d = docitem->desktopVisualBounds();
/* Note that the second condition here indicates that
** there are no items in the drawing.
diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp
index 109b235d0..a92b6392e 100644
--- a/src/dialogs/clonetiler.cpp
+++ b/src/dialogs/clonetiler.cpp
@@ -1170,10 +1170,9 @@ static void clonetiler_apply(GtkWidget */*widget*/, void *)
y0 = sp_repr_get_double_attribute (obj_repr, "inkscape:tile-y0", 0);
} else {
bool prefs_bbox = prefs->getBool("/tools/bounding_box", false);
- SPItem::BBoxType bbox_type = ( prefs_bbox ?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX );
- Geom::OptRect r = item->getBounds(item->i2doc_affine(),
- bbox_type);
+ SPItem::BBoxType bbox_type = ( !prefs_bbox ?
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX );
+ Geom::OptRect r = item->documentBounds(bbox_type);
if (r) {
w = r->dimensions()[Geom::X];
h = r->dimensions()[Geom::Y];
diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp
index 0c2bc5adc..a19f9b60f 100644
--- a/src/dialogs/export.cpp
+++ b/src/dialogs/export.cpp
@@ -783,20 +783,22 @@ sp_export_selection_modified ( Inkscape::Application */*inkscape*/,
if ( SP_ACTIVE_DESKTOP ) {
SPDocument *doc;
doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
- Geom::OptRect bbox = doc->getRoot()->getBboxDesktop(SPItem::RENDERING_BBOX);
+ Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds();
if (bbox) {
- sp_export_set_area (base, bbox->min()[Geom::X],
- bbox->min()[Geom::Y],
- bbox->max()[Geom::X],
- bbox->max()[Geom::Y]);
+ sp_export_set_area (base, bbox->left(),
+ bbox->top(),
+ bbox->right(),
+ bbox->bottom());
}
}
break;
case SELECTION_SELECTION:
if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
- NRRect bbox;
- (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(&bbox, SPItem::RENDERING_BBOX);
- sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
+ Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->visualBounds();
+ sp_export_set_area (base, bbox->left(),
+ bbox->top(),
+ bbox->right(),
+ bbox->bottom());
}
break;
default:
@@ -852,7 +854,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
case SELECTION_SELECTION:
if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false)
{
- bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->bounds(SPItem::RENDERING_BBOX);
+ bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds();
/* Only if there is a selection that we can set
do we break, otherwise we fall through to the
drawing */
@@ -864,7 +866,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
/** \todo
* This returns wrong values if the document has a viewBox.
*/
- bbox = doc->getRoot()->getBboxDesktop(SPItem::RENDERING_BBOX);
+ bbox = doc->getRoot()->desktopVisualBounds();
/* If the drawing is valid, then we'll use it and break
otherwise we drop through to the page settings */
if (bbox) {
@@ -1129,8 +1131,7 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
dpi = DPI_BASE;
}
- Geom::OptRect area;
- item->invoke_bbox( area, item->i2dt_affine(), TRUE );
+ Geom::OptRect area = item->desktopVisualBounds();
if (area) {
gint width = (gint) (area->width() * dpi / PX_PER_IN + 0.5);
gint height = (gint) (area->height() * dpi / PX_PER_IN + 0.5);
@@ -1493,7 +1494,7 @@ sp_export_detect_size(GtkObject * base) {
switch (this_test[i]) {
case SELECTION_SELECTION:
if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
- Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::RENDERING_BBOX);
+ Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX);
//std::cout << "Selection " << bbox;
if ( bbox && sp_export_bbox_equal(*bbox,current_bbox)) {
@@ -1504,7 +1505,7 @@ sp_export_detect_size(GtkObject * base) {
case SELECTION_DRAWING: {
SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
- Geom::OptRect bbox = doc->getRoot()->getBboxDesktop(SPItem::RENDERING_BBOX);
+ Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds();
// std::cout << "Drawing " << bbox2;
if ( bbox && sp_export_bbox_equal(*bbox,current_bbox) ) {
diff --git a/src/dialogs/spellcheck.cpp b/src/dialogs/spellcheck.cpp
index d0de6ad20..bd8381d8c 100644
--- a/src/dialogs/spellcheck.cpp
+++ b/src/dialogs/spellcheck.cpp
@@ -243,8 +243,8 @@ gint compare_text_bboxes (gconstpointer a, gconstpointer b)
SPItem *i1 = SP_ITEM(a);
SPItem *i2 = SP_ITEM(b);
- Geom::OptRect bbox1 = i1->getBounds(i1->i2dt_affine());
- Geom::OptRect bbox2 = i2->getBounds(i2->i2dt_affine());
+ Geom::OptRect bbox1 = i1->desktopVisualBounds();
+ Geom::OptRect bbox2 = i2->desktopVisualBounds();
if (!bbox1 || !bbox2) {
return 0;
}
diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp
index a22d23548..5911f5908 100644
--- a/src/display/nr-filter-image.cpp
+++ b/src/display/nr-filter-image.cpp
@@ -74,7 +74,7 @@ void FilterImage::render_cairo(FilterSlot &slot)
document->ensureUpToDate();
Drawing drawing;
- Geom::OptRect optarea = SVGElem->getBounds(Geom::identity());
+ Geom::OptRect optarea = SVGElem->visualBounds();
if (!optarea) return;
unsigned const key = SPItem::display_key_new(1);
diff --git a/src/document.cpp b/src/document.cpp
index 72f92bd17..cf2474fe5 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -1086,7 +1086,7 @@ 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);
- Geom::OptRect box = child->getBboxDesktop();
+ Geom::OptRect box = child->desktopVisualBounds();
if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
s = g_slist_append(s, child);
}
diff --git a/src/eraser-context.cpp b/src/eraser-context.cpp
index de6c7d86f..11b150aa0 100644
--- a/src/eraser-context.cpp
+++ b/src/eraser-context.cpp
@@ -748,7 +748,7 @@ set_to_accumulated(SPEraserContext *dc)
Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
SPItem* acid = SP_ITEM(desktop->doc()->getObjectByRepr(dc->repr));
- Geom::OptRect eraserBbox = acid->getBounds(Geom::identity());
+ Geom::OptRect eraserBbox = acid->visualBounds();
Geom::Rect bounds = (*eraserBbox) * desktop->doc2dt();
std::vector<SPItem*> remainingItems;
GSList* toWorkOn = 0;
@@ -770,7 +770,7 @@ set_to_accumulated(SPEraserContext *dc)
for (GSList *i = toWorkOn ; i ; i = i->next ) {
SPItem *item = SP_ITEM(i->data);
if ( eraserMode ) {
- Geom::OptRect bbox = item->getBounds(Geom::identity());
+ Geom::OptRect bbox = item->visualBounds();
if (bbox && bbox->intersects(*eraserBbox)) {
Inkscape::XML::Node* dup = dc->repr->duplicate(xml_doc);
dc->repr->parent()->appendChild(dup);
diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp
index 1e6577173..b4f42a37d 100644
--- a/src/extension/dbus/document-interface.cpp
+++ b/src/extension/dbus/document-interface.cpp
@@ -157,16 +157,14 @@ desktop_ensure_active (SPDesktop* desk) {
gdouble
selection_get_center_x (Inkscape::Selection *sel){
- NRRect *box = g_new(NRRect, 1);;
- box = sel->boundsInDocument(box);
- return box->x0 + ((box->x1 - box->x0)/2);
+ Geom::OptRect box = sel->documentBounds(SPItem::GEOMETRIC_BBOX);
+ return box ? box->midpoint()[Geom::X] : 0;
}
gdouble
selection_get_center_y (Inkscape::Selection *sel){
- NRRect *box = g_new(NRRect, 1);;
- box = sel->boundsInDocument(box);
- return box->y0 + ((box->y1 - box->y0)/2);
+ Geom::OptRect box = sel->documentBounds(SPItem::GEOMETRIC_BBOX);
+ return box ? box->midpoint()[Geom::X] : 0;
}
/*
diff --git a/src/extension/internal/bitmap/crop.cpp b/src/extension/internal/bitmap/crop.cpp
index 23e31b510..2ad75a0dc 100644
--- a/src/extension/internal/bitmap/crop.cpp
+++ b/src/extension/internal/bitmap/crop.cpp
@@ -38,7 +38,7 @@ Crop::postEffect(Magick::Image *image, SPItem *item) {
sp_item_scale_rel (item, scale);
// Translate proportionaly to the image/bbox ratio
- Geom::OptRect bbox(item->getBboxDesktop());
+ Geom::OptRect bbox(item->desktopGeometricBounds());
//g_warning("bbox. W:%f, H:%f, X:%f, Y:%f", bbox->dimensions()[Geom::X], bbox->dimensions()[Geom::Y], bbox->min()[Geom::X], bbox->min()[Geom::Y]);
Geom::Translate translate (0,0);
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp
index c3a8a790b..a0573d9ff 100644
--- a/src/extension/internal/cairo-render-context.cpp
+++ b/src/extension/internal/cairo-render-context.cpp
@@ -682,12 +682,12 @@ CairoRenderContext::popLayer(void)
// copy the correct CTM to mask context
/*
if (_state->parent_has_userspace)
- mask_ctx->setTransform(&getParentState()->transform);
+ mask_ctx->setTransform(getParentState()->transform);
else
- mask_ctx->setTransform(&_state->transform);
+ mask_ctx->setTransform(_state->transform);
*/
// This is probably not correct... but it seems to do the trick.
- mask_ctx->setTransform(&_state->item_transform);
+ mask_ctx->setTransform(_state->item_transform);
// render mask contents to mask_ctx
_renderer->applyMask(mask_ctx, mask);
@@ -915,7 +915,7 @@ CairoRenderContext::finish(void)
}
void
-CairoRenderContext::transform(Geom::Affine const *transform)
+CairoRenderContext::transform(Geom::Affine const &transform)
{
g_assert( _is_valid );
@@ -924,42 +924,44 @@ CairoRenderContext::transform(Geom::Affine const *transform)
cairo_transform(_cr, &matrix);
// store new CTM
- getTransform(&_state->transform);
+ _state->transform = getTransform();
}
void
-CairoRenderContext::setTransform(Geom::Affine const *transform)
+CairoRenderContext::setTransform(Geom::Affine const &transform)
{
g_assert( _is_valid );
cairo_matrix_t matrix;
_initCairoMatrix(&matrix, transform);
cairo_set_matrix(_cr, &matrix);
- _state->transform = *transform;
+ _state->transform = transform;
}
-void
-CairoRenderContext::getTransform(Geom::Affine *copy) const
+Geom::Affine
+CairoRenderContext::getTransform() const
{
g_assert( _is_valid );
cairo_matrix_t ctm;
cairo_get_matrix(_cr, &ctm);
- (*copy)[0] = ctm.xx;
- (*copy)[1] = ctm.yx;
- (*copy)[2] = ctm.xy;
- (*copy)[3] = ctm.yy;
- (*copy)[4] = ctm.x0;
- (*copy)[5] = ctm.y0;
+ Geom::Affine ret;
+ ret[0] = ctm.xx;
+ ret[1] = ctm.yx;
+ ret[2] = ctm.xy;
+ ret[3] = ctm.yy;
+ ret[4] = ctm.x0;
+ ret[5] = ctm.y0;
+ return ret;
}
-void
-CairoRenderContext::getParentTransform(Geom::Affine *copy) const
+Geom::Affine
+CairoRenderContext::getParentTransform() const
{
g_assert( _is_valid );
CairoRenderState *parent_state = getParentState();
- memcpy(copy, &parent_state->transform, sizeof(Geom::Affine));
+ return parent_state->transform;
}
void
@@ -1002,7 +1004,7 @@ static bool pattern_hasItemChildren(SPPattern *pat)
}
cairo_pattern_t*
-CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver, NRRect const *pbox)
+CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox)
{
g_assert( SP_IS_PATTERN(paintserver) );
@@ -1023,10 +1025,10 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
if (pbox && pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
//Geom::Affine bbox2user (pbox->x1 - pbox->x0, 0.0, 0.0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0);
- bbox_width_scaler = pbox->x1 - pbox->x0;
- bbox_height_scaler = pbox->y1 - pbox->y0;
- ps2user[4] = x * bbox_width_scaler + pbox->x0;
- ps2user[5] = y * bbox_height_scaler + pbox->y0;
+ bbox_width_scaler = pbox->width();
+ bbox_height_scaler = pbox->height();
+ ps2user[4] = x * bbox_width_scaler + pbox->left();
+ ps2user[5] = y * bbox_height_scaler + pbox->top();
} else {
bbox_width_scaler = 1.0;
bbox_height_scaler = 1.0;
@@ -1059,8 +1061,8 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
pcs2dev[4] = x - view_box->x0 * pcs2dev[0];
pcs2dev[5] = y - view_box->y0 * pcs2dev[3];
} else if (pbox && pattern_patternContentUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
- pcs2dev[0] = pbox->x1 - pbox->x0;
- pcs2dev[3] = pbox->y1 - pbox->y0;
+ pcs2dev[0] = pbox->width();
+ pcs2dev[3] = pbox->height();
}
@@ -1089,7 +1091,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
ps2user[4] = ori[Geom::X];
ps2user[5] = ori[Geom::Y];
- pattern_ctx->setTransform(&pcs2dev);
+ pattern_ctx->setTransform(pcs2dev);
pattern_ctx->pushState();
// create drawing and group
@@ -1119,7 +1121,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
// set pattern transformation
cairo_matrix_t pattern_matrix;
- _initCairoMatrix(&pattern_matrix, &ps2user);
+ _initCairoMatrix(&pattern_matrix, ps2user);
cairo_matrix_invert(&pattern_matrix);
cairo_pattern_set_matrix(result, &pattern_matrix);
@@ -1142,7 +1144,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
cairo_pattern_t*
CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const paintserver,
- NRRect const *pbox, float alpha)
+ Geom::OptRect const &pbox, float alpha)
{
cairo_pattern_t *pattern = NULL;
bool apply_bbox2user = FALSE;
@@ -1157,7 +1159,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
Geom::Point p2 (lg->x2.computed, lg->y2.computed);
if (pbox && SP_GRADIENT(lg)->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) {
// convert to userspace
- Geom::Affine bbox2user(pbox->x1 - pbox->x0, 0, 0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0);
+ Geom::Affine bbox2user(pbox->width(), 0, 0, pbox->height(), pbox->left(), pbox->top());
p1 *= bbox2user;
p2 *= bbox2user;
}
@@ -1237,7 +1239,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
if (apply_bbox2user) {
// convert to userspace
cairo_matrix_t bbox2user;
- cairo_matrix_init (&bbox2user, pbox->x1 - pbox->x0, 0, 0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0);
+ cairo_matrix_init (&bbox2user, pbox->width(), 0, 0, pbox->height(), pbox->left(), pbox->top());
cairo_matrix_multiply (&pattern_matrix, &bbox2user, &pattern_matrix);
}
cairo_matrix_invert(&pattern_matrix); // because Cairo expects a userspace->patternspace matrix
@@ -1248,7 +1250,7 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain
}
void
-CairoRenderContext::_setFillStyle(SPStyle const *const style, NRRect const *pbox)
+CairoRenderContext::_setFillStyle(SPStyle const *const style, Geom::OptRect const &pbox)
{
g_return_if_fail( !style->fill.set
|| style->fill.isColor()
@@ -1284,7 +1286,7 @@ CairoRenderContext::_setFillStyle(SPStyle const *const style, NRRect const *pbox
}
void
-CairoRenderContext::_setStrokeStyle(SPStyle const *style, NRRect const *pbox)
+CairoRenderContext::_setStrokeStyle(SPStyle const *style, Geom::OptRect const &pbox)
{
float alpha = SP_SCALE24_TO_FLOAT(style->stroke_opacity.value);
if (_state->merge_opacity)
@@ -1351,7 +1353,7 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, NRRect const *pbox)
}
bool
-CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, NRRect const *pbox)
+CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, Geom::OptRect const &pbox)
{
g_assert( _is_valid );
@@ -1419,7 +1421,7 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con
}
bool CairoRenderContext::renderImage(GdkPixbuf *pb,
- Geom::Affine const *image_transform, SPStyle const * /*style*/)
+ Geom::Affine const &image_transform, SPStyle const * /*style*/)
{
g_assert( _is_valid );
@@ -1442,8 +1444,7 @@ bool CairoRenderContext::renderImage(GdkPixbuf *pb,
cairo_save(_cr);
// scaling by width & height is not needed because it will be done by Cairo
- if (image_transform)
- transform(image_transform);
+ transform(image_transform);
cairo_set_source_surface(_cr, image_surface, 0.0, 0.0);
@@ -1507,7 +1508,7 @@ unsigned int CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont * /*font*/,
}
bool
-CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const *font_matrix,
+CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_matrix,
std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style)
{
// create a cairo_font_face from PangoFont
@@ -1575,7 +1576,7 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const *font_ma
stroke = true;
}
if (fill) {
- _setFillStyle(style, NULL);
+ _setFillStyle(style, Geom::OptRect());
if (_is_texttopath) {
_showGlyphs(_cr, font, glyphtext, true);
have_path = true;
@@ -1586,7 +1587,7 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const *font_ma
}
}
if (stroke) {
- _setStrokeStyle(style, NULL);
+ _setStrokeStyle(style, Geom::OptRect());
if (!have_path) _showGlyphs(_cr, font, glyphtext, true);
cairo_stroke(_cr);
}
@@ -1625,22 +1626,22 @@ CairoRenderContext::_concatTransform(cairo_t *cr, double xx, double yx, double x
}
void
-CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, Geom::Affine const *transform)
+CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, Geom::Affine const &transform)
{
- matrix->xx = (*transform)[0];
- matrix->yx = (*transform)[1];
- matrix->xy = (*transform)[2];
- matrix->yy = (*transform)[3];
- matrix->x0 = (*transform)[4];
- matrix->y0 = (*transform)[5];
+ matrix->xx = transform[0];
+ matrix->yx = transform[1];
+ matrix->xy = transform[2];
+ matrix->yy = transform[3];
+ matrix->x0 = transform[4];
+ matrix->y0 = transform[5];
}
void
-CairoRenderContext::_concatTransform(cairo_t *cr, Geom::Affine const *transform)
+CairoRenderContext::_concatTransform(cairo_t *cr, Geom::Affine const &transform)
{
- _concatTransform(cr, (*transform)[0], (*transform)[1],
- (*transform)[2], (*transform)[3],
- (*transform)[4], (*transform)[5]);
+ _concatTransform(cr, transform[0], transform[1],
+ transform[2], transform[3],
+ transform[4], transform[5]);
}
static cairo_status_t
diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h
index d4117ff7e..94c7bb294 100644
--- a/src/extension/internal/cairo-render-context.h
+++ b/src/extension/internal/cairo-render-context.h
@@ -128,20 +128,20 @@ public:
CairoRenderState *getParentState(void) const;
void setStateForStyle(SPStyle const *style);
- void transform(Geom::Affine const *transform);
- void setTransform(Geom::Affine const *transform);
- void getTransform(Geom::Affine *copy) const;
- void getParentTransform(Geom::Affine *copy) const;
+ void transform(Geom::Affine const &transform);
+ void setTransform(Geom::Affine const &transform);
+ Geom::Affine getTransform() const;
+ Geom::Affine getParentTransform() const;
/* Clipping methods */
void addClipPath(Geom::PathVector const &pv, SPIEnum const *fill_rule);
void addClippingRect(double x, double y, double width, double height);
/* Rendering methods */
- bool renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, NRRect const *pbox);
+ bool renderPathVector(Geom::PathVector const &pathv, SPStyle const *style, Geom::OptRect const &pbox);
bool renderImage(GdkPixbuf *pb,
- Geom::Affine const *image_transform, SPStyle const *style);
- bool renderGlyphtext(PangoFont *font, Geom::Affine const *font_matrix,
+ Geom::Affine const &image_transform, SPStyle const *style);
+ bool renderGlyphtext(PangoFont *font, Geom::Affine const &font_matrix,
std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style);
/* More general rendering methods will have to be added (like fill, stroke) */
@@ -183,18 +183,18 @@ protected:
CairoClipMode _clip_mode;
cairo_pattern_t *_createPatternForPaintServer(SPPaintServer const *const paintserver,
- NRRect const *pbox, float alpha);
- cairo_pattern_t *_createPatternPainter(SPPaintServer const *const paintserver, NRRect const *pbox);
+ Geom::OptRect const &pbox, float alpha);
+ cairo_pattern_t *_createPatternPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox);
unsigned int _showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoGlyphInfo> const &glyphtext, bool is_stroke);
bool _finishSurfaceSetup(cairo_surface_t *surface, cairo_matrix_t *ctm = NULL);
- void _setFillStyle(SPStyle const *style, NRRect const *pbox);
- void _setStrokeStyle(SPStyle const *style, NRRect const *pbox);
+ void _setFillStyle(SPStyle const *style, Geom::OptRect const &pbox);
+ void _setStrokeStyle(SPStyle const *style, Geom::OptRect const &pbox);
- void _initCairoMatrix(cairo_matrix_t *matrix, Geom::Affine const *transform);
+ void _initCairoMatrix(cairo_matrix_t *matrix, Geom::Affine const &transform);
void _concatTransform(cairo_t *cr, double xx, double yx, double xy, double yy, double x0, double y0);
- void _concatTransform(cairo_t *cr, Geom::Affine const *transform);
+ void _concatTransform(cairo_t *cr, Geom::Affine const &transform);
GHashTable *font_table;
static void font_data_free(gpointer data);
diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp
index 5e7fb991a..adfa0421d 100644
--- a/src/extension/internal/cairo-renderer.cpp
+++ b/src/extension/internal/cairo-renderer.cpp
@@ -181,15 +181,13 @@ static void sp_shape_render_invoke_marker_rendering(SPMarker* marker, Geom::Affi
static void sp_shape_render (SPItem *item, CairoRenderContext *ctx)
{
- NRRect pbox;
-
SPShape *shape = SP_SHAPE(item);
if (!shape->curve) {
return;
}
- item->invoke_bbox( &pbox, Geom::identity(), TRUE);
+ Geom::OptRect pbox = item->geometricBounds();
SPStyle* style = item->style;
@@ -198,7 +196,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx)
return;
}
- ctx->renderPathVector(pathv, style, &pbox);
+ ctx->renderPathVector(pathv, style, pbox);
// START marker
for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START
@@ -316,7 +314,7 @@ static void sp_use_render(SPItem *item, CairoRenderContext *ctx)
if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) {
Geom::Affine tp(Geom::Translate(use->x.computed, use->y.computed));
ctx->pushState();
- ctx->transform(&tp);
+ ctx->transform(tp);
translated = true;
}
@@ -372,7 +370,7 @@ static void sp_image_render(SPItem *item, CairoRenderContext *ctx)
Geom::Scale s(width / (double)w, height / (double)h);
Geom::Affine t(s * tp);
- ctx->renderImage (image->pixbuf, &t, item->style);
+ ctx->renderImage (image->pixbuf, t, item->style);
}
static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx)
@@ -384,7 +382,7 @@ static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx)
/* Cloned <symbol> is actually renderable */
ctx->pushState();
- ctx->transform(&symbol->c2p);
+ ctx->transform(symbol->c2p);
// apply viewbox if set
if (0 /*symbol->viewBox_set*/) {
@@ -409,7 +407,7 @@ static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx)
vb2user[4] = x - symbol->viewBox.x0 * vb2user[0];
vb2user[5] = y - symbol->viewBox.y0 * vb2user[3];
- ctx->transform(&vb2user);
+ ctx->transform(vb2user);
}
sp_group_render(item, ctx);
@@ -425,8 +423,7 @@ static void sp_root_render(SPRoot *root, CairoRenderContext *ctx)
ctx->pushState();
renderer->setStateForItem(ctx, root);
- Geom::Affine tempmat (root->c2p);
- ctx->transform(&tempmat);
+ ctx->transform(root->c2p);
sp_group_render(root, ctx);
ctx->popState();
}
@@ -450,9 +447,8 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx)
}
TRACE(("sp_asbitmap_render: resolution: %f\n", res ));
- // Get the bounding box of the selection in document coordinates.
- Geom::OptRect bbox =
- item->getBounds(item->i2dt_affine(), SPItem::RENDERING_BBOX);
+ // Get the bounding box of the selection in desktop coordinates.
+ Geom::OptRect bbox = item->desktopVisualBounds();
// no bbox, e.g. empty group
if (!bbox) {
@@ -460,12 +456,7 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx)
}
Geom::Rect docrect(Geom::Rect(Geom::Point(0, 0), item->document->getDimensions()));
- Geom::Rect bboxrect(Geom::Rect(Geom::Point(bbox->min()[Geom::X], bbox->min()[Geom::Y]), Geom::Point(bbox->max()[Geom::X], bbox->max()[Geom::Y])));
-
- Geom::OptRect _bbox = Geom::intersect(docrect, bboxrect);
-
- // assign the object dimension clipped on the document, no need to draw on area not on canvas
- bbox = _bbox;
+ bbox &= docrect;
// no bbox, e.g. empty group
if (!bbox) {
@@ -473,14 +464,14 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx)
}
// The width and height of the bitmap in pixels
- unsigned width = ceil((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN));
- unsigned height = ceil((bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) * (res / PX_PER_IN));
+ unsigned width = ceil(bbox->width() * (res / PX_PER_IN));
+ unsigned height = ceil(bbox->height() * (res / PX_PER_IN));
if (width == 0 || height == 0) return;
// Scale to exactly fit integer bitmap inside bounding box
- double scale_x = (bbox->max()[Geom::X] - bbox->min()[Geom::X]) / width;
- double scale_y = (bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) / height;
+ double scale_x = bbox->width() / width;
+ double scale_y = bbox->height() / height;
// Location of bounding box in document coordinates.
double shift_x = bbox->min()[Geom::X];
@@ -516,7 +507,7 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx)
TEST(gdk_pixbuf_save( pb, "bitmap.png", "png", NULL, NULL ));
// TODO this is stupid - we just converted to pixbuf format when generating the bitmap!
convert_pixbuf_normal_to_argb32(pb);
- ctx->renderImage(pb, &t, item->style);
+ ctx->renderImage(pb, t, item->style);
gdk_pixbuf_unref(pb);
pb = 0;
}
@@ -604,8 +595,7 @@ void CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item)
state->merge_opacity = FALSE;
ctx->pushLayer();
}
- Geom::Affine tempmat (item->transform);
- ctx->transform(&tempmat);
+ ctx->transform(item->transform);
sp_item_invoke_render(item, ctx);
if (state->need_layer)
@@ -625,25 +615,25 @@ CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool page
base = doc->getRoot();
}
- NRRect d;
+ Geom::Rect d;
if (pageBoundingBox) {
- d.x0 = d.y0 = 0;
- d.x1 = doc->getWidth();
- d.y1 = doc->getHeight();
+ d = Geom::Rect::from_xywh(Geom::Point(0,0), doc->getDimensions());
} else {
- base->invoke_bbox( &d, base->i2dt_affine(), TRUE, SPItem::RENDERING_BBOX);
+ Geom::OptRect bbox = base->desktopVisualBounds();
+ if (!bbox) {
+ g_message("CairoRenderer: empty bounding box.");
+ return false;
+ }
+ d = *bbox;
}
if (ctx->_vector_based_target) {
// convert from px to pt
- d.x0 *= PT_PER_PX;
- d.x1 *= PT_PER_PX;
- d.y0 *= PT_PER_PX;
- d.y1 *= PT_PER_PX;
+ d *= Geom::Scale(PT_PER_PX);
}
- ctx->_width = d.x1-d.x0;
- ctx->_height = d.y1-d.y0;
+ ctx->_width = d.width();
+ ctx->_height = d.height();
TRACE(("setupDocument: %f x %f\n", ctx->_width, ctx->_height));
@@ -655,11 +645,12 @@ CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool page
if (ctx->_vector_based_target)
high *= PT_PER_PX;
- Geom::Affine tp(Geom::Translate(-d.x0 * (ctx->_vector_based_target ? PX_PER_PT : 1.0),
- (d.y1 - high) * (ctx->_vector_based_target ? PX_PER_PT : 1.0)));
- ctx->transform(&tp);
+ /// @fixme hardcoded dt2doc transform?
+ Geom::Affine tp(Geom::Translate(-d.left() * (ctx->_vector_based_target ? PX_PER_PT : 1.0),
+ (d.bottom() - high) * (ctx->_vector_based_target ? PX_PER_PT : 1.0)));
+ ctx->transform(tp);
}
-
+
return ret;
}
@@ -685,8 +676,8 @@ CairoRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp)
t[4] = clip_bbox.x0;
t[5] = clip_bbox.y0;
t *= ctx->getCurrentState()->transform;
- ctx->getTransform(&saved_ctm);
- ctx->setTransform(&t);
+ saved_ctm = ctx->getTransform();
+ ctx->setTransform(t);
}
TRACE(("BEGIN clip\n"));
@@ -696,12 +687,11 @@ CairoRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp)
SPItem const *item = SP_ITEM(child);
// combine transform of the item in clippath and the item using clippath:
- Geom::Affine tempmat (item->transform);
- tempmat = tempmat * (ctx->getCurrentState()->item_transform);
+ Geom::Affine tempmat = item->transform * ctx->getCurrentState()->item_transform;
// render this item in clippath
ctx->pushState();
- ctx->transform(&tempmat);
+ ctx->transform(tempmat);
setStateForItem(ctx, item);
// TODO fix this call to accept const items
sp_item_invoke_render(const_cast<SPItem *>(item), ctx);
@@ -716,7 +706,7 @@ CairoRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp)
cairo_clip(ctx->_cr);
if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX)
- ctx->setTransform(&saved_ctm);
+ ctx->setTransform(saved_ctm);
ctx->setRenderMode(saved_mode);
}
@@ -738,7 +728,7 @@ CairoRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask)
t[4] = mask_bbox.x0;
t[5] = mask_bbox.y0;
t *= ctx->getCurrentState()->transform;
- ctx->setTransform(&t);
+ ctx->setTransform(t);
}
// Clip mask contents... but...
diff --git a/src/extension/internal/emf-win32-print.cpp b/src/extension/internal/emf-win32-print.cpp
index 7ed0f6fcf..be5bf96c3 100644
--- a/src/extension/internal/emf-win32-print.cpp
+++ b/src/extension/internal/emf-win32-print.cpp
@@ -135,25 +135,22 @@ PrintEmfWin32::begin (Inkscape::Extension::Print *mod, SPDocument *doc)
_width = doc->getWidth();
_height = doc->getHeight();
- NRRect d;
bool pageBoundingBox;
pageBoundingBox = mod->get_param_bool("pageBoundingBox");
+
+ Geom::Rect d;
if (pageBoundingBox) {
- d.x0 = d.y0 = 0;
- d.x1 = _width;
- d.y1 = _height;
+ d = Geom::Rect::from_xywh(0, 0, _width, _height);
} else {
SPItem* doc_item = doc->getRoot();
- doc_item->invoke_bbox(&d, doc_item->i2dt_affine(), TRUE);
+ Geom::OptRect bbox = doc_item->desktopVisualBounds();
+ if (bbox) d = *bbox;
}
- d.x0 *= IN_PER_PX;
- d.y0 *= IN_PER_PX;
- d.x1 *= IN_PER_PX;
- d.y1 *= IN_PER_PX;
+ d *= IN_PER_PX;
- float dwInchesX = (d.x1 - d.x0);
- float dwInchesY = (d.y1 - d.y0);
+ float dwInchesX = d.width();
+ float dwInchesY = d.height();
// dwInchesX x dwInchesY in .01mm units
SetRect( &rc, 0, 0, (int) ceil(dwInchesX*2540), (int) ceil(dwInchesY*2540) );
diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp
index 6436624fd..da5ea6d9e 100644
--- a/src/extension/internal/grid.cpp
+++ b/src/extension/internal/grid.cpp
@@ -90,7 +90,7 @@ Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc
bounding_area = Geom::Rect( Geom::Point(0,0),
Geom::Point(doc->getWidth(), doc->getHeight()) );
} else {
- Geom::OptRect bounds = selection->bounds();
+ Geom::OptRect bounds = selection->visualBounds();
if (bounds) {
bounding_area = *bounds;
}
diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp
index 02f0823d9..0da048a17 100644
--- a/src/extension/internal/latex-text-renderer.cpp
+++ b/src/extension/internal/latex-text-renderer.cpp
@@ -588,27 +588,27 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *
base = doc->getRoot();
}
- Geom::OptRect d;
+ Geom::Rect d;
if (pageBoundingBox) {
- d = Geom::Rect( Geom::Point(0,0),
- Geom::Point(doc->getWidth(), doc->getHeight()) );
+ d = Geom::Rect::from_xywh(Geom::Point(0,0), doc->getDimensions());
} else {
- base->invoke_bbox( d, base->i2dt_affine(), TRUE, SPItem::RENDERING_BBOX);
- }
- if (!d) {
- g_message("LaTeXTextRenderer: could not retrieve boundingbox.");
- return false;
+ Geom::OptRect bbox = base->desktopVisualBounds();
+ if (!bbox) {
+ g_message("CairoRenderer: empty bounding box.");
+ return false;
+ }
+ d = *bbox;
}
// scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX
- double scale = 1/(d->width());
- double _width = d->width() * scale;
- double _height = d->height() * scale;
+ double scale = 1/(d.width());
+ double _width = d.width() * scale;
+ double _height = d.height() * scale;
push_transform( Geom::Scale(scale, scale) );
if (!pageBoundingBox)
{
- push_transform( Geom::Translate( - d->min() ) );
+ push_transform( Geom::Translate( -d.min() ) );
}
// flip y-axis
@@ -621,7 +621,7 @@ LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, SPItem *
// scaling of the image when including it in LaTeX
os << " \\ifx\\svgwidth\\undefined%\n";
- os << " \\setlength{\\unitlength}{" << d->width() * PT_PER_PX << "bp}%\n"; // note: 'bp' is the Postscript pt unit in LaTeX, see LP bug #792384
+ os << " \\setlength{\\unitlength}{" << d.width() * PT_PER_PX << "bp}%\n"; // note: 'bp' is the Postscript pt unit in LaTeX, see LP bug #792384
os << " \\ifx\\svgscale\\undefined%\n";
os << " \\relax%\n";
os << " \\else%\n";
diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp
index 568c804a0..735c57798 100644
--- a/src/extension/internal/odf.cpp
+++ b/src/extension/internal/odf.cpp
@@ -573,7 +573,7 @@ void SingularValueDecomposition::calculate()
//double eps = pow(2.0,-52.0);
//double tiny = pow(2.0,-966.0);
//let's just calculate these now
- //a double can be e ± 308.25, so this is safe
+ //a double can be e ± 308.25, so this is safe
double eps = 2.22e-16;
double tiny = 1.6e-291;
while (p > 0) {
@@ -965,15 +965,10 @@ static Geom::Affine getODFTransform(const SPItem *item)
*/
static Geom::OptRect getODFBoundingBox(const SPItem *item)
{
- Geom::OptRect bbox_temp = ((SPItem *)item)->getBboxDesktop();
- Geom::OptRect bbox;
- if (bbox_temp) {
- bbox = *bbox_temp;
- double doc_height = SP_ACTIVE_DOCUMENT->getHeight();
- Geom::Affine doc2dt_tf = Geom::Affine(Geom::Scale(1.0, -1.0));
- doc2dt_tf = doc2dt_tf * Geom::Affine(Geom::Translate(0, doc_height));
- bbox = *bbox * doc2dt_tf;
- bbox = *bbox * Geom::Affine(Geom::Scale(pxToCm));
+ // TODO: geometric or visual?
+ Geom::OptRect bbox = ((SPItem *)item)->documentVisualBounds();
+ if (bbox) {
+ *bbox *= Geom::Affine(Geom::Scale(pxToCm));
}
return bbox;
}
diff --git a/src/file.cpp b/src/file.cpp
index c6d43fa51..350281dee 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -1056,7 +1056,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
// move to mouse pointer
{
sp_desktop_document(desktop)->ensureUpToDate();
- Geom::OptRect sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->visualBounds();
if (sel_bbox) {
Geom::Point m( desktop->point() - sel_bbox->midpoint() );
sp_selection_move_relative(selection, m, false);
diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp
index 9ea9407b1..1b63bf6f9 100644
--- a/src/filter-chemistry.cpp
+++ b/src/filter-chemistry.cpp
@@ -317,7 +317,7 @@ new_filter_blend_gaussian_blur (SPDocument *document, const char *blendmode, gdo
SPFilter *
new_filter_simple_from_item (SPDocument *document, SPItem *item, const char *mode, gdouble radius)
{
- Geom::OptRect const r = item->getBboxDesktop(SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect const r = item->desktopGeometricBounds();
double width;
double height;
@@ -370,7 +370,7 @@ SPFilter *modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *it
stdDeviation /= expansion;
// Get the object size
- Geom::OptRect const r = item->getBboxDesktop(SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect const r = item->desktopGeometricBounds();
double width;
double height;
if (r) {
diff --git a/src/flood-context.cpp b/src/flood-context.cpp
index 8603f8b66..9e8705862 100644
--- a/src/flood-context.cpp
+++ b/src/flood-context.cpp
@@ -778,7 +778,7 @@ static void sp_flood_do_flood_fill(SPEventContext *event_context, GdkEvent *even
document->ensureUpToDate();
- Geom::OptRect bbox = document->getRoot()->getBounds(Geom::identity());
+ Geom::OptRect bbox = document->getRoot()->visualBounds();
if (!bbox) {
desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("<b>Area is not bounded</b>, cannot fill."));
diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp
index f803d7bf8..5a8b20850 100644
--- a/src/gradient-chemistry.cpp
+++ b/src/gradient-chemistry.cpp
@@ -296,7 +296,7 @@ SPGradient *sp_gradient_reset_to_userspace(SPGradient *gr, SPItem *item)
// calculate the bbox of the item
item->document->ensureUpToDate();
- Geom::OptRect bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine
+ Geom::OptRect bbox = item->visualBounds(); // we need "true" bbox without item_i2d_affine
if (!bbox)
return gr;
@@ -363,7 +363,7 @@ SPGradient *sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar
// calculate the bbox of the item
item->document->ensureUpToDate();
Geom::Affine bbox2user;
- Geom::OptRect bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine
+ Geom::OptRect bbox = item->visualBounds(); // we need "true" bbox without item_i2d_affine
if ( bbox ) {
bbox2user = Geom::Affine(bbox->dimensions()[Geom::X], 0,
0, bbox->dimensions()[Geom::Y],
@@ -1063,7 +1063,7 @@ Geom::Point sp_item_gradient_get_coords(SPItem *item, guint point_type, guint po
if (SP_GRADIENT(gradient)->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) {
item->document->ensureUpToDate();
- Geom::OptRect bbox = item->getBounds(Geom::identity()); // we need "true" bbox without item_i2d_affine
+ Geom::OptRect bbox = item->visualBounds(); // we need "true" bbox without item_i2d_affine
if (bbox) {
p *= Geom::Affine(bbox->dimensions()[Geom::X], 0,
0, bbox->dimensions()[Geom::Y],
diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp
index 142ae2a98..1275bf995 100644
--- a/src/gradient-drag.cpp
+++ b/src/gradient-drag.cpp
@@ -1788,15 +1788,15 @@ GrDrag::updateLevels ()
for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) {
SPItem *item = SP_ITEM(i->data);
- Geom::OptRect rect = item->getBboxDesktop ();
+ Geom::OptRect rect = item->desktopVisualBounds();
if (rect) {
// Remember the edges of the bbox and the center axis
hor_levels.push_back(rect->min()[Geom::Y]);
hor_levels.push_back(rect->max()[Geom::Y]);
- hor_levels.push_back(0.5 * (rect->min()[Geom::Y] + rect->max()[Geom::Y]));
+ hor_levels.push_back(rect->midpoint()[Geom::Y]);
vert_levels.push_back(rect->min()[Geom::X]);
vert_levels.push_back(rect->max()[Geom::X]);
- vert_levels.push_back(0.5 * (rect->min()[Geom::X] + rect->max()[Geom::X]));
+ vert_levels.push_back(rect->midpoint()[Geom::X]);
}
}
}
diff --git a/src/graphlayout.cpp b/src/graphlayout.cpp
index 57002bfb6..6197be9f7 100644
--- a/src/graphlayout.cpp
+++ b/src/graphlayout.cpp
@@ -128,7 +128,7 @@ void graphlayout(GSList const *const items) {
++i)
{
SPItem *u=*i;
- Geom::OptRect const item_box(u->getBboxDesktop());
+ Geom::OptRect const item_box = u->desktopVisualBounds();
if(item_box) {
Geom::Point ll(item_box->min());
Geom::Point ur(item_box->max());
@@ -231,8 +231,8 @@ void graphlayout(GSList const *const items) {
map<string,unsigned>::iterator i=nodelookup.find(u->getId());
if(i!=nodelookup.end()) {
Rectangle* r=rs[i->second];
- Geom::OptRect item_box(u->getBboxDesktop());
- if(item_box) {
+ Geom::OptRect item_box = u->desktopVisualBounds();
+ if (item_box) {
Geom::Point const curr(item_box->midpoint());
Geom::Point const dest(r->getCentreX(),r->getCentreY());
sp_item_move_rel(u, Geom::Translate(dest - curr));
diff --git a/src/interface.cpp b/src/interface.cpp
index a981424fa..fb0d23e1b 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -1425,7 +1425,7 @@ sp_ui_drag_data_received(GtkWidget *widget,
// move to mouse pointer
{
sp_desktop_document(desktop)->ensureUpToDate();
- Geom::OptRect sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->visualBounds();
if (sel_bbox) {
Geom::Point m( desktop->point() - sel_bbox->midpoint() );
sp_selection_move_relative(selection, m, false);
diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp
index a72fa0180..fa1a07414 100644
--- a/src/libnrtype/Layout-TNG-Output.cpp
+++ b/src/libnrtype/Layout-TNG-Output.cpp
@@ -81,7 +81,7 @@ void Layout::_getGlyphTransformMatrix(int glyph_index, Geom::Affine *matrix) con
}
}
-void Layout::show(DrawingGroup *in_arena, NRRect const *paintbox) const
+void Layout::show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const
{
int glyph_index = 0;
for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) {
@@ -99,13 +99,14 @@ void Layout::show(DrawingGroup *in_arena, NRRect const *paintbox) const
}
glyph_index++;
}
- nr_text->setPaintBox(paintbox ? paintbox->upgrade_2geom() : Geom::OptRect());
+ nr_text->setPaintBox(paintbox);
in_arena->prependChild(nr_text);
}
}
-void Layout::getBoundingBox(NRRect *bounding_box, Geom::Affine const &transform, int start, int length) const
+Geom::OptRect Layout::bounds(Geom::Affine const &transform, int start, int length) const
{
+ Geom::OptRect bbox;
for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; glyph_index++) {
if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1) continue;
if (start != -1 && (int) _glyphs[glyph_index].in_character < start) continue;
@@ -122,26 +123,15 @@ void Layout::getBoundingBox(NRRect *bounding_box, Geom::Affine const &transform,
if(_glyphs[glyph_index].span(this).font) {
Geom::OptRect glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph);
if (glyph_rect) {
- Geom::Point bmi = glyph_rect->min(), bma = glyph_rect->max();
- Geom::Point tlp(bmi[0],bmi[1]), trp(bma[0],bmi[1]), blp(bmi[0],bma[1]), brp(bma[0],bma[1]);
- tlp *= total_transform;
- trp *= total_transform;
- blp *= total_transform;
- brp *= total_transform;
- *glyph_rect = Geom::Rect(tlp,trp);
- glyph_rect->expandTo(blp);
- glyph_rect->expandTo(brp);
- if ( (glyph_rect->min())[0] < bounding_box->x0 ) bounding_box->x0=(glyph_rect->min())[0];
- if ( (glyph_rect->max())[0] > bounding_box->x1 ) bounding_box->x1=(glyph_rect->max())[0];
- if ( (glyph_rect->min())[1] < bounding_box->y0 ) bounding_box->y0=(glyph_rect->min())[1];
- if ( (glyph_rect->max())[1] > bounding_box->y1 ) bounding_box->y1=(glyph_rect->max())[1];
+ bbox.unionWith(*glyph_rect * total_transform);
}
}
}
+ return bbox;
}
void Layout::print(SPPrintContext *ctx,
- NRRect const *pbox, NRRect const *dbox, NRRect const *bbox,
+ Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox,
Geom::Affine const &ctm) const
{
if (_input_stream.empty()) return;
@@ -240,7 +230,7 @@ void Layout::showGlyphs(CairoRenderContext *ctx) const
if (pathv) {
Geom::PathVector pathv_trans = (*pathv) * glyph_matrix;
SPStyle const *style = text_source->style;
- ctx->renderPathVector(pathv_trans, style, NULL);
+ ctx->renderPathVector(pathv_trans, style, Geom::OptRect());
}
glyph_index++;
continue;
@@ -302,7 +292,7 @@ void Layout::showGlyphs(CairoRenderContext *ctx) const
ctx->pushLayer();
}
if (glyph_index - first_index > 0)
- ctx->renderGlyphtext(span.font->pFont, &font_matrix, glyphtext, style);
+ ctx->renderGlyphtext(span.font->pFont, font_matrix, glyphtext, style);
if (opacity != 1.0) {
ctx->popLayer();
ctx->popState();
@@ -388,9 +378,9 @@ Glib::ustring Layout::dumpAsText() const
for (unsigned char_index = 0 ; char_index < _characters.size() ; char_index++) {
if (_characters[char_index].in_span != span_index) continue;
if (_input_stream[_spans[span_index].in_input_stream_item]->Type() != TEXT_SOURCE) {
- snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *(unsigned*)&_characters[char_index].char_attributes, _characters[char_index].in_glyph);
+ snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *(unsigned*) &_characters[char_index].char_attributes, _characters[char_index].in_glyph);
} else {
- snprintf(line, sizeof(line), " %d: '%c' x=%f flags=%03x glyph=%d\n", char_index, *iter_char, _characters[char_index].x, *(unsigned*)&_characters[char_index].char_attributes, _characters[char_index].in_glyph);
+ snprintf(line, sizeof(line), " %d: '%c' x=%f flags=%03x glyph=%d\n", char_index, *iter_char, _characters[char_index].x, *(unsigned*) &_characters[char_index].char_attributes, _characters[char_index].in_glyph);
iter_char++;
}
result += line;
diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h
index 25f80e9e9..a8852ed8a 100644
--- a/src/libnrtype/Layout-TNG.h
+++ b/src/libnrtype/Layout-TNG.h
@@ -328,7 +328,7 @@ public:
\param in_arena The arena to add the glyphs group to
\param paintbox The current rendering tile
*/
- void show(DrawingGroup *in_arena, NRRect const *paintbox) const;
+ void show(DrawingGroup *in_arena, Geom::OptRect const &paintbox) const;
/** Calculates the smallest rectangle completely enclosing all the
glyphs.
@@ -336,7 +336,7 @@ public:
\param transform The transform to be applied to the entire object
prior to calculating its bounds.
*/
- void getBoundingBox(NRRect *bounding_box, Geom::Affine const &transform, int start = -1, int length = -1) const;
+ Geom::OptRect bounds(Geom::Affine const &transform, int start = -1, int length = -1) const;
/** Sends all the glyphs to the given print context.
\param ctx I have
@@ -345,7 +345,7 @@ public:
\param bbox parameters
\param ctm do yet
*/
- void print(SPPrintContext *ctx, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox, Geom::Affine const &ctm) const;
+ void print(SPPrintContext *ctx, Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox, Geom::Affine const &ctm) const;
#ifdef HAVE_CAIRO_PDF
/** Renders all the glyphs to the given Cairo rendering context.
diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp
index 96d465569..8b5badf5f 100644
--- a/src/live_effects/lpe-extrude.cpp
+++ b/src/live_effects/lpe-extrude.cpp
@@ -174,10 +174,10 @@ LPEExtrude::resetDefaults(SPItem * item)
using namespace Geom;
- Geom::OptRect bbox = item->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = item->geometricBounds();
if (bbox) {
- Interval boundingbox_X = (*bbox)[Geom::X];
- Interval boundingbox_Y = (*bbox)[Geom::Y];
+ Interval const &boundingbox_X = (*bbox)[Geom::X];
+ Interval const &boundingbox_Y = (*bbox)[Geom::Y];
extrude_vector.set_and_write_new_values( Geom::Point(boundingbox_X.middle(), boundingbox_Y.middle()),
(boundingbox_X.extent() + boundingbox_Y.extent())*Geom::Point(-0.05,0.2) );
}
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp
index 02d24752b..2d043ca91 100644
--- a/src/live_effects/lpe-mirror_symmetry.cpp
+++ b/src/live_effects/lpe-mirror_symmetry.cpp
@@ -45,8 +45,10 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem *lpeitem)
{
using namespace Geom;
+ // fixme: what happens if the bbox is empty?
+ // fixme: this is probably wrong
Geom::Affine t = lpeitem->i2dt_affine();
- Geom::Rect bbox = *lpeitem->getBounds(t); // fixme: what happens if getBounds does not return a valid rect?
+ Geom::Rect bbox = *lpeitem->desktopVisualBounds();
Point A(bbox.left(), bbox.bottom());
Point B(bbox.left(), bbox.top());
diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp
index 671d88a8b..87e3dbe5c 100644
--- a/src/live_effects/lpe-rough-hatches.cpp
+++ b/src/live_effects/lpe-rough-hatches.cpp
@@ -557,7 +557,7 @@ LPERoughHatches::resetDefaults(SPItem * item)
{
Effect::resetDefaults(item);
- Geom::OptRect bbox = item->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = item->geometricBounds();
Geom::Point origin(0.,0.);
Geom::Point vector(50.,0.);
if (bbox) {
diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp
index 382231378..c241b9a4c 100644
--- a/src/live_effects/lpegroupbbox.cpp
+++ b/src/live_effects/lpegroupbbox.cpp
@@ -34,7 +34,7 @@ GroupBBoxEffect::original_bbox(SPLPEItem *lpeitem, bool absolute)
transform = Geom::identity();
}
- Geom::OptRect bbox = lpeitem->getBounds(transform, SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = lpeitem->geometricBounds(transform);
if (bbox) {
boundingbox_X = (*bbox)[Geom::X];
boundingbox_Y = (*bbox)[Geom::Y];
diff --git a/src/main.cpp b/src/main.cpp
index ace99f519..501a3e5d2 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1195,8 +1195,8 @@ do_query_dimension (SPDocument *doc, bool extent, Geom::Dim2 const axis, const g
doc->ensureUpToDate();
SPItem *item = ((SPItem *) o);
- // "true" SVG bbox for scripting
- Geom::OptRect area = item->getBounds(item->i2doc_affine());
+ // visual bbox in document coords for scripting
+ Geom::OptRect area = item->documentVisualBounds();
if (area) {
Inkscape::SVGOStringStream os;
if (extent) {
@@ -1226,7 +1226,7 @@ do_query_all_recurse (SPObject *o)
{
SPItem *item = ((SPItem *) o);
if (o->getId() && SP_IS_ITEM(item)) {
- Geom::OptRect area = item->getBounds(item->i2doc_affine());
+ Geom::OptRect area = item->documentVisualBounds();
if (area) {
Inkscape::SVGOStringStream os;
os << o->getId();
@@ -1320,8 +1320,7 @@ sp_do_export_png(SPDocument *doc)
// write object bbox to area
doc->ensureUpToDate();
- Geom::OptRect areaMaybe;
- static_cast<SPItem *>(o_area)->invoke_bbox( areaMaybe, static_cast<SPItem *>(o_area)->i2dt_affine(), TRUE);
+ Geom::OptRect areaMaybe = static_cast<SPItem *>(o_area)->desktopVisualBounds();
if (areaMaybe) {
area = *areaMaybe;
} else {
diff --git a/src/marker.cpp b/src/marker.cpp
index c8fa9218d..9db5cfdc1 100644
--- a/src/marker.cpp
+++ b/src/marker.cpp
@@ -45,7 +45,7 @@ static Inkscape::XML::Node *sp_marker_write (SPObject *object, Inkscape::XML::Do
static Inkscape::DrawingItem *sp_marker_private_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
static void sp_marker_private_hide (SPItem *item, unsigned int key);
-static void sp_marker_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_marker_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static void sp_marker_print (SPItem *item, SPPrintContext *ctx);
static void sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems);
@@ -541,10 +541,11 @@ sp_marker_private_hide (SPItem */*item*/, unsigned int /*key*/)
/**
* This routine is disabled to break propagation.
*/
-static void
-sp_marker_bbox(SPItem const *, NRRect *, Geom::Affine const &, unsigned const)
+static Geom::OptRect
+sp_marker_bbox(SPItem const *, Geom::Affine const &, SPItem::BBoxType)
{
- /* Break propagation */
+ /* Break propagation */
+ return Geom::OptRect();
}
/**
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index fd8ef0c7c..07d690ce0 100644
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -135,15 +135,14 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent,
if (SP_IS_GROUP(o)) {
_findCandidates(o, it, false, bbox_to_snap, clip_or_mask, additional_affine);
} else {
- Geom::OptRect bbox_of_item = Geom::Rect();
+ Geom::OptRect bbox_of_item;
if (clip_or_mask) {
// Oh oh, this will get ugly. We cannot use sp_item_i2d_affine directly because we need to
// insert an additional transformation in document coordinates (code copied from sp_item_i2d_affine)
- item->invoke_bbox(bbox_of_item,
- item->i2doc_affine() * additional_affine * _snapmanager->getDesktop()->doc2dt(),
- true);
+ bbox_of_item = item->visualBounds(item->i2doc_affine() * additional_affine *
+ _snapmanager->getDesktop()->doc2dt());
} else {
- item->invoke_bbox( bbox_of_item, item->i2dt_affine(), true);
+ bbox_of_item = item->desktopVisualBounds();
}
if (bbox_of_item) {
// See if the item is within range
@@ -188,7 +187,7 @@ void Inkscape::ObjectSnapper::_collectNodes(SnapSourceType const &t,
Preferences *prefs = Preferences::get();
bool prefs_bbox = prefs->getBool("/tools/bounding_box");
bbox_type = !prefs_bbox ?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
}
// Consider the page border for snapping to
@@ -255,7 +254,7 @@ void Inkscape::ObjectSnapper::_collectNodes(SnapSourceType const &t,
// Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox
// of the item AND the bbox of the clipping path at the same time
if (!(*i).clip_or_mask) {
- Geom::OptRect b = root_item->getBboxDesktop(bbox_type);
+ Geom::OptRect b = root_item->desktopBounds(bbox_type);
getBBoxPoints(b, _points_to_snap_to, true,
_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_BBOX_CORNER),
_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_BBOX_EDGE_MIDPOINT),
@@ -370,7 +369,7 @@ void Inkscape::ObjectSnapper::_collectPaths(Geom::Point /*p*/,
Preferences *prefs = Preferences::get();
int prefs_bbox = prefs->getBool("/tools/bounding_box", 0);
bbox_type = !prefs_bbox ?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
}
// Consider the page border for snapping
@@ -449,11 +448,10 @@ void Inkscape::ObjectSnapper::_collectPaths(Geom::Point /*p*/,
// Discard the bbox of a clipped path / mask, because we don't want to snap to both the bbox
// of the item AND the bbox of the clipping path at the same time
if (!(*i).clip_or_mask) {
- Geom::OptRect rect;
- root_item->invoke_bbox( rect, i2doc, TRUE, bbox_type);
+ Geom::OptRect rect = root_item->bounds(bbox_type, i2doc);
if (rect) {
Geom::PathVector *path = _getPathvFromRect(*rect);
- rect = root_item->getBboxDesktop(bbox_type);
+ rect = root_item->desktopBounds(bbox_type);
_paths_to_snap_to->push_back(SnapCandidatePath(path, SNAPTARGET_BBOX_EDGE, rect));
}
}
diff --git a/src/print.cpp b/src/print.cpp
index 2eadf0fa9..3e477c976 100644
--- a/src/print.cpp
+++ b/src/print.cpp
@@ -56,16 +56,18 @@ sp_print_comment(SPPrintContext *ctx, char const *comment)
unsigned int
sp_print_fill(SPPrintContext *ctx, Geom::PathVector const &pathv, Geom::Affine const *ctm, SPStyle const *style,
- NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
+ Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox)
{
- return ctx->module->fill(pathv, ctm, style, pbox, dbox, bbox);
+ NRRect nrpbox(pbox), nrdbox(dbox), nrbbox(bbox);
+ return ctx->module->fill(pathv, ctm, style, &nrpbox, &nrdbox, &nrbbox);
}
unsigned int
sp_print_stroke(SPPrintContext *ctx, Geom::PathVector const &pathv, Geom::Affine const *ctm, SPStyle const *style,
- NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
+ Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox)
{
- return ctx->module->stroke(pathv, ctm, style, pbox, dbox, bbox);
+ NRRect nrpbox(pbox), nrdbox(dbox), nrbbox(bbox);
+ return ctx->module->stroke(pathv, ctm, style, &nrpbox, &nrdbox, &nrbbox);
}
unsigned int
diff --git a/src/print.h b/src/print.h
index 6bdbe4b82..34c85d901 100644
--- a/src/print.h
+++ b/src/print.h
@@ -27,9 +27,9 @@ unsigned int sp_print_bind(SPPrintContext *ctx, Geom::Affine const *transform, f
unsigned int sp_print_release(SPPrintContext *ctx);
unsigned int sp_print_comment(SPPrintContext *ctx, char const *comment);
unsigned int sp_print_fill(SPPrintContext *ctx, Geom::PathVector const &pathv, Geom::Affine const *ctm, SPStyle const *style,
- NRRect const *pbox, NRRect const *dbox, NRRect const *bbox);
+ Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox);
unsigned int sp_print_stroke(SPPrintContext *ctx, Geom::PathVector const &pathv, Geom::Affine const *transform, SPStyle const *style,
- NRRect const *pbox, NRRect const *dbox, NRRect const *bbox);
+ Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox);
unsigned int sp_print_image_R8G8B8A8_N(SPPrintContext *ctx,
guchar *px, unsigned int w, unsigned int h, unsigned int rs,
diff --git a/src/removeoverlap.cpp b/src/removeoverlap.cpp
index a503fea35..6dd8d6a79 100644
--- a/src/removeoverlap.cpp
+++ b/src/removeoverlap.cpp
@@ -50,7 +50,7 @@ void removeoverlap(GSList const *const items, double const xGap, double const yG
++it)
{
using Geom::X; using Geom::Y;
- Geom::OptRect item_box((*it)->getBboxDesktop());
+ Geom::OptRect item_box((*it)->desktopVisualBounds());
if (item_box) {
Geom::Point min(item_box->min() - .5*gap);
Geom::Point max(item_box->max() + .5*gap);
diff --git a/src/selcue.cpp b/src/selcue.cpp
index c647c1f96..dbcaf4cc3 100644
--- a/src/selcue.cpp
+++ b/src/selcue.cpp
@@ -68,8 +68,6 @@ void Inkscape::SelCue::_updateItemBboxes()
g_return_if_fail(_selection != NULL);
int prefs_bbox = prefs->getBool("/tools/bounding_box");
- SPItem::BBoxType bbox_type = !prefs_bbox ?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
GSList const *items = _selection->itemList();
if (_item_bboxes.size() != g_slist_length((GSList *) items)) {
@@ -83,7 +81,8 @@ void Inkscape::SelCue::_updateItemBboxes()
SPCanvasItem* box = _item_bboxes[bcount ++];
if (box) {
- Geom::OptRect const b = item->getBboxDesktop(bbox_type);
+ Geom::OptRect const b = (prefs_bbox == 0) ?
+ item->desktopVisualBounds() : item->desktopGeometricBounds();
if (b) {
sp_canvas_item_show(box);
@@ -118,13 +117,12 @@ void Inkscape::SelCue::_newItemBboxes()
g_return_if_fail(_selection != NULL);
int prefs_bbox = prefs->getBool("/tools/bounding_box");
- SPItem::BBoxType bbox_type = !prefs_bbox ?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) {
SPItem *item = (SPItem *) l->data;
- Geom::OptRect const b = item->getBboxDesktop(bbox_type);
+ Geom::OptRect const b = (prefs_bbox == 0) ?
+ item->desktopVisualBounds() : item->desktopGeometricBounds();
SPCanvasItem* box = NULL;
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 23991bfb6..75745f4af 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -777,7 +777,7 @@ enclose_items(GSList const *items)
Geom::OptRect r;
for (GSList const *i = items; i; i = i->next) {
- r.unionWith(((SPItem *) i->data)->getBboxDesktop());
+ r.unionWith(((SPItem *) i->data)->desktopVisualBounds());
}
return r;
}
@@ -829,7 +829,7 @@ sp_selection_raise(SPDesktop *desktop)
for (SPObject *newref = child->next; newref; newref = newref->next) {
// if the sibling is an item AND overlaps our selection,
if (SP_IS_ITEM(newref)) {
- Geom::OptRect newref_bbox = SP_ITEM(newref)->getBboxDesktop();
+ Geom::OptRect newref_bbox = SP_ITEM(newref)->desktopVisualBounds();
if ( newref_bbox && selected->intersects(*newref_bbox) ) {
// AND if it's not one of our selected objects,
if (!g_slist_find((GSList *) items, newref)) {
@@ -924,7 +924,7 @@ sp_selection_lower(SPDesktop *desktop)
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)) {
- Geom::OptRect ref_bbox = SP_ITEM(newref)->getBboxDesktop();
+ Geom::OptRect ref_bbox = SP_ITEM(newref)->desktopVisualBounds();
if ( ref_bbox && selected->intersects(*ref_bbox) ) {
// AND if it's not one of our selected objects,
if (!g_slist_find((GSList *) items, newref)) {
@@ -1481,7 +1481,7 @@ sp_selection_scale_absolute(Inkscape::Selection *selection,
if (selection->isEmpty())
return;
- Geom::OptRect const bbox(selection->bounds());
+ Geom::OptRect bbox = selection->visualBounds();
if ( !bbox ) {
return;
}
@@ -1503,7 +1503,7 @@ void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point con
if (selection->isEmpty())
return;
- Geom::OptRect const bbox(selection->bounds());
+ Geom::OptRect bbox = selection->visualBounds();
if ( !bbox ) {
return;
@@ -1621,7 +1621,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle)
if (selection->isEmpty())
return;
- Geom::OptRect const bbox(selection->bounds());
+ Geom::OptRect bbox = selection->visualBounds();
boost::optional<Geom::Point> center = selection->center();
if ( !bbox || !center ) {
@@ -1650,7 +1650,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow)
if (selection->isEmpty())
return;
- Geom::OptRect const bbox(selection->bounds());
+ Geom::OptRect bbox = selection->visualBounds();
if (!bbox) {
return;
}
@@ -1687,7 +1687,7 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times)
if (selection->isEmpty())
return;
- Geom::OptRect sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->visualBounds();
if (!sel_bbox) {
return;
@@ -2014,7 +2014,7 @@ SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root,
void scroll_to_show_item(SPDesktop *desktop, SPItem *item)
{
Geom::Rect dbox = desktop->get_display_area();
- Geom::OptRect sbox = item->getBboxDesktop();
+ Geom::OptRect sbox = item->desktopVisualBounds();
if ( sbox && dbox.contains(*sbox) == false ) {
Geom::Point const s_dt = sbox->midpoint();
@@ -2248,8 +2248,8 @@ sp_select_clone_original(SPDesktop *desktop)
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
bool highlight = prefs->getBool("/options/highlightoriginal/value");
if (highlight) {
- Geom::OptRect a = item->getBounds(item->i2dt_affine());
- Geom::OptRect b = original->getBounds(original->i2dt_affine());
+ Geom::OptRect a = item->desktopVisualBounds();
+ Geom::OptRect b = original->desktopVisualBounds();
if ( a && b ) {
// draw a flashing line between the objects
SPCurve *curve = new SPCurve();
@@ -2291,7 +2291,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply)
}
doc->ensureUpToDate();
- Geom::OptRect r = selection->bounds(SPItem::RENDERING_BBOX);
+ Geom::OptRect r = selection->visualBounds();
boost::optional<Geom::Point> c = selection->center();
if ( !r || !c ) {
return;
@@ -2322,7 +2322,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply)
repr_copies = g_slist_prepend(repr_copies, dup);
}
- Geom::Rect bounds(desktop->dt2doc(r->min()), desktop->dt2doc(r->max()));
+ Geom::Rect bbox(desktop->dt2doc(r->min()), desktop->dt2doc(r->max()));
if (apply) {
// delete objects so that their clones don't get alerted; this object will be restored shortly
@@ -2339,7 +2339,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply)
int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
- gchar const *mark_id = generate_marker(repr_copies, bounds, doc,
+ gchar const *mark_id = generate_marker(repr_copies, bbox, doc,
( Geom::Affine(Geom::Translate(desktop->dt2doc(
Geom::Point(r->min()[Geom::X],
r->max()[Geom::Y]))))
@@ -2416,7 +2416,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
}
doc->ensureUpToDate();
- Geom::OptRect r = selection->bounds(SPItem::RENDERING_BBOX);
+ Geom::OptRect r = selection->visualBounds();
if ( !r ) {
return;
}
@@ -2447,7 +2447,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
// restore the z-order after prepends
repr_copies = g_slist_reverse(repr_copies);
- Geom::Rect bounds(desktop->dt2doc(r->min()), desktop->dt2doc(r->max()));
+ Geom::Rect bbox(desktop->dt2doc(r->min()), desktop->dt2doc(r->max()));
if (apply) {
// delete objects so that their clones don't get alerted; this object will be restored shortly
@@ -2464,7 +2464,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
- gchar const *pat_id = pattern_tile(repr_copies, bounds, doc,
+ gchar const *pat_id = pattern_tile(repr_copies, bbox, doc,
( Geom::Affine(Geom::Translate(desktop->dt2doc(Geom::Point(r->min()[Geom::X],
r->max()[Geom::Y]))))
* parent_transform.inverse() ),
@@ -2477,8 +2477,8 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
Inkscape::XML::Node *rect = xml_doc->createElement("svg:rect");
rect->setAttribute("style", g_strdup_printf("stroke:none;fill:url(#%s)", pat_id));
- Geom::Point min = bounds.min() * parent_transform.inverse();
- Geom::Point max = bounds.max() * parent_transform.inverse();
+ Geom::Point min = bbox.min() * parent_transform.inverse();
+ Geom::Point max = bbox.max() * parent_transform.inverse();
sp_repr_set_svg_double(rect, "width", max[Geom::X] - min[Geom::X]);
sp_repr_set_svg_double(rect, "height", max[Geom::Y] - min[Geom::Y]);
@@ -2663,7 +2663,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop)
// Get the bounding box of the selection
document->ensureUpToDate();
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (!bbox) {
desktop->clearWaitingCursor();
return; // exceptional situation, so not bother with a translatable error message, just quit quietly
@@ -3200,7 +3200,7 @@ fit_canvas_to_selection(SPDesktop *desktop, bool with_margins)
desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to fit canvas to."));
return false;
}
- Geom::OptRect const bbox(desktop->selection->bounds(SPItem::RENDERING_BBOX));
+ Geom::OptRect const bbox(desktop->selection->visualBounds());
if (bbox) {
doc->fitToRect(*bbox, with_margins);
return true;
@@ -3232,7 +3232,7 @@ fit_canvas_to_drawing(SPDocument *doc, bool with_margins)
doc->ensureUpToDate();
SPItem const *const root = doc->getRoot();
- Geom::OptRect const bbox(root->getBounds(root->i2dt_affine(), SPItem::RENDERING_BBOX));
+ Geom::OptRect bbox = root->desktopVisualBounds();
if (bbox) {
doc->fitToRect(*bbox, with_margins);
return true;
diff --git a/src/selection.cpp b/src/selection.cpp
index 677e57d5f..92b35bce7 100644
--- a/src/selection.cpp
+++ b/src/selection.cpp
@@ -362,50 +362,48 @@ Inkscape::XML::Node *Selection::singleRepr() {
return obj ? obj->getRepr() : NULL;
}
-NRRect *Selection::bounds(NRRect *bbox, SPItem::BBoxType type) const
+Geom::OptRect Selection::bounds(SPItem::BBoxType type) const
{
- g_return_val_if_fail (bbox != NULL, NULL);
- *bbox = NRRect(bounds(type));
- return bbox;
+ return (type == SPItem::GEOMETRIC_BBOX) ?
+ geometricBounds() : visualBounds();
}
-Geom::OptRect Selection::bounds(SPItem::BBoxType type) const
+Geom::OptRect Selection::geometricBounds() const
{
GSList const *items = const_cast<Selection *>(this)->itemList();
Geom::OptRect bbox;
for ( GSList const *i = items ; i != NULL ; i = i->next ) {
- bbox.unionWith(SP_ITEM(i->data)->getBboxDesktop(type));
+ bbox.unionWith(SP_ITEM(i->data)->desktopGeometricBounds());
}
return bbox;
}
-NRRect *Selection::boundsInDocument(NRRect *bbox, SPItem::BBoxType type) const {
- g_return_val_if_fail (bbox != NULL, NULL);
+Geom::OptRect Selection::visualBounds() const
+{
+ GSList const *items = const_cast<Selection *>(this)->itemList();
- GSList const *items=const_cast<Selection *>(this)->itemList();
- if (!items) {
- bbox->x0 = bbox->y0 = bbox->x1 = bbox->y1 = 0.0;
- return bbox;
+ Geom::OptRect bbox;
+ for ( GSList const *i = items ; i != NULL ; i = i->next ) {
+ bbox.unionWith(SP_ITEM(i->data)->desktopVisualBounds());
}
+ return bbox;
+}
- bbox->x0 = bbox->y0 = 1e18;
- bbox->x1 = bbox->y1 = -1e18;
+Geom::OptRect Selection::documentBounds(SPItem::BBoxType type) const
+{
+ Geom::OptRect bbox;
+ GSList const *items = const_cast<Selection *>(this)->itemList();
+ if (!items) return bbox;
for ( GSList const *iter=items ; iter != NULL ; iter = iter->next ) {
- SPItem *item=SP_ITEM(iter->data);
- Geom::Affine i2doc(item->i2doc_affine());
- item->invoke_bbox( bbox, i2doc, FALSE, type);
+ SPItem *item = SP_ITEM(iter->data);
+ bbox |= item->documentBounds(type);
}
return bbox;
}
-Geom::OptRect Selection::boundsInDocument(SPItem::BBoxType type) const {
- NRRect r;
- return to_2geom(boundsInDocument(&r, type));
-}
-
/** Extract the position of the center from the first selected object */
// If we have a selection of multiple items, then the center of the first item
// will be returned; this is also the case in SelTrans::centerRequest()
@@ -418,9 +416,9 @@ boost::optional<Geom::Point> Selection::center() const {
return first->getCenter();
}
}
- Geom::OptRect bbox = bounds();
+ Geom::OptRect bbox = visualBounds();
if (bbox) {
- return bounds()->midpoint();
+ return bbox->midpoint();
} else {
return boost::optional<Geom::Point>();
}
diff --git a/src/selection.h b/src/selection.h
index 00572a1c5..af0facc3d 100644
--- a/src/selection.h
+++ b/src/selection.h
@@ -244,25 +244,12 @@ public:
guint numberOfParents();
/** @brief Returns the bounding rectangle of the selection */
- NRRect *bounds(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
- /** @brief Returns the bounding rectangle of the selection */
- Geom::OptRect bounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
-
- /**
- * @brief Returns the bounding rectangle of the selection
- *
- * Gives the coordinates in internal format, does not match onscreen guides.
- * (0,0 is the upper left corner, not the lower left corner)
- */
- NRRect *boundsInDocument(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
+ Geom::OptRect bounds(SPItem::BBoxType type) const;
+ Geom::OptRect visualBounds() const;
+ Geom::OptRect geometricBounds() const;
- /**
- * @brief Returns the bounding rectangle of the selection
- *
- * Gives the coordinates in internal format, does not match onscreen guides.
- * (0,0 is the upper left corner, not the lower left corner)
- */
- Geom::OptRect boundsInDocument(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
+ /// Returns the bounding rectangle of the selectionin document coordinates.
+ Geom::OptRect documentBounds(SPItem::BBoxType type) const;
/**
* @brief Returns the rotation/skew center of the selection
diff --git a/src/seltrans.cpp b/src/seltrans.cpp
index 3a204a49e..0e5e533fc 100644
--- a/src/seltrans.cpp
+++ b/src/seltrans.cpp
@@ -90,7 +90,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) :
_grabbed(false),
_show_handles(true),
_bbox(),
- _approximate_bbox(),
+ _visual_bbox(),
_absolute_affine(Geom::Scale(1,1)),
_opposite(Geom::Point(0,0)),
_opposite_for_specpoints(Geom::Point(0,0)),
@@ -104,7 +104,7 @@ Inkscape::SelTrans::SelTrans(SPDesktop *desktop) :
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int prefs_bbox = prefs->getBool("/tools/bounding_box");
_snap_bbox_type = !prefs_bbox ?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
g_return_if_fail(desktop != NULL);
@@ -279,8 +279,8 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
// First, determine the bounding box
_bbox = selection->bounds(_snap_bbox_type);
- _approximate_bbox = selection->bounds(SPItem::APPROXIMATE_BBOX); // Used for correctly scaling the strokewidth
- _geometric_bbox = selection->bounds(SPItem::GEOMETRIC_BBOX);
+ _visual_bbox = selection->visualBounds(); // Used for correctly scaling the strokewidth
+ _geometric_bbox = selection->geometricBounds();
_point = p;
if (_geometric_bbox) {
@@ -336,7 +336,8 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s
// More than 50 items will produce at least 200 bbox points, which might make Inkscape crawl
// (see the comment a few lines above). In that case we will use the bbox of the selection as a whole
for (unsigned i = 0; i < _items.size(); i++) {
- getBBoxPoints(_items[i]->getBboxDesktop(_snap_bbox_type), &_bbox_points_for_translating, false, c, emp, mp);
+ Geom::OptRect b = _items[i]->desktopBounds(_snap_bbox_type);
+ getBBoxPoints(b, &_bbox_points_for_translating, false, c, emp, mp);
}
} else {
_bbox_points_for_translating = _bbox_points; // use the bbox points of the selection as a whole
@@ -696,7 +697,7 @@ void Inkscape::SelTrans::_updateVolatileState()
//Update the bboxes
_bbox = selection->bounds(_snap_bbox_type);
- _approximate_bbox = selection->bounds(SPItem::APPROXIMATE_BBOX);
+ _visual_bbox = selection->visualBounds();
if (!_bbox) {
_empty = true;
@@ -898,8 +899,7 @@ void Inkscape::SelTrans::_selChanged(Inkscape::Selection */*selection*/)
// reread in case it changed on the fly:
int prefs_bbox = prefs->getBool("/tools/bounding_box");
_snap_bbox_type = !prefs_bbox ?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
- //SPItem::APPROXIMATE_BBOX will be replaced by SPItem::VISUAL_BBOX, as soon as the latter is implemented properly
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
_updateVolatileState();
_current_relative_affine.setIdentity();
@@ -1602,8 +1602,8 @@ Geom::Scale Inkscape::calcScaleFactors(Geom::Point const &initial_point, Geom::P
Geom::Point Inkscape::SelTrans::_calcAbsAffineDefault(Geom::Scale const default_scale)
{
Geom::Affine abs_affine = Geom::Translate(-_origin) * Geom::Affine(default_scale) * Geom::Translate(_origin);
- Geom::Point new_bbox_min = _approximate_bbox->min() * abs_affine;
- Geom::Point new_bbox_max = _approximate_bbox->max() * abs_affine;
+ Geom::Point new_bbox_min = _visual_bbox->min() * abs_affine;
+ Geom::Point new_bbox_max = _visual_bbox->max() * abs_affine;
bool transform_stroke = false;
gdouble strokewidth = 0;
@@ -1614,7 +1614,7 @@ Geom::Point Inkscape::SelTrans::_calcAbsAffineDefault(Geom::Scale const default_
strokewidth = _strokewidth;
}
- _absolute_affine = get_scale_transform_with_uniform_stroke (*_approximate_bbox, strokewidth, transform_stroke,
+ _absolute_affine = get_scale_transform_with_uniform_stroke (*_visual_bbox, strokewidth, transform_stroke,
new_bbox_min[Geom::X], new_bbox_min[Geom::Y], new_bbox_max[Geom::X], new_bbox_max[Geom::Y]);
// return the new handle position
diff --git a/src/seltrans.h b/src/seltrans.h
index dd890ee9b..9d14fda26 100644
--- a/src/seltrans.h
+++ b/src/seltrans.h
@@ -136,7 +136,7 @@ private:
SPItem::BBoxType _snap_bbox_type;
Geom::OptRect _bbox;
- Geom::OptRect _approximate_bbox;
+ Geom::OptRect _visual_bbox;
Geom::OptRect _geometric_bbox;
gdouble _strokewidth;
diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp
index 0b3320e59..2213443a5 100644
--- a/src/sp-clippath.cpp
+++ b/src/sp-clippath.cpp
@@ -34,7 +34,7 @@ struct SPClipPathView {
SPClipPathView *next;
unsigned int key;
Inkscape::DrawingItem *arenaitem;
- NRRect bbox;
+ Geom::OptRect bbox;
};
SPClipPathView *sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, Inkscape::DrawingItem *arenaitem);
@@ -193,10 +193,9 @@ void SPClipPath::update(SPObject *object, SPCtx *ctx, guint flags)
SPClipPath *cp = SP_CLIPPATH(object);
for (SPClipPathView *v = cp->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
- if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) {
- Geom::Affine t(Geom::Scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0));
- t[4] = v->bbox.x0;
- t[5] = v->bbox.y0;
+ if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX && v->bbox) {
+ Geom::Affine t = Geom::Scale(v->bbox->dimensions());
+ t.setTranslation(v->bbox->min());
g->setChildTransform(t);
} else {
g->setChildTransform(Geom::identity());
@@ -257,10 +256,9 @@ Inkscape::DrawingItem *SPClipPath::show(Inkscape::Drawing &drawing, unsigned int
}
}
- if (clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) {
- Geom::Affine t(Geom::Scale(display->bbox.x1 - display->bbox.x0, display->bbox.y1 - display->bbox.y0));
- t[4] = display->bbox.x0;
- t[5] = display->bbox.y0;
+ if (clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX && display->bbox) {
+ Geom::Affine t = Geom::Scale(display->bbox->dimensions());
+ t.setTranslation(display->bbox->min());
ai->setChildTransform(t);
}
ai->setStyle(this->style);
@@ -287,42 +285,26 @@ void SPClipPath::hide(unsigned int key)
g_assert_not_reached();
}
-void SPClipPath::setBBox(unsigned int key, NRRect *bbox)
+void SPClipPath::setBBox(unsigned int key, Geom::OptRect const &bbox)
{
for (SPClipPathView *v = display; v != NULL; v = v->next) {
if (v->key == key) {
- if (!Geom::are_near(v->bbox.x0, bbox->x0) ||
- !Geom::are_near(v->bbox.y0, bbox->y0) ||
- !Geom::are_near(v->bbox.x1, bbox->x1) ||
- !Geom::are_near(v->bbox.y1, bbox->y1)) {
- v->bbox = *bbox;
- }
+ v->bbox = bbox;
break;
}
}
}
-void SPClipPath::getBBox(NRRect *bbox, Geom::Affine const &transform, unsigned const /*flags*/)
+Geom::OptRect SPClipPath::geometricBounds(Geom::Affine const &transform)
{
SPObject *i = 0;
- for (i = firstChild(); i && !SP_IS_ITEM(i); i = i->getNext()) {
- }
- if (!i) {
- return;
- }
-
- SP_ITEM(i)->invoke_bbox_full( bbox, Geom::Affine(SP_ITEM(i)->transform) * transform, SPItem::GEOMETRIC_BBOX, FALSE);
- SPObject *i_start = i;
-
- while (i != NULL) {
- if (i != i_start) {
- NRRect i_box;
- SP_ITEM(i)->invoke_bbox_full( &i_box, Geom::Affine(SP_ITEM(i)->transform) * transform, SPItem::GEOMETRIC_BBOX, FALSE);
- nr_rect_d_union (bbox, bbox, &i_box);
- }
- i = i->getNext();
- for (; i && !SP_IS_ITEM(i); i = i->getNext()){};
+ Geom::OptRect bbox;
+ for (i = firstChild(); i; i = i->getNext()) {
+ if (!SP_IS_ITEM(i)) continue;
+ Geom::OptRect tmp = SP_ITEM(i)->geometricBounds(Geom::Affine(SP_ITEM(i)->transform) * transform);
+ bbox.unionWith(tmp);
}
+ return bbox;
}
/* ClipPath views */
@@ -335,8 +317,7 @@ sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, Inkscape::D
new_path_view->next = list;
new_path_view->key = key;
new_path_view->arenaitem = arenaitem;
- new_path_view->bbox.x0 = new_path_view->bbox.x1 = 0.0;
- new_path_view->bbox.y0 = new_path_view->bbox.y1 = 0.0;
+ new_path_view->bbox = Geom::OptRect();
return new_path_view;
}
diff --git a/src/sp-clippath.h b/src/sp-clippath.h
index 11817eb77..c151851d3 100644
--- a/src/sp-clippath.h
+++ b/src/sp-clippath.h
@@ -43,8 +43,8 @@ public:
Inkscape::DrawingItem *show(Inkscape::Drawing &drawing, unsigned int key);
void hide(unsigned int key);
- void setBBox(unsigned int key, NRRect *bbox);
- void getBBox(NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+ void setBBox(unsigned int key, Geom::OptRect const &bbox);
+ Geom::OptRect geometricBounds(Geom::Affine const &transform);
private:
static void init(SPClipPath *clippath);
diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp
index ea8079bba..bd73a65c9 100644
--- a/src/sp-flowtext.cpp
+++ b/src/sp-flowtext.cpp
@@ -46,7 +46,7 @@ static Inkscape::XML::Node *sp_flowtext_write(SPObject *object, Inkscape::XML::D
static void sp_flowtext_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
static void sp_flowtext_set(SPObject *object, unsigned key, gchar const *value);
-static void sp_flowtext_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_flowtext_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static void sp_flowtext_print(SPItem *item, SPPrintContext *ctx);
static gchar *sp_flowtext_description(SPItem *item);
static void sp_flowtext_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
@@ -176,20 +176,19 @@ static void sp_flowtext_update(SPObject *object, SPCtx *ctx, unsigned flags)
group->rebuildLayout();
- NRRect paintbox;
- group->invoke_bbox( &paintbox, Geom::identity(), TRUE);
+ Geom::OptRect pbox = group->geometricBounds();
for (SPItemView *v = group->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
group->_clearFlow(g);
g->setStyle(object->style);
// pass the bbox of the flowtext object as paintbox (used for paintserver fills)
- group->layout.show(g, &paintbox);
+ group->layout.show(g, pbox);
}
}
static void sp_flowtext_modified(SPObject *object, guint flags)
{
- SPObject *ft = SP_FLOWTEXT (object);
+ SPObject *ft = object;
SPObject *region = NULL;
if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
@@ -198,13 +197,12 @@ static void sp_flowtext_modified(SPObject *object, guint flags)
// FIXME: the below stanza is copied over from sp_text_modified, consider factoring it out
if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) {
SPFlowtext *text = SP_FLOWTEXT(object);
- NRRect paintbox;
- text->invoke_bbox( &paintbox, Geom::identity(), TRUE);
+ Geom::OptRect pbox = text->geometricBounds();
for (SPItemView* v = text->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
text->_clearFlow(g);
g->setStyle(object->style);
- text->layout.show(g, &paintbox);
+ text->layout.show(g, pbox);
}
}
@@ -329,53 +327,33 @@ static Inkscape::XML::Node *sp_flowtext_write(SPObject *object, Inkscape::XML::D
return repr;
}
-static void
-sp_flowtext_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const /*flags*/)
+static Geom::OptRect
+sp_flowtext_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
{
SPFlowtext *group = SP_FLOWTEXT(item);
- group->layout.getBoundingBox(bbox, transform);
+ Geom::OptRect bbox = group->layout.bounds(transform);
// Add stroke width
- SPStyle* style = item->style;
- if ( !style->stroke.isNone() ) {
- double const scale = transform.descrim();
- if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord
- double const width = MAX(0.125, style->stroke_width.computed * scale);
- if ( fabs(bbox->x1 - bbox->x0) > -0.00001 && fabs(bbox->y1 - bbox->y0) > -0.00001 ) {
- bbox->x0-=0.5*width;
- bbox->x1+=0.5*width;
- bbox->y0-=0.5*width;
- bbox->y1+=0.5*width;
- }
- }
+ // FIXME this code is incorrect
+ if (type == SPItem::VISUAL_BBOX && !item->style->stroke.isNone()) {
+ double scale = transform.descrim();
+ bbox->expandBy(0.5 * item->style->stroke_width.computed * scale);
}
+ return bbox;
}
static void
sp_flowtext_print(SPItem *item, SPPrintContext *ctx)
{
SPFlowtext *group = SP_FLOWTEXT(item);
+ Geom::OptRect pbox, bbox, dbox;
- NRRect pbox;
- item->invoke_bbox( &pbox, Geom::identity(), TRUE);
- NRRect bbox;
- Geom::OptRect bbox_maybe = item->getBboxDesktop();
- if (!bbox_maybe) {
- return;
- }
- bbox.x0 = bbox_maybe->min()[Geom::X];
- bbox.y0 = bbox_maybe->min()[Geom::Y];
- bbox.x1 = bbox_maybe->max()[Geom::X];
- bbox.y1 = bbox_maybe->max()[Geom::Y];
-
- NRRect dbox;
- dbox.x0 = 0.0;
- dbox.y0 = 0.0;
- dbox.x1 = item->document->getWidth();
- dbox.y1 = item->document->getHeight();
+ pbox = item->geometricBounds();
+ bbox = item->desktopVisualBounds();
+ dbox = Geom::Rect::from_xywh(Geom::Point(0,0), item->document->getDimensions());
Geom::Affine const ctm (item->i2dt_affine());
- group->layout.print(ctx, &pbox, &dbox, &bbox, ctm);
+ group->layout.print(ctx, pbox, dbox, bbox, ctm);
}
@@ -417,9 +395,8 @@ sp_flowtext_show(SPItem *item, Inkscape::Drawing &drawing, unsigned/* key*/, uns
flowed->setStyle(group->style);
// pass the bbox of the flowtext object as paintbox (used for paintserver fills)
- NRRect paintbox;
- item->invoke_bbox( &paintbox, Geom::identity(), TRUE);
- group->layout.show(flowed, &paintbox);
+ Geom::OptRect bbox = group->geometricBounds();
+ group->layout.show(flowed, bbox);
return flowed;
}
diff --git a/src/sp-image.cpp b/src/sp-image.cpp
index 5f398b10e..3ae2b6e63 100644
--- a/src/sp-image.cpp
+++ b/src/sp-image.cpp
@@ -80,7 +80,7 @@ static void sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags);
static void sp_image_modified (SPObject *object, unsigned int flags);
static Inkscape::XML::Node *sp_image_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
-static void sp_image_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_image_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static void sp_image_print (SPItem * item, SPPrintContext *ctx);
static gchar * sp_image_description (SPItem * item);
static void sp_image_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
@@ -1062,21 +1062,16 @@ static Inkscape::XML::Node *sp_image_write( SPObject *object, Inkscape::XML::Doc
return repr;
}
-static void sp_image_bbox( SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const /*flags*/ )
+static Geom::OptRect sp_image_bbox( SPItem const *item,Geom::Affine const &transform, SPItem::BBoxType type )
{
SPImage const &image = *SP_IMAGE(item);
+ Geom::OptRect bbox;
if ((image.width.computed > 0.0) && (image.height.computed > 0.0)) {
- double const x0 = image.x.computed;
- double const y0 = image.y.computed;
- double const x1 = x0 + image.width.computed;
- double const y1 = y0 + image.height.computed;
-
- nr_rect_union_pt(bbox, Geom::Point(x0, y0) * transform);
- nr_rect_union_pt(bbox, Geom::Point(x1, y0) * transform);
- nr_rect_union_pt(bbox, Geom::Point(x1, y1) * transform);
- nr_rect_union_pt(bbox, Geom::Point(x0, y1) * transform);
+ bbox = Geom::Rect::from_xywh(image.x.computed, image.y.computed, image.width.computed, image.height.computed);
+ *bbox *= transform;
}
+ return bbox;
}
static void sp_image_print( SPItem *item, SPPrintContext *ctx )
@@ -1499,10 +1494,8 @@ static void sp_image_set_curve( SPImage *image )
image->curve = image->curve->unref();
}
} else {
- NRRect rect;
- sp_image_bbox(image, &rect, Geom::identity(), 0);
- Geom::Rect rect2 = *to_2geom(&rect);
- SPCurve *c = SPCurve::new_from_rect(rect2, true);
+ Geom::OptRect rect = sp_image_bbox(image, Geom::identity(), SPItem::VISUAL_BBOX);
+ SPCurve *c = SPCurve::new_from_rect(*rect, true);
if (image->curve) {
image->curve = image->curve->unref();
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index f8ab0460a..ada980b3e 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -65,7 +65,7 @@ static void sp_group_modified (SPObject *object, guint flags);
static Inkscape::XML::Node *sp_group_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static void sp_group_set(SPObject *object, unsigned key, char const *value);
-static void sp_group_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_group_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static void sp_group_print (SPItem * item, SPPrintContext *ctx);
static gchar * sp_group_description (SPItem * item);
static Inkscape::DrawingItem *sp_group_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
@@ -274,10 +274,10 @@ static Inkscape::XML::Node * sp_group_write(SPObject *object, Inkscape::XML::Doc
return repr;
}
-static void
-sp_group_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags)
+static Geom::OptRect
+sp_group_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
{
- SP_GROUP(item)->group->calculateBBox(bbox, transform, flags);
+ return SP_GROUP(item)->group->bounds(type, transform);
}
static void
@@ -696,9 +696,9 @@ void CGroup::onModified(guint flags) {
}
}
-void CGroup::calculateBBox(NRRect *bbox, Geom::Affine const &transform, unsigned const flags) {
-
- Geom::OptRect dummy_bbox;
+Geom::OptRect CGroup::bounds(SPItem::BBoxType type, Geom::Affine const &transform)
+{
+ Geom::OptRect bbox;
GSList *l = _group->childList(false, SPObject::ActionBBox);
while (l) {
@@ -706,12 +706,11 @@ void CGroup::calculateBBox(NRRect *bbox, Geom::Affine const &transform, unsigned
if (SP_IS_ITEM(o) && !SP_ITEM(o)->isHidden()) {
SPItem *child = SP_ITEM(o);
Geom::Affine const ct(child->transform * transform);
- child->invoke_bbox_full( dummy_bbox, ct, flags, FALSE);
+ bbox |= child->bounds(type, transform);
}
l = g_slist_remove (l, o);
}
-
- *bbox = NRRect(dummy_bbox);
+ return bbox;
}
void CGroup::onPrint(SPPrintContext *ctx) {
diff --git a/src/sp-item-group.h b/src/sp-item-group.h
index 99f375e44..f56192925 100644
--- a/src/sp-item-group.h
+++ b/src/sp-item-group.h
@@ -69,7 +69,7 @@ public:
virtual void onChildRemoved(Inkscape::XML::Node *child);
virtual void onUpdate(SPCtx *ctx, unsigned int flags);
virtual void onModified(guint flags);
- virtual void calculateBBox(NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+ virtual Geom::OptRect bounds(SPItem::BBoxType type, Geom::Affine const &transform);
virtual void onPrint(SPPrintContext *ctx);
virtual void onOrderChanged(Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref);
virtual gchar *getDescription();
diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp
index 9f166e718..749a32d52 100644
--- a/src/sp-item-transform.cpp
+++ b/src/sp-item-transform.cpp
@@ -39,7 +39,7 @@ sp_item_rotate_rel(SPItem *item, Geom::Rotate const &rotation)
void
sp_item_scale_rel (SPItem *item, Geom::Scale const &scale)
{
- Geom::OptRect bbox = item->getBboxDesktop();
+ Geom::OptRect bbox = item->desktopVisualBounds();
if (bbox) {
Geom::Translate const s(bbox->midpoint()); // use getCenter?
item->set_i2d_affine(item->i2dt_affine() * s.inverse() * scale * s);
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 07ce73c4b..a2a603c68 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -253,7 +253,7 @@ bool SPItem::isExplicitlyHidden() const
* Sets the display CSS property to `hidden' if \a val is true,
* otherwise makes it unset
*/
-void SPItem::setExplicitlyHidden(bool const val) {
+void SPItem::setExplicitlyHidden(bool val) {
style->display.set = val;
style->display.value = ( val ? SP_CSS_DISPLAY_NONE : SP_CSS_DISPLAY_INLINE );
style->display.computed = style->display.value;
@@ -263,17 +263,17 @@ void SPItem::setExplicitlyHidden(bool const val) {
/**
* Sets the transform_center_x and transform_center_y properties to retain the rotation centre
*/
-void SPItem::setCenter(Geom::Point object_centre) {
- // for getBounds() to work
+void SPItem::setCenter(Geom::Point const &object_centre) {
document->ensureUpToDate();
- Geom::OptRect bbox = getBounds(i2dt_affine());
+ // FIXME this is seriously wrong
+ Geom::OptRect bbox = desktopGeometricBounds();
if (bbox) {
transform_center_x = object_centre[Geom::X] - bbox->midpoint()[Geom::X];
- if (fabs(transform_center_x) < 1e-5) // rounding error
+ if (Geom::are_near(transform_center_x, 0)) // rounding error
transform_center_x = 0;
transform_center_y = object_centre[Geom::Y] - bbox->midpoint()[Geom::Y];
- if (fabs(transform_center_y) < 1e-5) // rounding error
+ if (Geom::are_near(transform_center_y, 0)) // rounding error
transform_center_y = 0;
}
}
@@ -289,10 +289,10 @@ bool SPItem::isCenterSet() {
}
Geom::Point SPItem::getCenter() const {
- // for getBounds() to work
document->ensureUpToDate();
- Geom::OptRect bbox = getBounds(i2dt_affine());
+ // FIXME this is seriously wrong
+ Geom::OptRect bbox = desktopGeometricBounds();
if (bbox) {
return bbox->midpoint() + Geom::Point (transform_center_x, transform_center_y);
} else {
@@ -515,8 +515,7 @@ void SPItem::clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item)
}
}
if (SP_IS_CLIPPATH(clip)) {
- NRRect bbox;
- item->invoke_bbox( &bbox, Geom::identity(), TRUE);
+ Geom::OptRect bbox = item->geometricBounds();
for (SPItemView *v = item->display; v != NULL; v = v->next) {
if (!v->arenaitem->key()) {
v->arenaitem->setKey(SPItem::display_key_new(3));
@@ -525,7 +524,7 @@ void SPItem::clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item)
v->arenaitem->drawing(),
v->arenaitem->key());
v->arenaitem->setClip(ai);
- SP_CLIPPATH(clip)->setBBox(v->arenaitem->key(), &bbox);
+ SP_CLIPPATH(clip)->setBBox(v->arenaitem->key(), bbox);
clip->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
}
@@ -540,8 +539,7 @@ void SPItem::mask_ref_changed(SPObject *old_mask, SPObject *mask, SPItem *item)
}
}
if (SP_IS_MASK(mask)) {
- NRRect bbox;
- item->invoke_bbox( &bbox, Geom::identity(), TRUE);
+ Geom::OptRect bbox = item->geometricBounds();
for (SPItemView *v = item->display; v != NULL; v = v->next) {
if (!v->arenaitem->key()) {
v->arenaitem->setKey(SPItem::display_key_new(3));
@@ -550,7 +548,7 @@ void SPItem::mask_ref_changed(SPObject *old_mask, SPObject *mask, SPItem *item)
v->arenaitem->drawing(),
v->arenaitem->key());
v->arenaitem->setMask(ai);
- sp_mask_set_bbox(SP_MASK(mask), v->arenaitem->key(), &bbox);
+ sp_mask_set_bbox(SP_MASK(mask), v->arenaitem->key(), bbox);
mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
}
@@ -575,16 +573,15 @@ void SPItem::sp_item_update(SPObject *object, SPCtx *ctx, guint flags)
SPMask *mask = item->mask_ref ? item->mask_ref->getObject() : NULL;
if ( clip_path || mask ) {
- NRRect bbox;
- item->invoke_bbox( &bbox, Geom::identity(), TRUE);
+ Geom::OptRect bbox = item->geometricBounds();
if (clip_path) {
for (SPItemView *v = item->display; v != NULL; v = v->next) {
- clip_path->setBBox(v->arenaitem->key(), &bbox);
+ clip_path->setBBox(v->arenaitem->key(), bbox);
}
}
if (mask) {
for (SPItemView *v = item->display; v != NULL; v = v->next) {
- sp_mask_set_bbox(mask, v->arenaitem->key(), &bbox);
+ sp_mask_set_bbox(mask, v->arenaitem->key(), bbox);
}
}
}
@@ -599,8 +596,7 @@ void SPItem::sp_item_update(SPObject *object, SPCtx *ctx, guint flags)
/* Update bounding box data used by filters */
if (item->style->filter.set && item->display) {
- Geom::OptRect item_bbox;
- item->invoke_bbox( item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect item_bbox = item->geometricBounds();
SPItemView *itemview = item->display;
do {
@@ -677,169 +673,132 @@ Inkscape::XML::Node *SPItem::sp_item_write(SPObject *const object, Inkscape::XML
return repr;
}
-/**
- * \return There is no guarantee that the return value will contain a rectangle.
- If this item does not have a boundingbox, it might well be empty.
- */
-Geom::OptRect SPItem::getBounds(Geom::Affine const &transform,
- SPItem::BBoxType type,
- unsigned int /*dkey*/) const
-{
- Geom::OptRect r;
- invoke_bbox_full( r, transform, type, TRUE);
- return r;
-}
-
-void SPItem::invoke_bbox( Geom::OptRect &bbox, Geom::Affine const &transform, unsigned const clear, SPItem::BBoxType type)
-{
- invoke_bbox_full( bbox, transform, type, clear);
-}
-
-// DEPRECATED to phase out the use of NRRect in favor of Geom::OptRect
-void SPItem::invoke_bbox( NRRect *bbox, Geom::Affine const &transform, unsigned const clear, SPItem::BBoxType type)
+/** @brief Get item's geometric bounding box in this item's coordinate system.
+ * The geometric bounding box includes only the path, disregarding all style attributes. */
+Geom::OptRect SPItem::geometricBounds(Geom::Affine const &transform) const
{
- invoke_bbox_full( bbox, transform, type, clear);
+ Geom::OptRect bbox;
+ // call the subclass method
+ if (((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox) {
+ bbox = ((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox(this, transform, SPItem::GEOMETRIC_BBOX);
+ }
+ return bbox;
}
-/** Calls \a item's subclass' bounding box method; clips it by the bbox of clippath, if any; and
- * unions the resulting bbox with \a bbox. If \a clear is true, empties \a bbox first. Passes the
- * transform and the flags to the actual bbox methods. Note that many of subclasses (e.g. groups,
- * clones), in turn, call this function in their bbox methods.
- * \retval bbox Note that there is no guarantee that bbox will contain a rectangle when the
- * function returns. If this item does not have a boundingbox, this might well be empty.
- */
-void SPItem::invoke_bbox_full( Geom::OptRect &bbox, Geom::Affine const &transform, unsigned const flags, unsigned const clear) const
+/** @brief Get item's visual bounding box in this item's coordinate system.
+ * The visual bounding box includes the stroke and the filter region. */
+Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const
{
- if (clear) {
- bbox = Geom::OptRect();
- }
-
- // TODO: replace NRRect by Geom::Rect, for all SPItemClasses, and for SP_CLIPPATH
+ using Geom::X;
+ using Geom::Y;
- NRRect temp_bbox;
- temp_bbox.x0 = temp_bbox.y0 = Geom::infinity();
- temp_bbox.x1 = temp_bbox.y1 = -Geom::infinity();
+ Geom::OptRect bbox;
- // call the subclass method
- if (((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox) {
- ((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox(this, &temp_bbox, transform, flags);
- }
-
- // unless this is geometric bbox, extend by filter area and crop the bbox by clip path, if any
- if ((SPItem::BBoxType) flags != SPItem::GEOMETRIC_BBOX) {
- if ( style && style->filter.href) {
- SPObject *filter = style->getFilter();
- if (filter && SP_IS_FILTER(filter)) {
- // default filer area per the SVG spec:
- double x = -0.1;
- double y = -0.1;
- double w = 1.2;
- double h = 1.2;
-
- // if area is explicitly set, override:
- if (SP_FILTER(filter)->x._set)
- x = SP_FILTER(filter)->x.computed;
- if (SP_FILTER(filter)->y._set)
- y = SP_FILTER(filter)->y.computed;
- if (SP_FILTER(filter)->width._set)
- w = SP_FILTER(filter)->width.computed;
- if (SP_FILTER(filter)->height._set)
- h = SP_FILTER(filter)->height.computed;
-
- double dx0 = 0;
- double dx1 = 0;
- double dy0 = 0;
- double dy1 = 0;
- if (filter_is_single_gaussian_blur(SP_FILTER(filter))) {
- // if this is a single blur, use 2.4*radius
- // which may be smaller than the default area;
- // see set_filter_area for why it's 2.4
- double r = get_single_gaussian_blur_radius (SP_FILTER(filter));
- dx0 = -2.4 * r;
- dx1 = 2.4 * r;
- dy0 = -2.4 * r;
- dy1 = 2.4 * r;
- } else {
- // otherwise, calculate expansion from relative to absolute units:
- dx0 = x * (temp_bbox.x1 - temp_bbox.x0);
- dx1 = (w + x - 1) * (temp_bbox.x1 - temp_bbox.x0);
- dy0 = y * (temp_bbox.y1 - temp_bbox.y0);
- dy1 = (h + y - 1) * (temp_bbox.y1 - temp_bbox.y0);
- }
+ if ( style && style->filter.href && style->getFilter() && SP_IS_FILTER(style->getFilter())) {
+ // call the subclass method
+ if (((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox) {
+ bbox = ((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox(this, Geom::identity(), SPItem::VISUAL_BBOX);
+ }
- // transform the expansions by the item's transform:
- Geom::Affine i2dt(i2dt_affine ());
- dx0 *= i2dt.expansionX();
- dx1 *= i2dt.expansionX();
- dy0 *= i2dt.expansionY();
- dy1 *= i2dt.expansionY();
-
- // expand the bbox
- temp_bbox.x0 += dx0;
- temp_bbox.x1 += dx1;
- temp_bbox.y0 += dy0;
- temp_bbox.y1 += dy1;
- }
+ SPFilter *filter = SP_FILTER(style->getFilter());
+ // default filer area per the SVG spec:
+ SVGLength x, y, w, h;
+ Geom::Point minp, maxp;
+ x.set(SVGLength::PERCENT, -0.10, 0);
+ y.set(SVGLength::PERCENT, -0.10, 0);
+ w.set(SVGLength::PERCENT, 1.20, 0);
+ h.set(SVGLength::PERCENT, 1.20, 0);
+
+ // if area is explicitly set, override:
+ if (filter->x._set)
+ x = filter->x;
+ if (filter->y._set)
+ y = filter->y;
+ if (filter->width._set)
+ w = filter->width;
+ if (filter->height._set)
+ h = filter->height;
+
+ double len_x = bbox ? bbox->width() : 0;
+ double len_y = bbox ? bbox->height() : 0;
+
+ x.update(12, 6, len_x);
+ y.update(12, 6, len_y);
+ w.update(12, 6, len_x);
+ h.update(12, 6, len_y);
+
+ if (filter->filterUnits == SP_FILTER_UNITS_OBJECTBOUNDINGBOX && bbox) {
+ minp[X] = bbox->left() + x.computed * (x.unit == SVGLength::PERCENT ? 1.0 : len_x);
+ maxp[X] = minp[X] + w.computed * (w.unit == SVGLength::PERCENT ? 1.0 : len_x);
+ minp[Y] = bbox->top() + y.computed * (y.unit == SVGLength::PERCENT ? 1.0 : len_y);
+ maxp[Y] = minp[Y] + h.computed * (h.unit == SVGLength::PERCENT ? 1.0 : len_y);
+ } else if (filter->filterUnits == SP_FILTER_UNITS_USERSPACEONUSE) {
+ minp[X] = x.computed;
+ maxp[X] = minp[X] + w.computed;
+ minp[Y] = y.computed;
+ maxp[Y] = minp[Y] + h.computed;
}
- if (clip_ref->getObject()) {
- NRRect b;
- SP_CLIPPATH(clip_ref->getObject())->getBBox(&b, transform, flags);
- nr_rect_d_intersect (&temp_bbox, &temp_bbox, &b);
+ bbox = Geom::OptRect(minp, maxp);
+ *bbox *= transform;
+ } else {
+ // call the subclass method
+ if (((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox) {
+ bbox = ((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox(this, transform, SPItem::VISUAL_BBOX);
}
}
-
- if (temp_bbox.x0 > temp_bbox.x1 || temp_bbox.y0 > temp_bbox.y1) {
- // Either the bbox hasn't been touched by the SPItemClass' bbox method
- // (it still has its initial values, see above: x0 = y0 = Geom::infinity() and x1 = y1 = -Geom::infinity())
- // or it has explicitely been set to be like this (e.g. in sp_shape_bbox)
-
- // When x0 > x1 or y0 > y1, the bbox is considered to be "nothing", although it has not been
- // explicitely defined this way for NRRects (as opposed to Geom::OptRect)
- // So union bbox with nothing = do nothing, just return
- return;
+ if (clip_ref->getObject()) {
+ bbox.intersectWith(SP_CLIPPATH(clip_ref->getObject())->geometricBounds(transform));
}
- // Do not use temp_bbox.upgrade() here, because it uses a test that returns an empty Geom::OptRect()
- // for any rectangle with zero area. The geometrical bbox of for example a vertical line
- // would therefore be translated into empty Geom::OptRect() (see bug https://bugs.launchpad.net/inkscape/+bug/168684)
- Geom::OptRect temp_bbox_new = Geom::Rect(Geom::Point(temp_bbox.x0, temp_bbox.y0), Geom::Point(temp_bbox.x1, temp_bbox.y1));
-
- bbox.unionWith(temp_bbox_new);
+ return bbox;
}
-
-// DEPRECATED to phase out the use of NRRect in favor of Geom::OptRect
-/** Calls \a item's subclass' bounding box method; clips it by the bbox of clippath, if any; and
- * unions the resulting bbox with \a bbox. If \a clear is true, empties \a bbox first. Passes the
- * transform and the flags to the actual bbox methods. Note that many of subclasses (e.g. groups,
- * clones), in turn, call this function in their bbox methods. */
-void SPItem::invoke_bbox_full( NRRect *bbox, Geom::Affine const &transform, unsigned const flags, unsigned const clear)
+Geom::OptRect SPItem::bounds(BBoxType type, Geom::Affine const &transform) const
{
- g_assert(bbox != NULL);
-
- if (clear) {
- bbox->x0 = bbox->y0 = 1e18;
- bbox->x1 = bbox->y1 = -1e18;
- }
-
- NRRect this_bbox;
- this_bbox.x0 = this_bbox.y0 = 1e18;
- this_bbox.x1 = this_bbox.y1 = -1e18;
-
- // call the subclass method
- if (((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox) {
- ((SPItemClass *) G_OBJECT_GET_CLASS(this))->bbox(this, &this_bbox, transform, flags);
+ if (type == GEOMETRIC_BBOX) {
+ return geometricBounds(transform);
+ } else {
+ return visualBounds(transform);
}
+}
- // unless this is geometric bbox, crop the bbox by clip path, if any
- if ((SPItem::BBoxType) flags != SPItem::GEOMETRIC_BBOX && clip_ref->getObject()) {
- NRRect b;
- SP_CLIPPATH(clip_ref->getObject())->getBBox(&b, transform, flags);
- nr_rect_d_intersect (&this_bbox, &this_bbox, &b);
+/** Get item's geometric bbox in document coordinate system.
+ * Document coordinates are the default coordinates of the root element:
+ * the origin is at the top left, X grows to the right and Y grows downwards. */
+Geom::OptRect SPItem::documentGeometricBounds() const
+{
+ return geometricBounds(i2doc_affine());
+}
+/// Get item's visual bbox in document coordinate system.
+Geom::OptRect SPItem::documentVisualBounds() const
+{
+ return visualBounds(i2doc_affine());
+}
+Geom::OptRect SPItem::documentBounds(BBoxType type) const
+{
+ if (type == GEOMETRIC_BBOX) {
+ return documentGeometricBounds();
+ } else {
+ return documentVisualBounds();
}
-
- // if non-empty (with some tolerance - ?) union this_bbox with the bbox we've got passed
- if ( fabs(this_bbox.x1-this_bbox.x0) > -0.00001 && fabs(this_bbox.y1-this_bbox.y0) > -0.00001 ) {
- nr_rect_d_union (bbox, bbox, &this_bbox);
+}
+/** Get item's geometric bbox in desktop coordinate system.
+ * Desktop coordinates should be user defined. Currently they are hardcoded:
+ * origin is at bottom left, X grows to the right and Y grows upwards. */
+Geom::OptRect SPItem::desktopGeometricBounds() const
+{
+ return geometricBounds(i2dt_affine());
+}
+/// Get item's visual bbox in desktop coordinate system.
+Geom::OptRect SPItem::desktopVisualBounds() const
+{
+ return visualBounds(i2dt_affine());
+}
+Geom::OptRect SPItem::desktopBounds(BBoxType type) const
+{
+ if (type == GEOMETRIC_BBOX) {
+ return desktopGeometricBounds();
+ } else {
+ return desktopVisualBounds();
}
}
@@ -864,20 +823,6 @@ unsigned SPItem::pos_in_parent()
return 0;
}
-void SPItem::getBboxDesktop(NRRect *bbox, SPItem::BBoxType type)
-{
- g_assert(bbox != NULL);
-
- invoke_bbox( bbox, i2dt_affine(), TRUE, type);
-}
-
-Geom::OptRect SPItem::getBboxDesktop(SPItem::BBoxType type)
-{
- Geom::OptRect rect = Geom::OptRect();
- invoke_bbox( rect, i2dt_affine(), TRUE, type);
- return rect;
-}
-
void SPItem::sp_item_private_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs)
{
/* This will only be called if the derived class doesn't override this.
@@ -1011,6 +956,8 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned
}
if (ai != NULL) {
+ Geom::OptRect item_bbox = geometricBounds();
+
display = sp_item_view_new_prepend(display, this, flags, key, ai);
ai->setTransform(transform);
ai->setOpacity(SP_SCALE24_TO_FLOAT(style->opacity.value));
@@ -1029,9 +976,7 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned
ai->setClip(ac);
// Update bbox, in case the clip uses bbox units
- NRRect bbox;
- invoke_bbox( &bbox, Geom::identity(), TRUE);
- SP_CLIPPATH(cp)->setBBox(clip_key, &bbox);
+ SP_CLIPPATH(cp)->setBBox(clip_key, item_bbox);
cp->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
if (mask_ref->getObject()) {
@@ -1047,14 +992,10 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned
ai->setMask(ac);
// Update bbox, in case the mask uses bbox units
- NRRect bbox;
- invoke_bbox( &bbox, Geom::identity(), TRUE);
- sp_mask_set_bbox(SP_MASK(mask), mask_key, &bbox);
+ sp_mask_set_bbox(SP_MASK(mask), mask_key, item_bbox);
mask->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
}
ai->setData(this);
- Geom::OptRect item_bbox;
- invoke_bbox( item_bbox, Geom::identity(), TRUE, SPItem::GEOMETRIC_BBOX);
ai->setItemBounds(item_bbox);
}
@@ -1544,10 +1485,8 @@ SPItem *sp_item_first_item_child(SPObject *obj)
void SPItem::convert_to_guides() {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
int prefs_bbox = prefs->getInt("/tools/bounding_box", 0);
- SPItem::BBoxType bbox_type = (prefs_bbox ==0)?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
- Geom::OptRect bbox = getBboxDesktop(bbox_type);
+ Geom::OptRect bbox = (prefs_bbox == 0) ? desktopVisualBounds() : desktopGeometricBounds();
if (!bbox) {
g_warning ("Cannot determine item's bounding box during conversion to guides.\n");
return;
diff --git a/src/sp-item.h b/src/sp-item.h
index 633deb508..62336e3c8 100644
--- a/src/sp-item.h
+++ b/src/sp-item.h
@@ -112,7 +112,7 @@ public:
// includes only the bare path bbox, no stroke, no nothing
GEOMETRIC_BBOX,
// includes everything: correctly done stroke (with proper miters and caps), markers, filter margins (e.g. blur)
- RENDERING_BBOX
+ VISUAL_BBOX
};
unsigned int sensitive : 1;
@@ -151,7 +151,7 @@ public:
void setExplicitlyHidden(bool val);
- void setCenter(Geom::Point object_centre);
+ void setCenter(Geom::Point const &object_centre);
void unsetCenter();
bool isCenterSet();
Geom::Point getCenter() const;
@@ -167,15 +167,19 @@ public:
void raiseToTop();
void lowerToBottom();
- Geom::OptRect getBounds(Geom::Affine const &transform, BBoxType type=APPROXIMATE_BBOX, unsigned int dkey=0) const;
-
sigc::connection connectTransformed(sigc::slot<void, Geom::Affine const *, SPItem *> slot) {
return _transformed_signal.connect(slot);
}
- void invoke_bbox( Geom::OptRect &bbox, Geom::Affine const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
- void invoke_bbox( NRRect *bbox, Geom::Affine const &transform, unsigned const clear, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated));
- void invoke_bbox_full( Geom::OptRect &bbox, Geom::Affine const &transform, unsigned const flags, unsigned const clear) const;
- void invoke_bbox_full( NRRect *bbox, Geom::Affine const &transform, unsigned const flags, unsigned const clear) __attribute__ ((deprecated));
+
+ Geom::OptRect geometricBounds(Geom::Affine const &transform = Geom::identity()) const;
+ Geom::OptRect visualBounds(Geom::Affine const &transform = Geom::identity()) const;
+ Geom::OptRect bounds(BBoxType type, Geom::Affine const &transform = Geom::identity()) const;
+ Geom::OptRect documentGeometricBounds() const;
+ Geom::OptRect documentVisualBounds() const;
+ Geom::OptRect documentBounds(BBoxType type) const;
+ Geom::OptRect desktopGeometricBounds() const;
+ Geom::OptRect desktopVisualBounds() const;
+ Geom::OptRect desktopBounds(BBoxType type) const;
unsigned pos_in_parent();
gchar *description();
@@ -195,8 +199,7 @@ public:
void convert_item_to_guides();
gint emitEvent (SPEvent &event);
Inkscape::DrawingItem *get_arenaitem(unsigned int key);
- void getBboxDesktop(NRRect *bbox, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) __attribute__ ((deprecated));
- Geom::OptRect getBboxDesktop(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
+
Geom::Affine i2doc_affine() const;
Geom::Affine i2dt_affine() const;
void set_i2d_affine(Geom::Affine const &transform);
@@ -237,7 +240,7 @@ public:
SPObjectClass parent_class;
/** BBox union in given coordinate system */
- void (* bbox) (SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+ Geom::OptRect (* bbox) (SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
/** Printing method. Assumes ctm is set to item affine matrix */
/* \todo Think about it, and maybe implement generic export method instead (Lauris) */
diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp
index f23172a17..f955e5428 100644
--- a/src/sp-mask.cpp
+++ b/src/sp-mask.cpp
@@ -31,7 +31,7 @@ struct SPMaskView {
SPMaskView *next;
unsigned int key;
Inkscape::DrawingItem *arenaitem;
- NRRect bbox;
+ Geom::OptRect bbox;
};
static void sp_mask_class_init (SPMaskClass *klass);
@@ -216,10 +216,9 @@ static void sp_mask_update(SPObject *object, SPCtx *ctx, guint flags)
SPMask *mask = SP_MASK(object);
for (SPMaskView *v = mask->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
- if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) {
- Geom::Affine t(Geom::Scale(v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0));
- t[4] = v->bbox.x0;
- t[5] = v->bbox.y0;
+ if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX && v->bbox) {
+ Geom::Affine t = Geom::Scale(v->bbox->dimensions());
+ t.setTranslation(v->bbox->min());
g->setChildTransform(t);
} else {
g->setChildTransform(Geom::identity());
@@ -314,11 +313,10 @@ Inkscape::DrawingItem *sp_mask_show(SPMask *mask, Inkscape::Drawing &drawing, un
}
}
- if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) {
- Geom::Affine t(Geom::Scale(mask->display->bbox.x1 - mask->display->bbox.x0, mask->display->bbox.y1 - mask->display->bbox.y0));
- t[4] = mask->display->bbox.x0;
- t[5] = mask->display->bbox.y0;
- ai->setChildTransform(t);
+ if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX && mask->display->bbox) {
+ Geom::Affine t = Geom::Scale(mask->display->bbox->dimensions());
+ t.setTranslation(mask->display->bbox->min());
+ ai->setChildTransform(t);
}
return ai;
@@ -347,17 +345,12 @@ void sp_mask_hide(SPMask *cp, unsigned int key)
}
void
-sp_mask_set_bbox (SPMask *mask, unsigned int key, NRRect *bbox)
+sp_mask_set_bbox (SPMask *mask, unsigned int key, Geom::OptRect const &bbox)
{
for (SPMaskView *v = mask->display; v != NULL; v = v->next) {
if (v->key == key) {
- if (!Geom::are_near(v->bbox.x0, bbox->x0) ||
- !Geom::are_near(v->bbox.y0, bbox->y0) ||
- !Geom::are_near(v->bbox.x1, bbox->x1) ||
- !Geom::are_near(v->bbox.y1, bbox->y1)) {
- v->bbox = *bbox;
- }
- break;
+ v->bbox = bbox;
+ break;
}
}
}
@@ -372,8 +365,7 @@ sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, Inkscape::DrawingI
new_mask_view->next = list;
new_mask_view->key = key;
new_mask_view->arenaitem = arenaitem;
- new_mask_view->bbox.x0 = new_mask_view->bbox.x1 = 0.0;
- new_mask_view->bbox.y0 = new_mask_view->bbox.y1 = 0.0;
+ new_mask_view->bbox = Geom::OptRect();
return new_mask_view;
}
diff --git a/src/sp-mask.h b/src/sp-mask.h
index b1048e6be..d493c2dc7 100644
--- a/src/sp-mask.h
+++ b/src/sp-mask.h
@@ -13,6 +13,13 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#include <2geom/rect.h>
+#include "display/display-forward.h"
+#include "libnr/nr-forward.h"
+#include "sp-object-group.h"
+#include "uri-references.h"
+#include "xml/node.h"
+
#define SP_TYPE_MASK (sp_mask_get_type ())
#define SP_MASK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_MASK, SPMask))
#define SP_MASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_MASK, SPMaskClass))
@@ -23,12 +30,6 @@ class SPMask;
class SPMaskClass;
class SPMaskView;
-#include "display/display-forward.h"
-#include "libnr/nr-forward.h"
-#include "sp-object-group.h"
-#include "uri-references.h"
-#include "xml/node.h"
-
struct SPMask : public SPObjectGroup {
unsigned int maskUnits_set : 1;
unsigned int maskUnits : 1;
@@ -93,7 +94,7 @@ protected:
Inkscape::DrawingItem *sp_mask_show (SPMask *mask, Inkscape::Drawing &drawing, unsigned int key);
void sp_mask_hide (SPMask *mask, unsigned int key);
-void sp_mask_set_bbox (SPMask *mask, unsigned int key, NRRect *bbox);
+void sp_mask_set_bbox (SPMask *mask, unsigned int key, Geom::OptRect const &bbox);
const gchar *sp_mask_create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform);
diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp
index 5187ff027..8617c096a 100644
--- a/src/sp-offset.cpp
+++ b/src/sp-offset.cpp
@@ -514,7 +514,7 @@ sp_offset_set_shape(SPShape *shape)
theRes->ConvertToForme (orig, 1, originaux);
SPItem *item = shape;
- Geom::OptRect bbox = item->getBboxDesktop ();
+ Geom::OptRect bbox = item->desktopVisualBounds();
if ( bbox ) {
gdouble size = L2(bbox->dimensions());
gdouble const exp = item->transform.descrim();
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index 4fd1deb69..15fa76d65 100644
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
@@ -502,212 +502,158 @@ void SPShape::sp_shape_modified(SPObject *object, unsigned int flags)
* Calculates the bounding box for item, storing it into bbox.
* This also includes the bounding boxes of any markers included in the shape.
*/
-void SPShape::sp_shape_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags)
+Geom::OptRect SPShape::sp_shape_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType bboxtype)
{
SPShape const *shape = SP_SHAPE (item);
- SPItem::BBoxType bboxtype = (SPItem::BBoxType) flags;
-
- if (shape->curve) {
- Geom::OptRect geombbox = bounds_exact_transformed(shape->curve->get_pathvector(), transform);
- if (geombbox) {
- NRRect cbbox;
- cbbox.x0 = (*geombbox)[0][0];
- cbbox.y0 = (*geombbox)[1][0];
- cbbox.x1 = (*geombbox)[0][1];
- cbbox.y1 = (*geombbox)[1][1];
-
- switch (bboxtype) {
- case SPItem::GEOMETRIC_BBOX: {
- // do nothing
- break;
- }
- case SPItem::RENDERING_BBOX: {
- // convert the stroke to a path and calculate that path's geometric bbox
- SPStyle* style = item->style;
- if (!style->stroke.isNone()) {
- Geom::PathVector *pathv = item_outline(item);
- if (pathv) {
- Geom::OptRect geomstrokebbox = bounds_exact_transformed(*pathv, transform);
- if (geomstrokebbox) {
- NRRect strokebbox;
- strokebbox.x0 = (*geomstrokebbox)[0][0];
- strokebbox.y0 = (*geomstrokebbox)[1][0];
- strokebbox.x1 = (*geomstrokebbox)[0][1];
- strokebbox.y1 = (*geomstrokebbox)[1][1];
- nr_rect_d_union (&cbbox, &cbbox, &strokebbox);
- }
- delete pathv;
+ Geom::OptRect bbox;
+
+ if (!shape->curve) return bbox;
+ bbox = bounds_exact_transformed(shape->curve->get_pathvector(), transform);
+ if (!bbox) return bbox;
+
+ if (bboxtype == SPItem::VISUAL_BBOX) {
+ // convert the stroke to a path and calculate that path's geometric bbox
+ SPStyle* style = item->style;
+ if (!style->stroke.isNone()) {
+ Geom::PathVector *pathv = item_outline(item);
+ if (pathv) {
+ bbox |= bounds_exact_transformed(*pathv, transform);
+ delete pathv;
+ }
+ }
+ // Union with bboxes of the markers, if any
+ if ( shape->hasMarkers() && !shape->curve->get_pathvector().empty() ) {
+ /** \todo make code prettier! */
+ Geom::PathVector const & pathv = shape->curve->get_pathvector();
+ // START marker
+ for (unsigned i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START
+ if ( shape->marker[i] ) {
+ SPMarker* marker = SP_MARKER (shape->marker[i]);
+ SPItem* marker_item = sp_item_first_item_child( marker );
+
+ if (marker_item) {
+ Geom::Affine tr(sp_shape_marker_get_transform_at_start(pathv.begin()->front()));
+ if (!marker->orient_auto) {
+ Geom::Point transl = tr.translation();
+ tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
+ }
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = Geom::Scale(style->stroke_width.computed) * tr;
}
+
+ // total marker transform
+ tr = marker_item->transform * marker->c2p * tr * transform;
+
+ // get bbox of the marker with that transform
+ bbox |= marker_item->visualBounds(tr);
}
- break;
}
- default:
- case SPItem::APPROXIMATE_BBOX: {
- SPStyle* style = item->style;
- if (!style->stroke.isNone()) {
- double const scale = transform.descrim();
- if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord
- double const width = MAX(0.125, style->stroke_width.computed * scale);
- if ( fabs(cbbox.x1-cbbox.x0) > -0.00001 && fabs(cbbox.y1-cbbox.y0) > -0.00001 ) {
- cbbox.x0-=0.5*width;
- cbbox.x1+=0.5*width;
- cbbox.y0-=0.5*width;
- cbbox.y1+=0.5*width;
- }
+ }
+ // MID marker
+ for (unsigned i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID
+ SPMarker* marker = SP_MARKER (shape->marker[i]);
+ if ( !shape->marker[i] ) continue;
+ SPItem* marker_item = sp_item_first_item_child( marker );
+ if ( !marker_item ) continue;
+
+ for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
+ // START position
+ if ( path_it != pathv.begin()
+ && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there
+ {
+ Geom::Affine tr(sp_shape_marker_get_transform_at_start(path_it->front()));
+ if (!marker->orient_auto) {
+ Geom::Point transl = tr.translation();
+ tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
}
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = Geom::Scale(style->stroke_width.computed) * tr;
+ }
+ tr = marker_item->transform * marker->c2p * tr * transform;
+ bbox |= marker_item->visualBounds(tr);
}
+ // MID position
+ if ( path_it->size_default() > 1) {
+ Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
+ while (curve_it2 != path_it->end_default())
+ {
+ /* Put marker between curve_it1 and curve_it2.
+ * Loop to end_default (so including closing segment), because when a path is closed,
+ * there should be a midpoint marker between last segment and closing straight line segment */
- // Union with bboxes of the markers, if any
- if ( shape->hasMarkers() && !shape->curve->get_pathvector().empty() ) {
- /** \todo make code prettier! */
- Geom::PathVector const & pathv = shape->curve->get_pathvector();
- // START marker
- for (unsigned i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START
- if ( shape->marker[i] ) {
- SPMarker* marker = SP_MARKER (shape->marker[i]);
- SPItem* marker_item = sp_item_first_item_child( marker );
-
- if (marker_item) {
- Geom::Affine tr(sp_shape_marker_get_transform_at_start(pathv.begin()->front()));
- if (!marker->orient_auto) {
- Geom::Point transl = tr.translation();
- tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
- }
- if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
- tr = Geom::Scale(style->stroke_width.computed) * tr;
- }
-
- // total marker transform
- tr = marker_item->transform * marker->c2p * tr * transform;
-
- // get bbox of the marker with that transform
- NRRect marker_bbox;
- marker_item->invoke_bbox ( &marker_bbox, tr, true);
- // union it with the shape bbox
- nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
- }
- }
- }
- // MID marker
- for (unsigned i = 0; i < 3; i += 2) { // SP_MARKER_LOC and SP_MARKER_LOC_MID
SPMarker* marker = SP_MARKER (shape->marker[i]);
- if ( !shape->marker[i] ) continue;
SPItem* marker_item = sp_item_first_item_child( marker );
- if ( !marker_item ) continue;
-
- for(Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) {
- // START position
- if ( path_it != pathv.begin()
- && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there
- {
- Geom::Affine tr(sp_shape_marker_get_transform_at_start(path_it->front()));
- if (!marker->orient_auto) {
- Geom::Point transl = tr.translation();
- tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
- }
- if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
- tr = Geom::Scale(style->stroke_width.computed) * tr;
- }
- tr = marker_item->transform * marker->c2p * tr * transform;
- NRRect marker_bbox;
- marker_item->invoke_bbox ( &marker_bbox, tr, true);
- nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
- }
- // MID position
- if ( path_it->size_default() > 1) {
- Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
- Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
- while (curve_it2 != path_it->end_default())
- {
- /* Put marker between curve_it1 and curve_it2.
- * Loop to end_default (so including closing segment), because when a path is closed,
- * there should be a midpoint marker between last segment and closing straight line segment */
-
- SPMarker* marker = SP_MARKER (shape->marker[i]);
- SPItem* marker_item = sp_item_first_item_child( marker );
-
- if (marker_item) {
- Geom::Affine tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2));
- if (!marker->orient_auto) {
- Geom::Point transl = tr.translation();
- tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
- }
- if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
- tr = Geom::Scale(style->stroke_width.computed) * tr;
- }
- tr = marker_item->transform * marker->c2p * tr * transform;
- NRRect marker_bbox;
- marker_item->invoke_bbox ( &marker_bbox, tr, true);
- nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
- }
-
- ++curve_it1;
- ++curve_it2;
- }
+
+ if (marker_item) {
+ Geom::Affine tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2));
+ if (!marker->orient_auto) {
+ Geom::Point transl = tr.translation();
+ tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
}
- // END position
- if ( path_it != (pathv.end()-1) && !path_it->empty()) {
- Geom::Curve const &lastcurve = path_it->back_default();
- Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve);
- if (!marker->orient_auto) {
- Geom::Point transl = tr.translation();
- tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
- }
- if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
- tr = Geom::Scale(style->stroke_width.computed) * tr;
- }
- tr = marker_item->transform * marker->c2p * tr * transform;
- NRRect marker_bbox;
- marker_item->invoke_bbox ( &marker_bbox, tr, true);
- nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = Geom::Scale(style->stroke_width.computed) * tr;
}
+ tr = marker_item->transform * marker->c2p * tr * transform;
+ bbox |= marker_item->visualBounds(tr);
}
+
+ ++curve_it1;
+ ++curve_it2;
}
- // END marker
- for (unsigned i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END
- if ( shape->marker[i] ) {
- SPMarker* marker = SP_MARKER (shape->marker[i]);
- SPItem* marker_item = sp_item_first_item_child( marker );
-
- if (marker_item) {
- /* Get reference to last curve in the path.
- * For moveto-only path, this returns the "closing line segment". */
- Geom::Path const &path_last = pathv.back();
- unsigned int index = path_last.size_default();
- if (index > 0) {
- index--;
- }
- Geom::Curve const &lastcurve = path_last[index];
-
- Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve);
- if (!marker->orient_auto) {
- Geom::Point transl = tr.translation();
- tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
- }
- if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
- tr = Geom::Scale(style->stroke_width.computed) * tr;
- }
-
- // total marker transform
- tr = marker_item->transform * marker->c2p * tr * transform;
-
- // get bbox of the marker with that transform
- NRRect marker_bbox;
- marker_item->invoke_bbox ( &marker_bbox, tr, true);
- // union it with the shape bbox
- nr_rect_d_union (&cbbox, &cbbox, &marker_bbox);
- }
- }
+ }
+ // END position
+ if ( path_it != (pathv.end()-1) && !path_it->empty()) {
+ Geom::Curve const &lastcurve = path_it->back_default();
+ Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve);
+ if (!marker->orient_auto) {
+ Geom::Point transl = tr.translation();
+ tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
+ }
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = Geom::Scale(style->stroke_width.computed) * tr;
}
+ tr = marker_item->transform * marker->c2p * tr * transform;
+ bbox |= marker_item->visualBounds();
}
- break;
- } // end case approximate bbox type
- } // end switch bboxtype
+ }
+ }
+ // END marker
+ for (unsigned i = 0; i < 4; i += 3) { // SP_MARKER_LOC and SP_MARKER_LOC_END
+ if ( shape->marker[i] ) {
+ SPMarker* marker = SP_MARKER (shape->marker[i]);
+ SPItem* marker_item = sp_item_first_item_child( marker );
+
+ if (marker_item) {
+ /* Get reference to last curve in the path.
+ * For moveto-only path, this returns the "closing line segment". */
+ Geom::Path const &path_last = pathv.back();
+ unsigned int index = path_last.size_default();
+ if (index > 0) {
+ index--;
+ }
+ Geom::Curve const &lastcurve = path_last[index];
+
+ Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve);
+ if (!marker->orient_auto) {
+ Geom::Point transl = tr.translation();
+ tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl);
+ }
+ if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) {
+ tr = Geom::Scale(style->stroke_width.computed) * tr;
+ }
- // copy our bbox to the variable we're given
- *bbox = cbbox;
+ // total marker transform
+ tr = marker_item->transform * marker->c2p * tr * transform;
+
+ // get bbox of the marker with that transform
+ bbox |= marker_item->visualBounds(tr);
+ }
+ }
+ }
}
}
+ return bbox;
}
static void
@@ -736,7 +682,7 @@ sp_shape_print_invoke_marker_printing(SPObject* obj, Geom::Affine tr, SPStyle* s
void
sp_shape_print (SPItem *item, SPPrintContext *ctx)
{
- NRRect pbox, dbox, bbox;
+ Geom::OptRect pbox, dbox, bbox;
SPShape *shape = SP_SHAPE(item);
@@ -755,22 +701,19 @@ sp_shape_print (SPItem *item, SPPrintContext *ctx)
}
/* fixme: Think (Lauris) */
- item->invoke_bbox( &pbox, Geom::identity(), TRUE);
- dbox.x0 = 0.0;
- dbox.y0 = 0.0;
- dbox.x1 = item->document->getWidth();
- dbox.y1 = item->document->getHeight();
- item->getBboxDesktop (&bbox);
+ pbox = item->geometricBounds();
+ bbox = item->desktopVisualBounds();
+ dbox = Geom::Rect::from_xywh(Geom::Point(0,0), item->document->getDimensions());
Geom::Affine const i2dt(item->i2dt_affine());
SPStyle* style = item->style;
if (!style->fill.isNone()) {
- sp_print_fill (ctx, pathv, &i2dt, style, &pbox, &dbox, &bbox);
+ sp_print_fill (ctx, pathv, &i2dt, style, pbox, dbox, bbox);
}
if (!style->stroke.isNone()) {
- sp_print_stroke (ctx, pathv, &i2dt, style, &pbox, &dbox, &bbox);
+ sp_print_stroke (ctx, pathv, &i2dt, style, pbox, dbox, bbox);
}
/** \todo make code prettier */
@@ -1184,7 +1127,7 @@ void SPShape::sp_shape_snappoints(SPItem const *item, std::vector<Inkscape::Snap
Geom::Affine const i2dt (item->i2dt_affine ());
if (snapprefs->isTargetSnappable(Inkscape::SNAPTARGET_OBJECT_MIDPOINT)) {
- Geom::OptRect bbox = item->getBounds(i2dt);
+ Geom::OptRect bbox = item->desktopVisualBounds();
if (bbox) {
p.push_back(Inkscape::SnapCandidatePoint(bbox->midpoint(), Inkscape::SNAPSOURCE_OBJECT_MIDPOINT, Inkscape::SNAPTARGET_OBJECT_MIDPOINT));
}
diff --git a/src/sp-shape.h b/src/sp-shape.h
index 355d8e7cc..06bd704ad 100644
--- a/src/sp-shape.h
+++ b/src/sp-shape.h
@@ -66,7 +66,7 @@ private:
static void sp_shape_modified (SPObject *object, unsigned int flags);
static Inkscape::XML::Node *sp_shape_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
- static void sp_shape_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+ static Geom::OptRect sp_shape_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static Inkscape::DrawingItem *sp_shape_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
static void sp_shape_hide (SPItem *item, unsigned int key);
static void sp_shape_snappoints (SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp
index bee28f8e3..71de619c1 100644
--- a/src/sp-symbol.cpp
+++ b/src/sp-symbol.cpp
@@ -39,7 +39,7 @@ static Inkscape::XML::Node *sp_symbol_write (SPObject *object, Inkscape::XML::Do
static Inkscape::DrawingItem *sp_symbol_show (SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
static void sp_symbol_hide (SPItem *item, unsigned int key);
-static void sp_symbol_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_symbol_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static void sp_symbol_print (SPItem *item, SPPrintContext *ctx);
static SPGroupClass *parent_class;
@@ -399,18 +399,20 @@ static void sp_symbol_hide(SPItem *item, unsigned int key)
}
}
-static void sp_symbol_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags)
+static Geom::OptRect sp_symbol_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
{
SPSymbol const *symbol = SP_SYMBOL(item);
+ Geom::OptRect bbox;
if (symbol->cloned) {
// Cloned <symbol> is actually renderable
if (((SPItemClass *) (parent_class))->bbox) {
Geom::Affine const a( symbol->c2p * transform );
- ((SPItemClass *) (parent_class))->bbox(item, bbox, a, flags);
+ bbox = ((SPItemClass *) (parent_class))->bbox(item, a, type);
}
}
+ return bbox;
}
static void sp_symbol_print(SPItem *item, SPPrintContext *ctx)
diff --git a/src/sp-text.cpp b/src/sp-text.cpp
index 9bb674843..fc248824d 100644
--- a/src/sp-text.cpp
+++ b/src/sp-text.cpp
@@ -71,7 +71,7 @@ static void sp_text_update (SPObject *object, SPCtx *ctx, guint flags);
static void sp_text_modified (SPObject *object, guint flags);
static Inkscape::XML::Node *sp_text_write (SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
-static void sp_text_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_text_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static Inkscape::DrawingItem *sp_text_show (SPItem *item, Inkscape::Drawing &drawing, unsigned key, unsigned flags);
static void sp_text_hide (SPItem *item, unsigned key);
static char *sp_text_description (SPItem *item);
@@ -248,14 +248,13 @@ static void sp_text_update(SPObject *object, SPCtx *ctx, guint flags)
/* fixme: So check modification flag everywhere immediate state is used */
text->rebuildLayout();
- NRRect paintbox;
- text->invoke_bbox( &paintbox, Geom::identity(), TRUE);
+ Geom::OptRect paintbox = text->geometricBounds();
for (SPItemView* v = text->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
text->_clearFlow(g);
g->setStyle(object->style);
// pass the bbox of the text object as paintbox (used for paintserver fills)
- text->layout.show(g, &paintbox);
+ text->layout.show(g, paintbox);
}
}
}
@@ -277,13 +276,12 @@ static void sp_text_modified(SPObject *object, guint flags)
// and create new ones. This is probably quite wasteful.
if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) {
SPText *text = SP_TEXT (object);
- NRRect paintbox;
- text->invoke_bbox( &paintbox, Geom::identity(), TRUE);
+ Geom::OptRect paintbox = text->geometricBounds();
for (SPItemView* v = text->display; v != NULL; v = v->next) {
Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
text->_clearFlow(g);
g->setStyle(object->style);
- text->layout.show(g, &paintbox);
+ text->layout.show(g, paintbox);
}
}
@@ -363,25 +361,17 @@ static Inkscape::XML::Node *sp_text_write(SPObject *object, Inkscape::XML::Docum
return repr;
}
-static void
-sp_text_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const /*flags*/)
+static Geom::OptRect
+sp_text_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
{
- SP_TEXT(item)->layout.getBoundingBox(bbox, transform);
-
- // Add stroke width
- SPStyle* style = item->style;
- if (!style->stroke.isNone()) {
- double const scale = transform.descrim();
- if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord
- double const width = MAX(0.125, style->stroke_width.computed * scale);
- if ( fabs(bbox->x1 - bbox->x0) > -0.00001 && fabs(bbox->y1 - bbox->y0) > -0.00001 ) {
- bbox->x0-=0.5*width;
- bbox->x1+=0.5*width;
- bbox->y0-=0.5*width;
- bbox->y1+=0.5*width;
- }
- }
+ Geom::OptRect bbox = SP_TEXT(item)->layout.bounds(transform);
+
+ // FIXME this code is incorrect
+ if (type == SPItem::VISUAL_BBOX && !item->style->stroke.isNone()) {
+ double scale = transform.descrim();
+ bbox->expandBy(0.5 * item->style->stroke_width.computed * scale);
}
+ return bbox;
}
@@ -395,9 +385,7 @@ sp_text_show(SPItem *item, Inkscape::Drawing &drawing, unsigned /* key*/, unsign
flowed->setStyle(group->style);
// pass the bbox of the text object as paintbox (used for paintserver fills)
- NRRect paintbox;
- item->invoke_bbox( &paintbox, Geom::identity(), TRUE);
- group->layout.show(flowed, &paintbox);
+ group->layout.show(flowed, group->geometricBounds());
return flowed;
}
@@ -509,18 +497,15 @@ sp_text_set_transform (SPItem *item, Geom::Affine const &xform)
static void
sp_text_print (SPItem *item, SPPrintContext *ctx)
{
- NRRect pbox, dbox, bbox;
SPText *group = SP_TEXT (item);
+ Geom::OptRect pbox, bbox, dbox;
- item->invoke_bbox( &pbox, Geom::identity(), TRUE);
- item->getBboxDesktop (&bbox);
- dbox.x0 = 0.0;
- dbox.y0 = 0.0;
- dbox.x1 = item->document->getWidth();
- dbox.y1 = item->document->getHeight();
+ pbox = item->geometricBounds();
+ bbox = item->desktopVisualBounds();
+ dbox = Geom::Rect::from_xywh(Geom::Point(0,0), item->document->getDimensions());
Geom::Affine const ctm (item->i2dt_affine());
- group->layout.print(ctx,&pbox,&dbox,&bbox,ctm);
+ group->layout.print(ctx,pbox,dbox,bbox,ctm);
}
/*
diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp
index dcf46f6ac..ac20ce098 100644
--- a/src/sp-tref.cpp
+++ b/src/sp-tref.cpp
@@ -63,7 +63,7 @@ static void sp_tref_update(SPObject *object, SPCtx *ctx, guint flags);
static void sp_tref_modified(SPObject *object, guint flags);
static Inkscape::XML::Node *sp_tref_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
-static void sp_tref_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_tref_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static gchar *sp_tref_description(SPItem *item);
static void sp_tref_href_changed(SPObject *old_ref, SPObject *ref, SPTRef *tref);
@@ -314,39 +314,33 @@ sp_tref_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML:
return repr;
}
-/**
+/*
* The code for this function is swiped from the tspan bbox code, since tref should work pretty much the same way
*/
-static void
-sp_tref_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const /*flags*/)
+static Geom::OptRect
+sp_tref_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
{
+ Geom::OptRect bbox;
// find out the ancestor text which holds our layout
SPObject const *parent_text = item;
while ( parent_text && !SP_IS_TEXT(parent_text) ) {
parent_text = parent_text->parent;
}
if (parent_text == NULL) {
- return;
+ return bbox;
}
// get the bbox of our portion of the layout
- SP_TEXT(parent_text)->layout.getBoundingBox(
- bbox, transform, sp_text_get_length_upto(parent_text, item), sp_text_get_length_upto(item, NULL) - 1);
+ bbox = SP_TEXT(parent_text)->layout.bounds(transform,
+ sp_text_get_length_upto(parent_text, item), sp_text_get_length_upto(item, NULL) - 1);
// Add stroke width
- SPStyle* style = item->style;
- if (!style->stroke.isNone()) {
- double const scale = transform.descrim();
- if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord
- double const width = MAX(0.125, style->stroke_width.computed * scale);
- if ( fabs(bbox->x1 - bbox->x0) > -0.00001 && fabs(bbox->y1 - bbox->y0) > -0.00001 ) {
- bbox->x0-=0.5*width;
- bbox->x1+=0.5*width;
- bbox->y0-=0.5*width;
- bbox->y1+=0.5*width;
- }
- }
+ // FIXME this code is incorrect
+ if (type == SPItem::VISUAL_BBOX && !item->style->stroke.isNone()) {
+ double scale = transform.descrim();
+ bbox->expandBy(0.5 * item->style->stroke_width.computed * scale);
}
+ return bbox;
}
diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp
index 199d82e1b..f4e79f7d5 100644
--- a/src/sp-tspan.cpp
+++ b/src/sp-tspan.cpp
@@ -56,7 +56,7 @@ static void sp_tspan_release(SPObject *object);
static void sp_tspan_set(SPObject *object, unsigned key, gchar const *value);
static void sp_tspan_update(SPObject *object, SPCtx *ctx, guint flags);
static void sp_tspan_modified(SPObject *object, unsigned flags);
-static void sp_tspan_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_tspan_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static Inkscape::XML::Node *sp_tspan_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags);
static char *sp_tspan_description (SPItem *item);
@@ -203,34 +203,30 @@ static void sp_tspan_modified(SPObject *object, unsigned flags)
}
}
-static void sp_tspan_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const /*flags*/)
+static Geom::OptRect
+sp_tspan_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
{
+ Geom::OptRect bbox;
// find out the ancestor text which holds our layout
SPObject const *parent_text = item;
while (parent_text && !SP_IS_TEXT(parent_text)) {
parent_text = parent_text->parent;
}
if (parent_text == NULL) {
- return;
+ return bbox;
}
// get the bbox of our portion of the layout
- SP_TEXT(parent_text)->layout.getBoundingBox(bbox, transform, sp_text_get_length_upto(parent_text, item), sp_text_get_length_upto(item, NULL) - 1);
+ bbox = SP_TEXT(parent_text)->layout.bounds(transform, sp_text_get_length_upto(parent_text, item), sp_text_get_length_upto(item, NULL) - 1);
+ if (!bbox) return bbox;
// Add stroke width
- SPStyle* style = item->style;
- if (!style->stroke.isNone()) {
- double const scale = transform.descrim();
- if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord
- double const width = MAX(0.125, style->stroke_width.computed * scale);
- if ( fabs(bbox->x1 - bbox->x0) > -0.00001 && fabs(bbox->y1 - bbox->y0) > -0.00001 ) {
- bbox->x0-=0.5*width;
- bbox->x1+=0.5*width;
- bbox->y0-=0.5*width;
- bbox->y1+=0.5*width;
- }
- }
+ // FIXME this code is incorrect
+ if (type == SPItem::VISUAL_BBOX && !item->style->stroke.isNone()) {
+ double scale = transform.descrim();
+ bbox->expandBy(0.5 * item->style->stroke_width.computed * scale);
}
+ return bbox;
}
static Inkscape::XML::Node *
@@ -592,8 +588,7 @@ sp_textpath_to_text(SPObject *tp)
{
SPObject *text = tp->parent;
- Geom::OptRect bbox;
- SP_ITEM(text)->invoke_bbox(bbox, SP_ITEM(text)->i2doc_affine(), TRUE);
+ Geom::OptRect bbox = SP_ITEM(text)->geometricBounds(SP_ITEM(text)->i2doc_affine());
if (!bbox) return;
Geom::Point xy = bbox->min();
diff --git a/src/sp-use.cpp b/src/sp-use.cpp
index 89df9130d..057c01ef1 100644
--- a/src/sp-use.cpp
+++ b/src/sp-use.cpp
@@ -49,7 +49,7 @@ static Inkscape::XML::Node *sp_use_write(SPObject *object, Inkscape::XML::Docume
static void sp_use_update(SPObject *object, SPCtx *ctx, guint flags);
static void sp_use_modified(SPObject *object, guint flags);
-static void sp_use_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags);
+static Geom::OptRect sp_use_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type);
static void sp_use_snappoints(SPItem const *item, std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs);
static void sp_use_print(SPItem *item, SPPrintContext *ctx);
static gchar *sp_use_description(SPItem *item);
@@ -276,10 +276,11 @@ sp_use_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::
return repr;
}
-static void
-sp_use_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, unsigned const flags)
+static Geom::OptRect
+sp_use_bbox(SPItem const *item, Geom::Affine const &transform, SPItem::BBoxType type)
{
SPUse const *use = SP_USE(item);
+ Geom::OptRect bbox;
if (use->child && SP_IS_ITEM(use->child)) {
SPItem *child = SP_ITEM(use->child);
@@ -287,15 +288,9 @@ sp_use_bbox(SPItem const *item, NRRect *bbox, Geom::Affine const &transform, uns
* Geom::Translate(use->x.computed,
use->y.computed)
* transform );
- Geom::OptRect optbbox;
- child->invoke_bbox_full( optbbox, ct, flags, FALSE);
- if (optbbox) {
- bbox->x0 = (*optbbox)[0][0];
- bbox->y0 = (*optbbox)[1][0];
- bbox->x1 = (*optbbox)[0][1];
- bbox->y1 = (*optbbox)[1][1];
- }
+ bbox = child->bounds(type, ct);
}
+ return bbox;
}
static void
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index d3d6c3db7..28d6f90be 100644
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
@@ -1942,7 +1942,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop,
bool didSomething = false;
- Geom::OptRect selectionBbox = selection->bounds();
+ Geom::OptRect selectionBbox = selection->visualBounds();
if (!selectionBbox) {
return false;
}
@@ -1963,7 +1963,7 @@ sp_selected_path_simplify_items(SPDesktop *desktop,
continue;
if (simplifyIndividualPaths) {
- Geom::OptRect itemBbox = item->getBounds(item->i2dt_affine());
+ Geom::OptRect itemBbox = item->desktopVisualBounds();
if (itemBbox) {
simplifySize = L2(itemBbox->dimensions());
} else {
diff --git a/src/spray-context.cpp b/src/spray-context.cpp
index 33fffb01f..68b71b21f 100644
--- a/src/spray-context.cpp
+++ b/src/spray-context.cpp
@@ -444,7 +444,7 @@ bool sp_spray_recursive(SPDesktop *desktop,
dr=dr*radius;
if (mode == SPRAY_MODE_COPY) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
SPItem *item_copied;
if(_fid <= population)
@@ -496,7 +496,7 @@ bool sp_spray_recursive(SPDesktop *desktop,
Inkscape::XML::Node *old_repr = father->getRepr();
Inkscape::XML::Node *parent = old_repr->parent();
- Geom::OptRect a = father->getBounds(father->i2doc_affine());
+ Geom::OptRect a = father->documentVisualBounds();
if (a) {
if (i == 2) {
Inkscape::XML::Node *copy1 = old_repr->duplicate(xml_doc);
@@ -534,7 +534,7 @@ bool sp_spray_recursive(SPDesktop *desktop,
}
}
} else if (mode == SPRAY_MODE_CLONE) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
if(_fid <= population) {
SPItem *item_copied;
diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp
index d64fa749a..a4a6b231a 100644
--- a/src/text-chemistry.cpp
+++ b/src/text-chemistry.cpp
@@ -432,8 +432,7 @@ text_unflow ()
/* Set style */
rtext->setAttribute("style", flowtext->getRepr()->attribute("style")); // fixme: transfer style attrs too; and from descendants
- Geom::OptRect bbox;
- flowtext->invoke_bbox(bbox, flowtext->i2doc_affine(), TRUE);
+ Geom::OptRect bbox = flowtext->geometricBounds(flowtext->i2doc_affine());
if (bbox) {
Geom::Point xy = bbox->min();
sp_repr_set_svg_double(rtext, "x", xy[Geom::X]);
diff --git a/src/text-context.cpp b/src/text-context.cpp
index 1468984a1..d2bf8c5f5 100644
--- a/src/text-context.cpp
+++ b/src/text-context.cpp
@@ -432,7 +432,7 @@ sp_text_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEve
} else {
SP_CTRLRECT(tc->indicator)->setColor(0x0000ff7f, false, 0);
}
- Geom::OptRect ibbox = item_ungrouped->getBboxDesktop();
+ Geom::OptRect ibbox = item_ungrouped->desktopVisualBounds();
if (ibbox) {
SP_CTRLRECT(tc->indicator)->setRectangle(*ibbox);
}
@@ -1635,7 +1635,7 @@ sp_text_context_update_cursor(SPTextContext *tc, bool scroll_to_see)
SP_CTRLRECT(tc->frame)->setColor(0x0000ff7f, false, 0);
}
sp_canvas_item_show(tc->frame);
- Geom::OptRect frame_bbox = frame->getBboxDesktop();
+ Geom::OptRect frame_bbox = frame->desktopVisualBounds();
if (frame_bbox) {
SP_CTRLRECT(tc->frame)->setRectangle(*frame_bbox);
}
diff --git a/src/tweak-context.cpp b/src/tweak-context.cpp
index 83598d8da..5d592b83d 100644
--- a/src/tweak-context.cpp
+++ b/src/tweak-context.cpp
@@ -442,7 +442,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
} else {
if (mode == TWEAK_MODE_MOVE) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
double x = Geom::L2(a->midpoint() - p)/radius;
if (a->contains(p)) x = 0;
@@ -455,7 +455,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
} else if (mode == TWEAK_MODE_MOVE_IN_OUT) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
double x = Geom::L2(a->midpoint() - p)/radius;
if (a->contains(p)) x = 0;
@@ -469,7 +469,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
} else if (mode == TWEAK_MODE_MOVE_JITTER) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
double dp = g_random_double_range(0, M_PI*2);
double dr = g_random_double_range(0, radius);
@@ -484,7 +484,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
} else if (mode == TWEAK_MODE_SCALE) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
double x = Geom::L2(a->midpoint() - p)/radius;
if (a->contains(p)) x = 0;
@@ -497,7 +497,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
} else if (mode == TWEAK_MODE_ROTATE) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
double x = Geom::L2(a->midpoint() - p)/radius;
if (a->contains(p)) x = 0;
@@ -510,7 +510,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
} else if (mode == TWEAK_MODE_MORELESS) {
- Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ Geom::OptRect a = item->documentVisualBounds();
if (a) {
double x = Geom::L2(a->midpoint() - p)/radius;
if (a->contains(p)) x = 0;
@@ -562,7 +562,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P
}
// skip those paths whose bboxes are entirely out of reach with our radius
- Geom::OptRect bbox = item->getBounds(item->i2doc_affine());
+ Geom::OptRect bbox = item->documentVisualBounds();
if (bbox) {
bbox->expandBy(radius);
if (!bbox->contains(p)) {
@@ -946,8 +946,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point,
if (!style) {
return false;
}
- Geom::OptRect bbox = item->getBounds(item->i2doc_affine(),
- SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = item->documentGeometricBounds();
if (!bbox) {
return false;
}
@@ -976,8 +975,7 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point,
if (this_force > 0.002) {
if (do_blur) {
- Geom::OptRect bbox = item->getBounds(item->i2doc_affine(),
- SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = item->documentGeometricBounds();
if (!bbox) {
return did;
}
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index 60379a966..adec1de5d 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -467,7 +467,7 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a
if (separately) {
for (GSList *i = const_cast<GSList*>(selection->itemList()) ; i ; i = i->next) {
SPItem *item = SP_ITEM(i->data);
- Geom::OptRect obj_size = item->getBboxDesktop();
+ Geom::OptRect obj_size = item->desktopVisualBounds();
if ( !obj_size ) {
continue;
}
@@ -476,7 +476,7 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a
}
// resize the selection as a whole
else {
- Geom::OptRect sel_size = selection->bounds();
+ Geom::OptRect sel_size = selection->visualBounds();
if ( sel_size ) {
sp_selection_scale_relative(selection, sel_size->midpoint(),
_getScale(desktop, min, max, *sel_size, apply_x, apply_y));
@@ -636,7 +636,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection)
}
}
- Geom::OptRect size = selection->bounds();
+ Geom::OptRect size = selection->visualBounds();
if (size) {
sp_repr_set_point(_clipnode, "min", size->min());
sp_repr_set_point(_clipnode, "max", size->max());
@@ -852,7 +852,7 @@ void ClipboardManagerImpl::_pasteDocument(SPDesktop *desktop, SPDocument *clipdo
target_document->ensureUpToDate();
// move selection either to original position (in_place) or to mouse pointer
- Geom::OptRect sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->visualBounds();
if (sel_bbox) {
// get offset of selection to original position of copied elements
Geom::Point pos_original;
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index 8728e2ef4..36d5a20d0 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -155,7 +155,7 @@ private :
selected.erase(master);
/*}*/
//Compute the anchor point
- Geom::OptRect b = thing->getBboxDesktop ();
+ Geom::OptRect b = thing->desktopVisualBounds();
if (b) {
mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
@@ -172,7 +172,7 @@ private :
case AlignAndDistribute::DRAWING:
{
- Geom::OptRect b = sp_desktop_document(desktop)->getRoot()->getBboxDesktop();
+ Geom::OptRect b = sp_desktop_document(desktop)->getRoot()->desktopVisualBounds();
if (b) {
mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
@@ -184,7 +184,7 @@ private :
case AlignAndDistribute::SELECTION:
{
- Geom::OptRect b = selection->bounds();
+ Geom::OptRect b = selection->visualBounds();
if (b) {
mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
@@ -211,7 +211,7 @@ private :
bool changed = false;
Geom::OptRect b;
if (sel_as_group)
- b = selection->bounds();
+ b = selection->visualBounds();
//Move each item in the selected list separately
for (std::list<SPItem *>::iterator it(selected.begin());
@@ -220,7 +220,7 @@ private :
{
sp_desktop_document (desktop)->ensureUpToDate();
if (!sel_as_group)
- b = (*it)->getBboxDesktop();
+ b = (*it)->desktopVisualBounds();
if (b) {
Geom::Point const sp(a.sx0 * b->min()[Geom::X] + a.sx1 * b->max()[Geom::X],
a.sy0 * b->min()[Geom::Y] + a.sy1 * b->max()[Geom::Y]);
@@ -261,7 +261,7 @@ ActionAlign::Coeffs const ActionAlign::_allCoeffs[10] = {
{0., 0., 1., 0., 0., 0., 0., 1.}
};
-BBoxSort::BBoxSort(SPItem *pItem, Geom::Rect bounds, Geom::Dim2 orientation, double kBegin, double kEnd) :
+BBoxSort::BBoxSort(SPItem *pItem, Geom::Rect const &bounds, Geom::Dim2 orientation, double kBegin, double kEnd) :
item(pItem),
bbox (bounds)
{
@@ -324,7 +324,7 @@ private :
it != selected.end();
++it)
{
- Geom::OptRect bbox = (*it)->getBboxDesktop();
+ Geom::OptRect bbox = (*it)->desktopVisualBounds();
if (bbox) {
sorted.push_back(BBoxSort(*it, *bbox, _orientation, _kBegin, _kEnd));
}
@@ -699,7 +699,7 @@ private :
//Check 2 or more selected objects
if (selected.size() < 2) return;
- Geom::OptRect sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->visualBounds();
if (!sel_bbox) {
return;
}
@@ -721,7 +721,7 @@ private :
++it)
{
sp_desktop_document (desktop)->ensureUpToDate();
- Geom::OptRect item_box = (*it)->getBboxDesktop ();
+ Geom::OptRect item_box = (*it)->desktopVisualBounds();
if (item_box) {
// find new center, staying within bbox
double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box)[Geom::X].extent() /2 +
@@ -1245,7 +1245,7 @@ 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++) {
- Geom::OptRect b = (*it)->getBboxDesktop ();
+ Geom::OptRect b = (*it)->desktopVisualBounds();
if (b) {
gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
if (dim > max) {
@@ -1262,7 +1262,7 @@ 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++) {
- Geom::OptRect b = (*it)->getBboxDesktop ();
+ Geom::OptRect b = (*it)->desktopVisualBounds();
if (b) {
gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
if (dim < max) {
diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h
index 99b96463c..22227cb60 100644
--- a/src/ui/dialog/align-and-distribute.h
+++ b/src/ui/dialog/align-and-distribute.h
@@ -120,7 +120,7 @@ struct BBoxSort
SPItem *item;
float anchor;
Geom::Rect bbox;
- BBoxSort(SPItem *pItem, Geom::Rect bounds, Geom::Dim2 orientation, double kBegin, double kEnd);
+ BBoxSort(SPItem *pItem, Geom::Rect const &bounds, Geom::Dim2 orientation, double kBegin, double kEnd);
BBoxSort(const BBoxSort &rhs);
};
bool operator< (const BBoxSort &a, const BBoxSort &b);
diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp
index 4f4093a99..0d7a0c687 100644
--- a/src/ui/dialog/filedialogimpl-win32.cpp
+++ b/src/ui/dialog/filedialogimpl-win32.cpp
@@ -992,10 +992,8 @@ bool FileOpenDialogImplWin32::set_svg_preview()
NRRectL bbox = {0, 0, scaledSvgWidth, scaledSvgHeight};
// write object bbox to area
- Geom::OptRect maybeArea(area);
svgDoc->ensureUpToDate();
- svgDoc->getRoot()->invoke_bbox( maybeArea,
- svgDoc->getRoot()->i2dt_affine(), TRUE);
+ Geom::OptRect maybeArea = area | svgDoc->getRoot()->desktopVisualBounds();
NRArena *const arena = NRArena::create();
diff --git a/src/ui/dialog/tile.cpp b/src/ui/dialog/tile.cpp
index 68ad9393c..5f19a2613 100644
--- a/src/ui/dialog/tile.cpp
+++ b/src/ui/dialog/tile.cpp
@@ -47,8 +47,8 @@ sp_compare_x_position(SPItem *first, SPItem *second)
using Geom::X;
using Geom::Y;
- Geom::OptRect a = first->getBounds(first->i2doc_affine());
- Geom::OptRect b = second->getBounds(second->i2doc_affine());
+ Geom::OptRect a = first->documentVisualBounds();
+ Geom::OptRect b = second->documentVisualBounds();
if ( !a || !b ) {
// FIXME?
@@ -87,8 +87,8 @@ sp_compare_x_position(SPItem *first, SPItem *second)
int
sp_compare_y_position(SPItem *first, SPItem *second)
{
- Geom::OptRect a = first->getBounds(first->i2doc_affine());
- Geom::OptRect b = second->getBounds(second->i2doc_affine());
+ Geom::OptRect a = first->documentVisualBounds();
+ Geom::OptRect b = second->documentVisualBounds();
if ( !a || !b ) {
// FIXME?
@@ -167,7 +167,7 @@ void TileDialog::Grid_Arrange ()
cnt=0;
for (; items != NULL; items = items->next) {
SPItem *item = SP_ITEM(items->data);
- Geom::OptRect b = item->getBounds(item->i2doc_affine());
+ Geom::OptRect b = item->documentVisualBounds();
if (!b) {
continue;
}
@@ -210,7 +210,7 @@ void TileDialog::Grid_Arrange ()
const GSList *sizes = sorted;
for (; sizes != NULL; sizes = sizes->next) {
SPItem *item = SP_ITEM(sizes->data);
- Geom::OptRect b = item->getBounds(item->i2doc_affine());
+ Geom::OptRect b = item->documentVisualBounds();
if (b) {
width = b->dimensions()[Geom::X];
height = b->dimensions()[Geom::Y];
@@ -267,7 +267,7 @@ void TileDialog::Grid_Arrange ()
}
- Geom::OptRect sel_bbox = selection->bounds();
+ Geom::OptRect sel_bbox = selection->visualBounds();
// Fit to bbox, calculate padding between rows accordingly.
if ( sel_bbox && !SpaceManualRadioButton.get_active() ){
#ifdef DEBUG_GRID_ARRANGE
@@ -317,7 +317,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h
for (; current_row != NULL; current_row = current_row->next) {
SPItem *item=SP_ITEM(current_row->data);
Inkscape::XML::Node *repr = item->getRepr();
- Geom::OptRect b = item->getBounds(item->i2doc_affine());
+ Geom::OptRect b = item->documentVisualBounds();
Geom::Point min;
if (b) {
width = b->dimensions()[Geom::X];
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index 92c8bd349..029a83ea5 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -467,7 +467,7 @@ Transformation::updatePageMove(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
if (!_check_move_relative.get_active()) {
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
double x = bbox->min()[Geom::X];
double y = bbox->min()[Geom::Y];
@@ -489,7 +489,7 @@ void
Transformation::updatePageScale(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
double w = bbox->dimensions()[Geom::X];
double h = bbox->dimensions()[Geom::Y];
@@ -519,7 +519,7 @@ void
Transformation::updatePageSkew(Inkscape::Selection *selection)
{
if (selection && !selection->isEmpty()) {
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
double w = bbox->dimensions()[Geom::X];
double h = bbox->dimensions()[Geom::Y];
@@ -616,7 +616,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
if (_check_move_relative.get_active()) {
sp_selection_move_relative(selection, x, y);
} else {
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
sp_selection_move_relative(selection,
x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]);
@@ -637,7 +637,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
it != selected.end();
++it)
{
- Geom::OptRect bbox = (*it)->getBboxDesktop();
+ Geom::OptRect bbox = (*it)->desktopVisualBounds();
if (bbox) {
sorted.push_back(BBoxSort(*it, *bbox, Geom::X, x > 0? 1. : 0., x > 0? 0. : 1.));
}
@@ -661,7 +661,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
it != selected.end();
++it)
{
- Geom::OptRect bbox = (*it)->getBboxDesktop();
+ Geom::OptRect bbox = (*it)->desktopVisualBounds();
if (bbox) {
sorted.push_back(BBoxSort(*it, *bbox, Geom::Y, y > 0? 1. : 0., y > 0? 0. : 1.));
}
@@ -680,7 +680,7 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
}
}
} else {
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
sp_selection_move_relative(selection,
x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]);
@@ -705,7 +705,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
Geom::Scale scale (0,0);
// the values are increments!
if (_units_scale.isAbsolute()) {
- Geom::OptRect bbox(item->getBboxDesktop());
+ Geom::OptRect bbox = item->desktopVisualBounds();
if (bbox) {
double new_width = scaleX;
if (fabs(new_width) < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object
@@ -723,7 +723,7 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
sp_item_scale_rel (item, scale);
}
} else {
- Geom::OptRect bbox(selection->bounds());
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
Geom::Point center(bbox->midpoint()); // use rotation center?
Geom::Scale scale (0,0);
@@ -792,7 +792,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
} else { // absolute displacement
double skewX = _scalar_skew_horizontal.getValue("px");
double skewY = _scalar_skew_vertical.getValue("px");
- Geom::OptRect bbox(item->getBboxDesktop());
+ Geom::OptRect bbox = item->desktopVisualBounds();
if (bbox) {
double width = bbox->dimensions()[Geom::X];
double height = bbox->dimensions()[Geom::Y];
@@ -801,7 +801,7 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
}
}
} else { // transform whole selection
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
boost::optional<Geom::Point> center = selection->center();
if ( bbox && center ) {
@@ -886,7 +886,7 @@ Transformation::onMoveRelativeToggled()
//g_message("onMoveRelativeToggled: %f, %f px\n", x, y);
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
if (_check_move_relative.get_active()) {
@@ -1026,7 +1026,7 @@ Transformation::onClear()
_scalar_move_horizontal.setValue(0);
_scalar_move_vertical.setValue(0);
} else {
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
_scalar_move_horizontal.setValue(bbox->min()[Geom::X], "px");
_scalar_move_vertical.setValue(bbox->min()[Geom::Y], "px");
diff --git a/src/ui/widget/style-subject.cpp b/src/ui/widget/style-subject.cpp
index f4780896b..f3a8478ea 100644
--- a/src/ui/widget/style-subject.cpp
+++ b/src/ui/widget/style-subject.cpp
@@ -147,7 +147,7 @@ StyleSubject::iterator StyleSubject::CurrentLayer::begin() {
Geom::OptRect StyleSubject::CurrentLayer::getBounds(SPItem::BBoxType type) {
SPObject *layer = _getLayer();
if (layer && SP_IS_ITEM(layer)) {
- return SP_ITEM(layer)->getBboxDesktop(type);
+ return SP_ITEM(layer)->desktopBounds(type);
} else {
return Geom::OptRect();
}
diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h
index 6d5c96350..73f818516 100644
--- a/src/ui/widget/style-subject.h
+++ b/src/ui/widget/style-subject.h
@@ -45,7 +45,7 @@ public:
virtual iterator begin() = 0;
virtual iterator end() { return iterator(NULL); }
- virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) = 0;
+ virtual Geom::OptRect getBounds(SPItem::BBoxType type) = 0;
virtual int queryStyle(SPStyle *query, int property) = 0;
virtual void setCSS(SPCSSAttr *css) = 0;
@@ -68,7 +68,7 @@ public:
~Selection();
virtual iterator begin();
- virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
+ virtual Geom::OptRect getBounds(SPItem::BBoxType type);
virtual int queryStyle(SPStyle *query, int property);
virtual void setCSS(SPCSSAttr *css);
@@ -89,7 +89,7 @@ public:
~CurrentLayer();
virtual iterator begin();
- virtual Geom::OptRect getBounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX);
+ virtual Geom::OptRect getBounds(SPItem::BBoxType type);
virtual int queryStyle(SPStyle *query, int property);
virtual void setCSS(SPCSSAttr *css);
diff --git a/src/unclump.cpp b/src/unclump.cpp
index e570e8fa7..6b9a8c574 100644
--- a/src/unclump.cpp
+++ b/src/unclump.cpp
@@ -34,7 +34,7 @@ unclump_center (SPItem *item)
return i->second;
}
- Geom::OptRect r = item->getBounds(item->i2dt_affine());
+ Geom::OptRect r = item->desktopVisualBounds();
if (r) {
Geom::Point const c = r->midpoint();
c_cache[item->getId()] = c;
@@ -53,7 +53,7 @@ unclump_wh (SPItem *item)
if ( i != wh_cache.end() ) {
wh = i->second;
} else {
- Geom::OptRect r = item->getBounds(item->i2dt_affine());
+ Geom::OptRect r = item->desktopVisualBounds();
if (r) {
wh = r->dimensions();
wh_cache[item->getId()] = wh;
diff --git a/src/verbs.cpp b/src/verbs.cpp
index e443e9917..ac8699654 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -1325,7 +1325,7 @@ ObjectVerb::perform( SPAction *action, void *data, void */*pdata*/ )
if (sel->isEmpty())
return;
- Geom::OptRect bbox = sel->bounds();
+ Geom::OptRect bbox = sel->visualBounds();
if (!bbox) {
return;
}
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp
index 08f0eadfb..fff9c0a5c 100644
--- a/src/widgets/desktop-widget.cpp
+++ b/src/widgets/desktop-widget.cpp
@@ -1881,7 +1881,7 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale)
Geom::Rect darea ( Geom::Point(-doc->getWidth(), -doc->getHeight()),
Geom::Point(2 * doc->getWidth(), 2 * doc->getHeight()) );
- Geom::OptRect deskarea = darea | doc->getRoot()->getBboxDesktop();
+ Geom::OptRect deskarea = darea | doc->getRoot()->desktopVisualBounds();
/* Canvas region we always show unconditionally */
Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64),
diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp
index a57b56b5c..9540b59d6 100644
--- a/src/widgets/icon.cpp
+++ b/src/widgets/icon.cpp
@@ -1102,8 +1102,7 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::Drawing &drawing,
if (object && SP_IS_ITEM(object)) {
SPItem *item = SP_ITEM(object);
// Find bbox in document
- Geom::Affine const i2doc(item->i2doc_affine());
- Geom::OptRect dbox = item->getBounds(i2doc);
+ Geom::OptRect dbox = item->documentVisualBounds();
if ( object->parent == NULL )
{
diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp
index 260c09c69..5f90a8997 100644
--- a/src/widgets/select-toolbar.cpp
+++ b/src/widgets/select-toolbar.cpp
@@ -70,7 +70,7 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel)
if ( sel && !sel->isEmpty() ) {
int prefs_bbox = prefs->getInt("/tools/bounding_box", 0);
SPItem::BBoxType bbox_type = (prefs_bbox ==0)?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
Geom::OptRect const bbox(sel->bounds(bbox_type));
if ( bbox ) {
UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(G_OBJECT(spw), "tracker"));
@@ -160,12 +160,12 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
document->ensureUpToDate ();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- Geom::OptRect bbox_vis = selection->bounds(SPItem::APPROXIMATE_BBOX);
- Geom::OptRect bbox_geom = selection->bounds(SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox_vis = selection->visualBounds();
+ Geom::OptRect bbox_geom = selection->geometricBounds();
int prefs_bbox = prefs->getInt("/tools/bounding_box");
SPItem::BBoxType bbox_type = (prefs_bbox == 0)?
- SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX;
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
Geom::OptRect bbox_user = selection->bounds(bbox_type);
if ( !bbox_user ) {
@@ -247,10 +247,10 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
int transform_stroke = prefs->getBool("/options/transform/stroke", true) ? 1 : 0;
Geom::Affine scaler;
- if (bbox_type == SPItem::APPROXIMATE_BBOX) {
+ if (bbox_type == SPItem::VISUAL_BBOX) {
scaler = get_scale_transform_with_unequal_stroke (*bbox_vis, *bbox_geom, transform_stroke, x0, y0, x1, y1);
} else {
- // get_scale_transform_with_stroke() is intended for VISUAL (or APPROXIMATE) bounding boxes, not geometrical ones!
+ // get_scale_transform_with_stroke() is intended for visual bounding boxes, not geometrical ones!
// we'll trick it into using a geometric bounding box though, by setting the stroke width to zero
scaler = get_scale_transform_with_uniform_stroke (*bbox_user, 0, false, x0, y0, x1, y1);
}
diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp
index 8d9b9b429..bb9391c78 100644
--- a/src/widgets/stroke-style.cpp
+++ b/src/widgets/stroke-style.cpp
@@ -191,8 +191,7 @@ sp_marker_prev_new(unsigned psize, gchar const *mname,
SPItem *item = SP_ITEM(object);
// Find object's bbox in document
- Geom::Affine const i2doc(item->i2doc_affine());
- Geom::OptRect dbox = item->getBounds(i2doc);
+ Geom::OptRect dbox = item->documentVisualBounds();
if (!dbox) {
return NULL;
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 26947979d..61c7c8e88 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -5951,7 +5951,7 @@ static void lpetool_toggle_set_bbox(GtkToggleAction *act, gpointer data)
SPDesktop *desktop = static_cast<SPDesktop *>(data);
Inkscape::Selection *selection = desktop->selection;
- Geom::OptRect bbox = selection->bounds();
+ Geom::OptRect bbox = selection->visualBounds();
if (bbox) {
Geom::Point A(bbox->min());
@@ -6799,8 +6799,7 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl )
axis = Geom::Y;
}
- Geom::OptRect bbox
- = item->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX);
+ Geom::OptRect bbox = item->geometricBounds();
if (!bbox)
continue;
double width = bbox->dimensions()[axis];