summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-08-16 01:40:10 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-08-16 01:40:10 +0000
commit66bab1f2b80ff441643fd5fdeb5bade70fb5aa8c (patch)
tree60877c840f6ea4a15a6dea4bb3fcaead3ae7b353 /src/display
parentCorrectly invalidate cache of objects with background-accessing filters (diff)
downloadinkscape-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)
Diffstat (limited to 'src/display')
-rw-r--r--src/display/drawing-item.cpp6
-rw-r--r--src/display/drawing-item.h2
-rw-r--r--src/display/drawing-text.cpp39
-rw-r--r--src/display/drawing-text.h2
-rw-r--r--src/display/nr-filter-gaussian.cpp4
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");
};
}