summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/display/sp-canvas.cpp15
-rw-r--r--src/libnr/nr-convex-hull.h36
-rw-r--r--src/libnrtype/FontInstance.cpp14
-rwxr-xr-xsrc/libnrtype/Layout-TNG-OutIter.cpp2
-rwxr-xr-xsrc/libnrtype/Layout-TNG-Output.cpp30
-rwxr-xr-xsrc/libnrtype/Layout-TNG.h2
-rw-r--r--src/libnrtype/RasterFont.cpp32
-rw-r--r--src/libnrtype/font-instance.h3
-rw-r--r--src/selection.cpp28
-rw-r--r--src/sp-conn-end.cpp24
-rw-r--r--src/ui/dialog/align-and-distribute.cpp18
-rw-r--r--src/ui/dialog/align-and-distribute.h4
-rw-r--r--src/widgets/font-selector.cpp12
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<NR::Rect> 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<Rect> const &bounds() const {
return _bounds;
}
private:
- Rect _bounds;
+ Point _initial;
+ Maybe<Rect> _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<NR::Rect> 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<NR::Rect> 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<NR::Rect> 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<NR::Rect> 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<NR::Rect> 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 <libnrtype/nrtype-forward.h>
#include <libnrtype/font-style.h>
#include <livarot/livarot-forward.h>
+#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<NR::Rect> 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<NR::Point> Selection::getSnapPoints() const {
std::vector<NR::Point> Selection::getSnapPointsConvexHull() const {
GSList const *items = const_cast<Selection *>(this)->itemList();
+
std::vector<NR::Point> p;
for (GSList const *iter = items; iter != NULL; iter = iter->next) {
sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p));
}
- std::vector<NR::Point>::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<NR::Point> pHull;
+ if (!p.empty()) {
+ std::vector<NR::Point>::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<NR::Point> pHull(4);
- pHull[0] = rHull.corner(0);
- pHull[1] = rHull.corner(1);
- pHull[2] = rHull.corner(2);
- pHull[3] = rHull.corner(3);
+ NR::Maybe<NR::Rect> 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<NR::Rect> 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<NR::Rect> 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<NR::Rect> item_box = sp_item_bbox_desktop (*it);
if (item_box) {
// find new center, staying within bbox
- double x = _dialog.randomize_bbox.min()[NR::X] + item_box->extent(NR::X)/2 +
- g_random_double_range (0, _dialog.randomize_bbox.extent(NR::X) - item_box->extent(NR::X));
- double y = _dialog.randomize_bbox.min()[NR::Y] + item_box->extent(NR::Y)/2 +
- g_random_double_range (0, _dialog.randomize_bbox.extent(NR::Y) - item_box->extent(NR::Y));
+ 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<SPItem *>::iterator find_master(std::list <SPItem *> &list, bool horizontal);
void setMode(bool nodeEdit);
- NR::Rect randomize_bbox;
- bool randomize_bbox_set;
-
+ NR::Maybe<NR::Rect> 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<NR::Rect> 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 ) {