diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-08-16 01:40:10 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-08-16 01:40:10 +0000 |
| commit | 66bab1f2b80ff441643fd5fdeb5bade70fb5aa8c (patch) | |
| tree | 60877c840f6ea4a15a6dea4bb3fcaead3ae7b353 | |
| parent | Correctly invalidate cache of objects with background-accessing filters (diff) | |
| download | inkscape-66bab1f2b80ff441643fd5fdeb5bade70fb5aa8c.tar.gz inkscape-66bab1f2b80ff441643fd5fdeb5bade70fb5aa8c.zip | |
Add sanity checks against singular transforms in the drawing tree.
Fixes LP #825767.
Fixed bugs:
- https://launchpad.net/bugs/825767
(bzr r10347.1.33)
| -rw-r--r-- | src/display/drawing-item.cpp | 6 | ||||
| -rw-r--r-- | src/display/drawing-item.h | 2 | ||||
| -rw-r--r-- | src/display/drawing-text.cpp | 39 | ||||
| -rw-r--r-- | src/display/drawing-text.h | 2 | ||||
| -rw-r--r-- | src/display/nr-filter-gaussian.cpp | 4 |
5 files changed, 15 insertions, 38 deletions
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index f28894c14..1195bc56c 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -66,8 +66,7 @@ DrawingItem::DrawingItem(Drawing &drawing) , _propagate(0) // , _renders_opacity(0) , _pick_children(0) -{ -} +{} DrawingItem::~DrawingItem() { @@ -120,7 +119,7 @@ DrawingItem * DrawingItem::parent() const { // initially I wanted to return NULL if we are a clip or mask child, - // but the previous behavior was just to return the parent + // but the previous behavior was just to return the parent regardless of child type return _parent; } @@ -442,6 +441,7 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag // If we are invisible, return immediately if (!_visible) return; + if (_ctm.isSingular(NR_EPSILON)) return; // TODO convert outline rendering to a separate virtual function if (outline) { diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index 6d142c061..abc69be02 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -112,7 +112,7 @@ public: protected: enum ChildType { - CHILD_ORPHAN = 0, // no parent + CHILD_ORPHAN = 0, // no parent - implies _parent == NULL CHILD_NORMAL = 1, // contained in _children of parent CHILD_CLIP = 2, // referenced by _clip member of parent CHILD_MASK = 3, // referenced by _mask member of parent diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index 21588cc4f..5e6396df1 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -23,7 +23,6 @@ namespace Inkscape { DrawingGlyphs::DrawingGlyphs(Drawing &drawing) : DrawingItem(drawing) - , _glyph_transform(NULL) , _font(NULL) , _glyph(0) {} @@ -34,7 +33,6 @@ DrawingGlyphs::~DrawingGlyphs() _font->Unref(); _font = NULL; } - delete _glyph_transform; } void @@ -42,12 +40,7 @@ DrawingGlyphs::setGlyph(font_instance *font, int glyph, Geom::Affine const &tran { _markForRendering(); - if (trans.isIdentity()) { - delete _glyph_transform; // delete NULL; is safe - _glyph_transform = NULL; - } else { - _glyph_transform = new Geom::Affine(trans); - } + setTransform(trans); if (font) font->Ref(); if (_font) _font->Unref(); @@ -70,12 +63,7 @@ DrawingGlyphs::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, return STATE_ALL; } - Geom::OptRect b; - Geom::Affine t = _glyph_transform ? *_glyph_transform * ctx.ctm : ctx.ctm; - _x = t[4]; - _y = t[5]; - - b = bounds_exact_transformed(*_font->PathVector(_glyph), t); + Geom::OptRect b = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); if (b && ggroup->_nrstyle.stroke.type != NRStyle::PAINT_NONE) { float width, scale; scale = ctx.ctm.descrim(); @@ -165,21 +153,19 @@ void DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags) { if (_drawing.outline()) { - DrawingContext::Save save(ct); guint32 rgba = _drawing.outlinecolor; + Inkscape::DrawingContext::Save save(ct); ct.setSource(rgba); ct.setTolerance(1.25); // low quality, but good enough for outline mode - ct.newPath(); - ct.transform(_ctm); for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); if (!g) throw InvalidItemException(); Inkscape::DrawingContext::Save save(ct); - if (g->_glyph_transform) { - ct.transform(*g->_glyph_transform); - } + // skip glpyhs with singular transforms + if (g->_ctm.isSingular()) continue; + ct.transform(g->_ctm); ct.path(*g->_font->PathVector(g->_glyph)); ct.fill(); } @@ -189,9 +175,6 @@ DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned // NOTE: this is very similar to drawing-shape.cpp; the only difference is in path feeding bool has_stroke, has_fill; - Inkscape::DrawingContext::Save save(ct); - ct.transform(_ctm); - has_fill = _nrstyle.prepareFill(ct, _paintbox); has_stroke = _nrstyle.prepareStroke(ct, _paintbox); @@ -201,9 +184,8 @@ DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned if (!g) throw InvalidItemException(); Inkscape::DrawingContext::Save save(ct); - if (g->_glyph_transform) { - ct.transform(*g->_glyph_transform); - } + if (g->_ctm.isSingular()) continue; + ct.transform(g->_ctm); ct.path(*g->_font->PathVector(g->_glyph)); } @@ -232,16 +214,13 @@ DrawingText::_clipItem(DrawingContext &ct, Geom::IntRect const &area) ct.setFillRule(CAIRO_FILL_RULE_WINDING); } } - ct.transform(_ctm); for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); if (!g) throw InvalidItemException(); Inkscape::DrawingContext::Save save(ct); - if (g->_glyph_transform) { - ct.transform(*g->_glyph_transform); - } + ct.transform(g->_ctm); ct.path(*g->_font->PathVector(g->_glyph)); } ct.fill(); diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h index faa33057c..07962365c 100644 --- a/src/display/drawing-text.h +++ b/src/display/drawing-text.h @@ -34,10 +34,8 @@ protected: unsigned flags, unsigned reset); virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); - Geom::Affine *_glyph_transform; font_instance *_font; int _glyph; - float _x, _y; friend class DrawingText; }; diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp index 988a8479e..19cf51772 100644 --- a/src/display/nr-filter-gaussian.cpp +++ b/src/display/nr-filter-gaussian.cpp @@ -511,7 +511,7 @@ gaussian_pass_IIR(Geom::Dim2 d, double deviation, cairo_surface_t *src, cairo_su w, h, b, M, tmpdata, num_threads); break; default: - assert(false); + g_warning("gaussian_pass_IIR: unsupported image format"); }; } @@ -544,7 +544,7 @@ gaussian_pass_FIR(Geom::Dim2 d, double deviation, cairo_surface_t *src, cairo_su w, h, &kernel[0], scr_len, num_threads); break; default: - assert(false); + g_warning("gaussian_pass_FIR: unsupported image format"); }; } |
