From b3b33c740c63c9e07ad171bc8c67bae552ebdd7b Mon Sep 17 00:00:00 2001 From: mental Date: Sun, 11 Mar 2007 21:23:04 +0000 Subject: [PATCH] Eliminate remaining sources of empty NR::Rects --- src/display/sp-canvas.cpp | 15 +++++++---- src/libnr/nr-convex-hull.h | 36 +++++++++++++++++++------- src/libnrtype/FontInstance.cpp | 14 +++++----- src/libnrtype/Layout-TNG-OutIter.cpp | 2 +- src/libnrtype/Layout-TNG-Output.cpp | 30 +++++++++++---------- src/libnrtype/Layout-TNG.h | 2 +- src/libnrtype/RasterFont.cpp | 32 +++++++++++++---------- src/libnrtype/font-instance.h | 3 ++- src/selection.cpp | 28 +++++++++++--------- src/sp-conn-end.cpp | 24 ++++++++++------- src/ui/dialog/align-and-distribute.cpp | 18 ++++++------- src/ui/dialog/align-and-distribute.h | 4 +-- src/widgets/font-selector.cpp | 12 +++++---- 13 files changed, 129 insertions(+), 91 deletions(-) diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 75ffeed84..559515e03 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -744,11 +744,16 @@ sp_canvas_group_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned i } } - NR::Rect const &bounds = corners.bounds(); - item->x1 = bounds.min()[NR::X]; - item->y1 = bounds.min()[NR::Y]; - item->x2 = bounds.max()[NR::X]; - item->y2 = bounds.max()[NR::Y]; + NR::Maybe const bounds = corners.bounds(); + if (bounds) { + item->x1 = bounds->min()[NR::X]; + item->y1 = bounds->min()[NR::Y]; + item->x2 = bounds->max()[NR::X]; + item->y2 = bounds->max()[NR::Y]; + } else { + item->x1 = item->x2 = corners.midpoint()[NR::X]; + item->y1 = item->y2 = corners.midpoint()[NR::Y]; + } } /** diff --git a/src/libnr/nr-convex-hull.h b/src/libnr/nr-convex-hull.h index 28cde376d..fef885f00 100644 --- a/src/libnr/nr-convex-hull.h +++ b/src/libnr/nr-convex-hull.h @@ -17,31 +17,49 @@ namespace NR { class ConvexHull { public: - explicit ConvexHull(Point const &p) : _bounds(p, p) {} + explicit ConvexHull(Point const &p) + : _initial(p) {} Point midpoint() const { - return _bounds.midpoint(); + if (_bounds) { + return _bounds->midpoint(); + } else { + return _initial; + } } void add(Point const &p) { - _bounds.expandTo(p); + if (_bounds) { + _bounds->expandTo(p); + } else if ( p != _initial ) { + _bounds = Rect(_initial, p); + } } void add(Rect const &p) { // Note that this is a hack. when convexhull actually works // you will need to add all four points. - _bounds.expandTo(p.min()); - _bounds.expandTo(p.max()); + if (_bounds) { + _bounds = union_bounds(*_bounds, p); + } else { + _bounds = p; + _bounds->expandTo(_initial); + } } void add(ConvexHull const &h) { - _bounds.expandTo(h._bounds); + if (h._bounds) { + add(*h._bounds); + } else { + add(h._initial); + } } - - Rect const &bounds() const { + + Maybe const &bounds() const { return _bounds; } private: - Rect _bounds; + Point _initial; + Maybe _bounds; }; } /* namespace NR */ diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 574a76f62..419a631a5 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -611,7 +611,7 @@ bool font_instance::FontSlope(double &run, double &rise) return true; } -NR::Rect font_instance::BBox(int glyph_id) +NR::Maybe font_instance::BBox(int glyph_id) { int no=-1; if ( id_to_no.find(glyph_id) == id_to_no.end() ) { @@ -624,11 +624,13 @@ NR::Rect font_instance::BBox(int glyph_id) } else { no=id_to_no[glyph_id]; } - if ( no < 0 ) return NR::Rect(NR::Point(0,0),NR::Point(0,0)); - NR::Point rmin(glyphs[no].bbox[0],glyphs[no].bbox[1]); - NR::Point rmax(glyphs[no].bbox[2],glyphs[no].bbox[3]); - NR::Rect res(rmin,rmax); - return res; + if ( no < 0 ) { + return NR::Nothing(); + } else { + NR::Point rmin(glyphs[no].bbox[0],glyphs[no].bbox[1]); + NR::Point rmax(glyphs[no].bbox[2],glyphs[no].bbox[3]); + return NR::Rect(rmin, rmax); + } } Path* font_instance::Outline(int glyph_id,Path* copyInto) diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp index 8c525084e..167352bd3 100755 --- a/src/libnrtype/Layout-TNG-OutIter.cpp +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -201,7 +201,7 @@ Layout::iterator Layout::sourceToIterator(void *source_cookie) const return sourceToIterator(source_cookie, Glib::ustring::const_iterator(std::string::const_iterator(NULL))); } -NR::Rect Layout::glyphBoundingBox(iterator const &it, double *rotation) const +NR::Maybe Layout::glyphBoundingBox(iterator const &it, double *rotation) const { if (rotation) *rotation = _glyphs[it._glyph_index].rotation; return _glyphs[it._glyph_index].span(this).font->BBox(_glyphs[it._glyph_index].glyph); diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 5152909f8..68d7752c3 100755 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -113,20 +113,22 @@ void Layout::getBoundingBox(NRRect *bounding_box, NR::Matrix const &transform, i _getGlyphTransformMatrix(glyph_index, &glyph_matrix); NR::Matrix total_transform = glyph_matrix; total_transform *= transform; - NR::Rect glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph); - NR::Point bmi = glyph_rect.min(), bma = glyph_rect.max(); - NR::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 = NR::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]; + NR::Maybe glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph); + if (glyph_rect) { + NR::Point bmi = glyph_rect->min(), bma = glyph_rect->max(); + NR::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 = NR::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]; + } } } diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 48b01eae5..3eed1fc43 100755 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -443,7 +443,7 @@ public: /** Returns the bounding box of the given glyph, and its rotation. The centre of rotation is the horizontal centre of the box at the text baseline. */ - NR::Rect glyphBoundingBox(iterator const &it, double *rotation) const; + NR::Maybe glyphBoundingBox(iterator const &it, double *rotation) const; /** Returns the zero-based line number of the character pointed to by \a it. */ diff --git a/src/libnrtype/RasterFont.cpp b/src/libnrtype/RasterFont.cpp index 68ecb2e4d..c9af6621f 100644 --- a/src/libnrtype/RasterFont.cpp +++ b/src/libnrtype/RasterFont.cpp @@ -107,20 +107,24 @@ void raster_font::BBox(int glyph_id,NRRect *area) { area->x0=area->y0=area->x1=area->y1=0; if ( daddy == NULL ) return; - NR::Rect res=daddy->BBox(glyph_id); - NR::Point bmi=res.min(),bma=res.max(); - NR::Point tlp(bmi[0],bmi[1]),trp(bma[0],bmi[1]),blp(bmi[0],bma[1]),brp(bma[0],bma[1]); - tlp=tlp*style.transform; - trp=trp*style.transform; - blp=blp*style.transform; - brp=brp*style.transform; - res=NR::Rect(tlp,trp); - res.expandTo(blp); - res.expandTo(brp); - area->x0=(res.min())[0]; - area->y0=(res.min())[1]; - area->x1=(res.max())[0]; - area->y1=(res.max())[1]; + NR::Maybe res=daddy->BBox(glyph_id); + if (res) { + NR::Point bmi=res->min(),bma=res->max(); + NR::Point tlp(bmi[0],bmi[1]),trp(bma[0],bmi[1]),blp(bmi[0],bma[1]),brp(bma[0],bma[1]); + tlp=tlp*style.transform; + trp=trp*style.transform; + blp=blp*style.transform; + brp=brp*style.transform; + *res=NR::Rect(tlp,trp); + res->expandTo(blp); + res->expandTo(brp); + area->x0=(res->min())[0]; + area->y0=(res->min())[1]; + area->x1=(res->max())[0]; + area->y1=(res->max())[1]; + } else { + nr_rect_d_set_empty(area); + } } void raster_font::LoadRasterGlyph(int glyph_id) diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h index ec58ce1d7..4bec0203d 100644 --- a/src/libnrtype/font-instance.h +++ b/src/libnrtype/font-instance.h @@ -12,6 +12,7 @@ #include #include #include +#include "libnr/nr-rect.h" // the font_instance are the template of several raster_font; they provide metrics and outlines // that are drawn by the raster_font, so the raster_font needs info relative to the way the @@ -77,7 +78,7 @@ public: bool FontMetrics(double &ascent, double &descent, double &leading); bool FontSlope(double &run, double &rise); // for generating slanted cursors for oblique fonts - NR::Rect BBox(int glyph_id); + NR::Maybe BBox(int glyph_id); // creates a rasterfont for the given style raster_font* RasterFont(NR::Matrix const &trs, double stroke_width, diff --git a/src/selection.cpp b/src/selection.cpp index c6b307c3b..201661eec 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -380,24 +380,28 @@ std::vector Selection::getSnapPoints() const { std::vector Selection::getSnapPointsConvexHull() const { GSList const *items = const_cast(this)->itemList(); + std::vector p; for (GSList const *iter = items; iter != NULL; iter = iter->next) { sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p)); } - std::vector::iterator i; - NR::ConvexHull cvh(*(p.begin())); - for (i = p.begin(); i != p.end(); i++) { - // these are the points we get back - cvh.add(*i); - } + std::vector pHull; + if (!p.empty()) { + std::vector::iterator i; + NR::ConvexHull cvh(p.front()); + for (i = p.begin(); i != p.end(); i++) { + // these are the points we get back + cvh.add(*i); + } - NR::Rect rHull = cvh.bounds(); - std::vector pHull(4); - pHull[0] = rHull.corner(0); - pHull[1] = rHull.corner(1); - pHull[2] = rHull.corner(2); - pHull[3] = rHull.corner(3); + NR::Maybe rHull = cvh.bounds(); + if (rHull) { + for ( unsigned i = 0 ; i < 4 ; ++i ) { + pHull.push_back(rHull->corner(i)); + } + } + } return pHull; } diff --git a/src/sp-conn-end.cpp b/src/sp-conn-end.cpp index 7a8a60dd0..dd6497526 100644 --- a/src/sp-conn-end.cpp +++ b/src/sp-conn-end.cpp @@ -71,12 +71,14 @@ sp_conn_end_move_compensate(NR::Matrix const *mp, SPItem *moved_item, }; for (unsigned h = 0; h < 2; ++h) { NR::Maybe bbox = h2attItem[h]->getBounds(NR::identity()); - if (bbox) { - h2bbox_icoordsys[h] = *bbox; - } else { - // FIXME - h2bbox_icoordsys[h] = NR::Rect(NR::Point(0, 0), NR::Point(0, 0)); + if (!bbox) { + if (updatePathRepr) { + path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + path->updateRepr(); + } + return; } + h2bbox_icoordsys[h] = *bbox; h2i2anc[h] = i2anc_affine(h2attItem[h], ancestor); h2endPt_icoordsys[h] = h2bbox_icoordsys[h].midpoint(); } @@ -112,13 +114,15 @@ sp_conn_end_move_compensate(NR::Matrix const *mp, SPItem *moved_item, NR::Rect otherpt_rect = NR::Rect(other_endpt, other_endpt); NR::Rect h2bbox_icoordsys[2] = { otherpt_rect, otherpt_rect }; NR::Maybe bbox = h2attItem[ind]->getBounds(NR::identity()); - if (bbox) { - h2bbox_icoordsys[ind] = *bbox; - } else { - // FIXME - h2bbox_icoordsys[ind] = NR::Rect(NR::Point(0, 0), NR::Point(0, 0)); + if (!bbox) { + if (updatePathRepr) { + path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + path->updateRepr(); + } + return; } + h2bbox_icoordsys[ind] = *bbox; h2i2anc = i2anc_affine(h2attItem[ind], ancestor); h2endPt_icoordsys[ind] = h2bbox_icoordsys[ind].midpoint(); diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 7c5908e58..34fa910cc 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -602,9 +602,8 @@ private : // This bbox is cached between calls to randomize, so that there's no growth nor shrink // nor drift on sequential randomizations. Discard cache on global (or better active // desktop's) selection_change signal. - if (!_dialog.randomize_bbox_set) { + if (!_dialog.randomize_bbox) { _dialog.randomize_bbox = *sel_bbox; - _dialog.randomize_bbox_set = true; } // see comment in ActionAlign above @@ -619,10 +618,10 @@ private : NR::Maybe item_box = sp_item_bbox_desktop (*it); if (item_box) { // find new center, staying within bbox - double x = _dialog.randomize_bbox.min()[NR::X] + item_box->extent(NR::X)/2 + - g_random_double_range (0, _dialog.randomize_bbox.extent(NR::X) - item_box->extent(NR::X)); - double y = _dialog.randomize_bbox.min()[NR::Y] + item_box->extent(NR::Y)/2 + - g_random_double_range (0, _dialog.randomize_bbox.extent(NR::Y) - item_box->extent(NR::Y)); + double x = _dialog.randomize_bbox->min()[NR::X] + item_box->extent(NR::X)/2 + + g_random_double_range (0, _dialog.randomize_bbox->extent(NR::X) - item_box->extent(NR::X)); + double y = _dialog.randomize_bbox->min()[NR::Y] + item_box->extent(NR::Y)/2 + + g_random_double_range (0, _dialog.randomize_bbox->extent(NR::Y) - item_box->extent(NR::Y)); // displacement is the new center minus old: NR::Point t = NR::Point (x, y) - 0.5*(item_box->max() + item_box->min()); sp_item_move_rel(*it, NR::translate(t)); @@ -767,7 +766,7 @@ void on_tool_changed(Inkscape::Application *inkscape, SPEventContext *context, A void on_selection_changed(Inkscape::Application *inkscape, Inkscape::Selection *selection, AlignAndDistribute *daad) { - daad->randomize_bbox_set = false; + daad->randomize_bbox = NR::Nothing(); } ///////////////////////////////////////////////////////// @@ -777,7 +776,7 @@ void on_selection_changed(Inkscape::Application *inkscape, Inkscape::Selection * AlignAndDistribute::AlignAndDistribute() : Dialog ("dialogs.align", SP_VERB_DIALOG_ALIGN_DISTRIBUTE), - randomize_bbox (NR::Point (0, 0), NR::Point (0, 0)), + randomize_bbox(NR::Nothing()), _alignFrame(_("Align")), _distributeFrame(_("Distribute")), _removeOverlapFrame(_("Remove overlaps")), @@ -941,8 +940,7 @@ AlignAndDistribute::AlignAndDistribute() // Connect to the global selection change, to invalidate cached randomize_bbox g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this); - randomize_bbox = NR::Rect (NR::Point (0, 0), NR::Point (0, 0)); - randomize_bbox_set = false; + randomize_bbox = NR::Nothing(); show_all_children(); diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index 69fc17673..6d22071f3 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -65,9 +65,7 @@ public: std::list::iterator find_master(std::list &list, bool horizontal); void setMode(bool nodeEdit); - NR::Rect randomize_bbox; - bool randomize_bbox_set; - + NR::Maybe randomize_bbox; protected: diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 4c84eeb24..bb155fc7c 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -626,11 +626,13 @@ static gint sp_font_preview_expose(GtkWidget *widget, GdkEventExpose *event) hpos[len] = base_pt[0]; len++; if ( curF ) { - NR::Rect nbbox = curF->BBox(str_text->glyph_text[i].gl); - bbox.x0 = MIN(bbox.x0, base_pt[NR::X] + theSize * (nbbox.min())[0]); - bbox.y0 = MIN(bbox.y0, base_pt[NR::Y] - theSize * (nbbox.max())[1]); - bbox.x1 = MAX(bbox.x1, base_pt[NR::X] + theSize * (nbbox.max())[0]); - bbox.y1 = MAX(bbox.y1, base_pt[NR::Y] - theSize * (nbbox.min())[1]); + NR::Maybe nbbox = curF->BBox(str_text->glyph_text[i].gl); + if (nbbox) { + bbox.x0 = MIN(bbox.x0, base_pt[NR::X] + theSize * (nbbox->min())[0]); + bbox.y0 = MIN(bbox.y0, base_pt[NR::Y] - theSize * (nbbox->max())[1]); + bbox.x1 = MAX(bbox.x1, base_pt[NR::X] + theSize * (nbbox->max())[0]); + bbox.y1 = MAX(bbox.y1, base_pt[NR::Y] - theSize * (nbbox->min())[1]); + } } } if ( curF ) { -- 2.30.2