summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-02-08 19:12:21 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-02-08 19:12:21 +0000
commit0912ab9a77d4b3f26975f3ca94e14ee72b63d6b6 (patch)
treec9342a4d89751b8157c9fe8f9cdd9404114aaae0 /src
parentupdate to trunk (diff)
parentFix for Bug #879058 (Spray Single Path Mode includes original object). (diff)
downloadinkscape-0912ab9a77d4b3f26975f3ca94e14ee72b63d6b6.tar.gz
inkscape-0912ab9a77d4b3f26975f3ca94e14ee72b63d6b6.zip
update to trunk
(bzr r11950.1.250)
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/Makefile_insert3
-rw-r--r--src/display/canvas-arena.cpp8
-rw-r--r--src/display/drawing-context.cpp22
-rw-r--r--src/display/drawing-context.h6
-rw-r--r--src/display/drawing-group.cpp12
-rw-r--r--src/display/drawing-group.h4
-rw-r--r--src/display/drawing-image.cpp52
-rw-r--r--src/display/drawing-image.h2
-rw-r--r--src/display/drawing-item.cpp96
-rw-r--r--src/display/drawing-item.h10
-rw-r--r--src/display/drawing-shape.cpp54
-rw-r--r--src/display/drawing-shape.h4
-rw-r--r--src/display/drawing-surface.cpp24
-rw-r--r--src/display/drawing-surface.h2
-rw-r--r--src/display/drawing-text.cpp120
-rw-r--r--src/display/drawing-text.h8
-rw-r--r--src/display/drawing.cpp16
-rw-r--r--src/display/drawing.h2
-rw-r--r--src/display/nr-filter-image.cpp12
-rw-r--r--src/display/nr-filter-slot.cpp6
-rw-r--r--src/display/nr-filter-slot.h2
-rw-r--r--src/display/nr-filter.cpp4
-rw-r--r--src/display/nr-filter.h4
-rw-r--r--src/display/nr-style.cpp32
-rw-r--r--src/display/nr-style.h8
-rw-r--r--src/document.cpp12
-rw-r--r--src/extension/internal/emf-inout.cpp2
-rw-r--r--src/extension/internal/emf-inout.h1
-rw-r--r--src/extension/internal/emf-print.cpp40
-rw-r--r--src/extension/internal/emf-print.h3
-rw-r--r--src/extension/internal/image-resolution.cpp6
-rw-r--r--src/extension/internal/text_reassemble.c137
-rw-r--r--src/extension/internal/text_reassemble.h7
-rw-r--r--src/extension/internal/wmf-inout.cpp44
-rw-r--r--src/helper/pixbuf-ops.cpp4
-rw-r--r--src/helper/png-write.cpp12
-rw-r--r--src/libuemf/README6
-rw-r--r--src/libuemf/uemf_utf.c95
-rw-r--r--src/libuemf/uwmf.c22
-rw-r--r--src/marker.cpp267
-rw-r--r--src/marker.h15
-rw-r--r--src/sp-image.cpp347
-rw-r--r--src/sp-image.h14
-rw-r--r--src/sp-mesh-array.cpp4
-rw-r--r--src/sp-pattern.cpp67
-rw-r--r--src/sp-pattern.h6
-rw-r--r--src/sp-root.cpp327
-rw-r--r--src/sp-root.h15
-rw-r--r--src/sp-symbol.cpp234
-rw-r--r--src/sp-symbol.h15
-rw-r--r--src/ui/cache/svg_preview_cache.cpp4
-rw-r--r--src/ui/dialog/clonetiler.cpp4
-rw-r--r--src/ui/tools/flood-tool.cpp12
-rw-r--r--src/ui/tools/spray-tool.cpp2
-rw-r--r--src/uri-references.cpp13
-rw-r--r--src/viewbox.cpp277
-rw-r--r--src/viewbox.h66
-rw-r--r--src/widgets/icon.cpp4
59 files changed, 1162 insertions, 1438 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 54b15d342..d1a3d194e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -78,7 +78,7 @@ set(sp_SRC
sp-use-reference.cpp
sp-use.cpp
splivarot.cpp
-
+ viewbox.cpp
# -------
# Headers
@@ -163,6 +163,7 @@ set(sp_SRC
sp-tspan.h
sp-use-reference.h
sp-use.h
+ viewbox.h
)
set(inkscape_SRC
diff --git a/src/Makefile_insert b/src/Makefile_insert
index 5e441560a..7aedb38ee 100644
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
@@ -228,7 +228,8 @@ ink_common_sources += \
uri-references.cpp uri-references.h \
vanishing-point.cpp vanishing-point.h \
verbs.cpp verbs.h \
- version.cpp version.h
+ version.cpp version.h \
+ viewbox.cpp viewbox.h
# Additional dependencies
diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp
index 8e25c1843..404a94828 100644
--- a/src/display/canvas-arena.cpp
+++ b/src/display/canvas-arena.cpp
@@ -216,10 +216,10 @@ sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf)
Geom::OptIntRect r = buf->rect;
if (!r || r->hasZeroArea()) return;
- Inkscape::DrawingContext ct(buf->ct, r->min());
+ Inkscape::DrawingContext dc(buf->ct, r->min());
arena->drawing.update(Geom::IntRect::infinite(), arena->ctx);
- arena->drawing.render(ct, *r);
+ arena->drawing.render(dc, *r);
}
static double
@@ -386,9 +386,9 @@ sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, Geo
g_return_if_fail (ca != NULL);
g_return_if_fail (SP_IS_CANVAS_ARENA (ca));
- Inkscape::DrawingContext ct(surface, r.min());
+ Inkscape::DrawingContext dc(surface, r.min());
ca->drawing.update(Geom::IntRect::infinite(), ca->ctx);
- ca->drawing.render(ct, r);
+ ca->drawing.render(dc, r);
}
/*
diff --git a/src/display/drawing-context.cpp b/src/display/drawing-context.cpp
index de5beb0f6..319136e06 100644
--- a/src/display/drawing-context.cpp
+++ b/src/display/drawing-context.cpp
@@ -25,27 +25,27 @@ using Geom::Y;
*/
DrawingContext::Save::Save()
- : _ct(NULL)
+ : _dc(NULL)
{}
-DrawingContext::Save::Save(DrawingContext &ct)
- : _ct(&ct)
+DrawingContext::Save::Save(DrawingContext &dc)
+ : _dc(&dc)
{
- _ct->save();
+ _dc->save();
}
DrawingContext::Save::~Save()
{
- if (_ct) {
- _ct->restore();
+ if (_dc) {
+ _dc->restore();
}
}
-void DrawingContext::Save::save(DrawingContext &ct)
+void DrawingContext::Save::save(DrawingContext &dc)
{
- if (_ct) {
+ if (_dc) {
// TODO: it might be better to treat this occurence as a bug
- _ct->restore();
+ _dc->restore();
}
- _ct = &ct;
- _ct->save();
+ _dc = &dc;
+ _dc->save();
}
/**
diff --git a/src/display/drawing-context.h b/src/display/drawing-context.h
index 35be9a86b..d990bcb73 100644
--- a/src/display/drawing-context.h
+++ b/src/display/drawing-context.h
@@ -31,11 +31,11 @@ public:
class Save {
public:
Save();
- Save(DrawingContext &ct);
+ Save(DrawingContext &dc);
~Save();
- void save(DrawingContext &ct);
+ void save(DrawingContext &dc);
private:
- DrawingContext *_ct;
+ DrawingContext *_dc;
};
DrawingContext(cairo_t *ct, Geom::Point const &origin);
diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp
index b5ce18891..38ace001f 100644
--- a/src/display/drawing-group.cpp
+++ b/src/display/drawing-group.cpp
@@ -98,12 +98,12 @@ DrawingGroup::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u
}
unsigned
-DrawingGroup::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at)
+DrawingGroup::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at)
{
if (stop_at == NULL) {
// normal rendering
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
- i->render(ct, area, flags, stop_at);
+ i->render(dc, area, flags, stop_at);
}
} else {
// background rendering
@@ -111,11 +111,11 @@ DrawingGroup::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigne
if (&*i == stop_at) return RENDER_OK; // do not render the stop_at item at all
if (i->isAncestorOf(stop_at)) {
// render its ancestors without masks, opacity or filters
- i->render(ct, area, flags | RENDER_FILTER_BACKGROUND, stop_at);
+ i->render(dc, area, flags | RENDER_FILTER_BACKGROUND, stop_at);
// stop further rendering
return RENDER_OK;
} else {
- i->render(ct, area, flags, stop_at);
+ i->render(dc, area, flags, stop_at);
}
}
}
@@ -123,10 +123,10 @@ DrawingGroup::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigne
}
void
-DrawingGroup::_clipItem(DrawingContext &ct, Geom::IntRect const &area)
+DrawingGroup::_clipItem(DrawingContext &dc, Geom::IntRect const &area)
{
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
- i->clip(ct, area);
+ i->clip(dc, area);
}
}
diff --git a/src/display/drawing-group.h b/src/display/drawing-group.h
index 775fec8c4..651e9d8af 100644
--- a/src/display/drawing-group.h
+++ b/src/display/drawing-group.h
@@ -34,9 +34,9 @@ public:
protected:
virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx,
unsigned flags, unsigned reset);
- virtual unsigned _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags,
+ virtual unsigned _renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags,
DrawingItem *stop_at);
- virtual void _clipItem(DrawingContext &ct, Geom::IntRect const &area);
+ virtual void _clipItem(DrawingContext &dc, Geom::IntRect const &area);
virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags);
virtual bool _canClip();
diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp
index 1b9214c49..8fd81caac 100644
--- a/src/display/drawing-image.cpp
+++ b/src/display/drawing-image.cpp
@@ -102,22 +102,22 @@ DrawingImage::_updateItem(Geom::IntRect const &, UpdateContext const &, unsigned
return STATE_ALL;
}
-unsigned DrawingImage::_renderItem(DrawingContext &ct, Geom::IntRect const &/*area*/, unsigned /*flags*/, DrawingItem * /*stop_at*/)
+unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*area*/, unsigned /*flags*/, DrawingItem * /*stop_at*/)
{
bool outline = _drawing.outline();
if (!outline) {
if (!_pixbuf) return RENDER_OK;
- Inkscape::DrawingContext::Save save(ct);
- ct.transform(_ctm);
- ct.newPath();
- ct.rectangle(_clipbox);
- ct.clip();
+ Inkscape::DrawingContext::Save save(dc);
+ dc.transform(_ctm);
+ dc.newPath();
+ dc.rectangle(_clipbox);
+ dc.clip();
- ct.translate(_origin);
- ct.scale(_scale);
- ct.setSource(_pixbuf->getSurfaceRaw(), 0, 0);
+ dc.translate(_origin);
+ dc.scale(_scale);
+ dc.setSource(_pixbuf->getSurfaceRaw(), 0, 0);
if (_style) {
// See: http://www.w3.org/TR/SVG/painting.html#ImageRenderingProperty
@@ -128,24 +128,24 @@ unsigned DrawingImage::_renderItem(DrawingContext &ct, Geom::IntRect const &/*ar
// Do nothing
break;
case SP_CSS_COLOR_RENDERING_OPTIMIZEQUALITY:
- ct.patternSetFilter( CAIRO_FILTER_BEST );
+ dc.patternSetFilter( CAIRO_FILTER_BEST );
break;
case SP_CSS_COLOR_RENDERING_OPTIMIZESPEED:
default:
- ct.patternSetFilter( CAIRO_FILTER_NEAREST );
+ dc.patternSetFilter( CAIRO_FILTER_NEAREST );
break;
}
}
- ct.paint(_opacity);
+ dc.paint(_opacity);
} else { // outline; draw a rect instead
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff);
- { Inkscape::DrawingContext::Save save(ct);
- ct.transform(_ctm);
- ct.newPath();
+ { Inkscape::DrawingContext::Save save(dc);
+ dc.transform(_ctm);
+ dc.newPath();
Geom::Rect r = bounds();
Geom::Point c00 = r.corner(0);
@@ -153,21 +153,21 @@ unsigned DrawingImage::_renderItem(DrawingContext &ct, Geom::IntRect const &/*ar
Geom::Point c11 = r.corner(2);
Geom::Point c10 = r.corner(1);
- ct.moveTo(c00);
+ dc.moveTo(c00);
// the box
- ct.lineTo(c10);
- ct.lineTo(c11);
- ct.lineTo(c01);
- ct.lineTo(c00);
+ dc.lineTo(c10);
+ dc.lineTo(c11);
+ dc.lineTo(c01);
+ dc.lineTo(c00);
// the diagonals
- ct.lineTo(c11);
- ct.moveTo(c10);
- ct.lineTo(c01);
+ dc.lineTo(c11);
+ dc.moveTo(c10);
+ dc.lineTo(c01);
}
- ct.setLineWidth(0.5);
- ct.setSource(rgba);
- ct.stroke();
+ dc.setLineWidth(0.5);
+ dc.setSource(rgba);
+ dc.stroke();
}
return RENDER_OK;
}
diff --git a/src/display/drawing-image.h b/src/display/drawing-image.h
index cebaafc85..64e4517b0 100644
--- a/src/display/drawing-image.h
+++ b/src/display/drawing-image.h
@@ -38,7 +38,7 @@ public:
protected:
virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx,
unsigned flags, unsigned reset);
- virtual unsigned _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags,
+ virtual unsigned _renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags,
DrawingItem *stop_at);
virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags);
diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp
index a9b07bb6e..13e7b61eb 100644
--- a/src/display/drawing-item.cpp
+++ b/src/display/drawing-item.cpp
@@ -24,60 +24,60 @@
namespace Inkscape {
#ifdef WITH_CSSBLEND
-void set_cairo_blend_operator( DrawingContext &ct, unsigned blend_mode ) {
+void set_cairo_blend_operator( DrawingContext &dc, unsigned blend_mode ) {
// All of the blend modes are implemented in Cairo as of 1.10.
// For a detailed description, see:
// http://cairographics.org/operators/
switch (blend_mode) {
case SP_CSS_BLEND_MULTIPLY:
- ct.setOperator(CAIRO_OPERATOR_MULTIPLY);
+ dc.setOperator(CAIRO_OPERATOR_MULTIPLY);
break;
case SP_CSS_BLEND_SCREEN:
- ct.setOperator(CAIRO_OPERATOR_SCREEN);
+ dc.setOperator(CAIRO_OPERATOR_SCREEN);
break;
case SP_CSS_BLEND_DARKEN:
- ct.setOperator(CAIRO_OPERATOR_DARKEN);
+ dc.setOperator(CAIRO_OPERATOR_DARKEN);
break;
case SP_CSS_BLEND_LIGHTEN:
- ct.setOperator(CAIRO_OPERATOR_LIGHTEN);
+ dc.setOperator(CAIRO_OPERATOR_LIGHTEN);
break;
case SP_CSS_BLEND_OVERLAY:
- ct.setOperator(CAIRO_OPERATOR_OVERLAY);
+ dc.setOperator(CAIRO_OPERATOR_OVERLAY);
break;
case SP_CSS_BLEND_COLORDODGE:
- ct.setOperator(CAIRO_OPERATOR_COLOR_DODGE);
+ dc.setOperator(CAIRO_OPERATOR_COLOR_DODGE);
break;
case SP_CSS_BLEND_COLORBURN:
- ct.setOperator(CAIRO_OPERATOR_COLOR_BURN);
+ dc.setOperator(CAIRO_OPERATOR_COLOR_BURN);
break;
case SP_CSS_BLEND_HARDLIGHT:
- ct.setOperator(CAIRO_OPERATOR_HARD_LIGHT);
+ dc.setOperator(CAIRO_OPERATOR_HARD_LIGHT);
break;
case SP_CSS_BLEND_SOFTLIGHT:
- ct.setOperator(CAIRO_OPERATOR_SOFT_LIGHT);
+ dc.setOperator(CAIRO_OPERATOR_SOFT_LIGHT);
break;
case SP_CSS_BLEND_DIFFERENCE:
- ct.setOperator(CAIRO_OPERATOR_DIFFERENCE);
+ dc.setOperator(CAIRO_OPERATOR_DIFFERENCE);
break;
case SP_CSS_BLEND_EXCLUSION:
- ct.setOperator(CAIRO_OPERATOR_EXCLUSION);
+ dc.setOperator(CAIRO_OPERATOR_EXCLUSION);
break;
case SP_CSS_BLEND_HUE:
- ct.setOperator(CAIRO_OPERATOR_HSL_HUE);
+ dc.setOperator(CAIRO_OPERATOR_HSL_HUE);
break;
case SP_CSS_BLEND_SATURATION:
- ct.setOperator(CAIRO_OPERATOR_HSL_SATURATION);
+ dc.setOperator(CAIRO_OPERATOR_HSL_SATURATION);
break;
case SP_CSS_BLEND_COLOR:
- ct.setOperator(CAIRO_OPERATOR_HSL_COLOR);
+ dc.setOperator(CAIRO_OPERATOR_HSL_COLOR);
break;
case SP_CSS_BLEND_LUMINOSITY:
- ct.setOperator(CAIRO_OPERATOR_HSL_LUMINOSITY);
+ dc.setOperator(CAIRO_OPERATOR_HSL_LUMINOSITY);
break;
case SP_CSS_BLEND_NORMAL:
default:
- ct.setOperator(CAIRO_OPERATOR_OVER);
+ dc.setOperator(CAIRO_OPERATOR_OVER);
break;
}
}
@@ -545,7 +545,7 @@ struct MaskLuminanceToAlpha {
* @param flags Rendering options. This deals mainly with cache control.
*/
unsigned
-DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at)
+DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at)
{
bool outline = _drawing.outline();
bool render_filters = _drawing.renderFilters();
@@ -560,7 +560,7 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
// TODO convert outline rendering to a separate virtual function
if (outline) {
- _renderOutline(ct, area, flags);
+ _renderOutline(dc, area, flags);
return RENDER_OK;
}
@@ -573,9 +573,9 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
if (_cache) {
_cache->prepare();
#ifdef WITH_CSSBLEND
- set_cairo_blend_operator( ct, _blend_mode );
+ set_cairo_blend_operator( dc, _blend_mode );
#endif
- _cache->paintFromCache(ct, carea);
+ _cache->paintFromCache(dc, carea);
if (!carea) return RENDER_OK;
} else {
// There is no cache. This could be because caching of this item
@@ -625,7 +625,7 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
// filters and opacity do not apply when rendering the ancestors of the filtered
// element
if ((flags & RENDER_FILTER_BACKGROUND) || !needs_intermediate_rendering) {
- return _renderItem(ct, *carea, flags & ~RENDER_FILTER_BACKGROUND, stop_at);
+ return _renderItem(dc, *carea, flags & ~RENDER_FILTER_BACKGROUND, stop_at);
}
// iarea is the bounding box for intermediate rendering
@@ -688,9 +688,9 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
}
if (bg_root) {
DrawingSurface bg(*iarea);
- DrawingContext bgct(bg);
- bg_root->render(bgct, *iarea, flags | RENDER_FILTER_BACKGROUND, this);
- _filter->render(this, ict, &bgct);
+ DrawingContext bgdc(bg);
+ bg_root->render(bgdc, *iarea, flags | RENDER_FILTER_BACKGROUND, this);
+ _filter->render(this, ict, &bgdc);
rendered = true;
}
}
@@ -716,20 +716,20 @@ DrawingItem::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flag
cachect.fill();
_cache->markClean(*carea);
}
- ct.rectangle(*carea);
- ct.setSource(&intermediate);
+ dc.rectangle(*carea);
+ dc.setSource(&intermediate);
#ifdef WITH_CSSBLEND
- set_cairo_blend_operator( ct, _blend_mode );
+ set_cairo_blend_operator( dc, _blend_mode );
#endif
- ct.fill();
- ct.setSource(0,0,0,0);
- // the call above is to clear a ref on the intermediate surface held by ct
+ dc.fill();
+ dc.setSource(0,0,0,0);
+ // the call above is to clear a ref on the intermediate surface held by dc
return render_result;
}
void
-DrawingItem::_renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsigned flags)
+DrawingItem::_renderOutline(DrawingContext &dc, Geom::IntRect const &area, unsigned flags)
{
// intersect with bbox rather than drawbox, as we want to render things outside
// of the clipping path as well
@@ -738,7 +738,7 @@ DrawingItem::_renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsig
// just render everything: item, clip, mask
// First, render the object itself
- _renderItem(ct, *carea, flags, NULL);
+ _renderItem(dc, *carea, flags, NULL);
// render clip and mask, if any
guint32 saved_rgba = _drawing.outlinecolor; // save current outline color
@@ -746,12 +746,12 @@ DrawingItem::_renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsig
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (_clip) {
_drawing.outlinecolor = prefs->getInt("/options/wireframecolors/clips", 0x00ff00ff); // green clips
- _clip->render(ct, *carea, flags);
+ _clip->render(dc, *carea, flags);
}
// render mask as an object, using a different color
if (_mask) {
_drawing.outlinecolor = prefs->getInt("/options/wireframecolors/masks", 0x0000ffff); // blue masks
- _mask->render(ct, *carea, flags);
+ _mask->render(dc, *carea, flags);
}
_drawing.outlinecolor = saved_rgba; // restore outline color
}
@@ -765,31 +765,31 @@ DrawingItem::_renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsig
* of render() for details.
*/
void
-DrawingItem::clip(Inkscape::DrawingContext &ct, Geom::IntRect const &area)
+DrawingItem::clip(Inkscape::DrawingContext &dc, Geom::IntRect const &area)
{
// don't bother if the object does not implement clipping (e.g. DrawingImage)
if (!_canClip()) return;
if (!_visible) return;
if (!area.intersects(_bbox)) return;
- ct.setSource(0,0,0,1);
- ct.pushGroup();
+ dc.setSource(0,0,0,1);
+ dc.pushGroup();
// rasterize the clipping path
- _clipItem(ct, area);
+ _clipItem(dc, area);
if (_clip) {
// The item used as the clipping path itself has a clipping path.
// Render this item's clipping path onto a temporary surface, then composite it
// with the item using the IN operator
- ct.pushGroup();
- _clip->clip(ct, area);
- ct.popGroupToSource();
- ct.setOperator(CAIRO_OPERATOR_IN);
- ct.paint();
+ dc.pushGroup();
+ _clip->clip(dc, area);
+ dc.popGroupToSource();
+ dc.setOperator(CAIRO_OPERATOR_IN);
+ dc.paint();
}
- ct.popGroupToSource();
- ct.setOperator(CAIRO_OPERATOR_OVER);
- ct.paint();
- ct.setSource(0,0,0,0);
+ dc.popGroupToSource();
+ dc.setOperator(CAIRO_OPERATOR_OVER);
+ dc.paint();
+ dc.setSource(0,0,0,0);
}
/**
diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h
index 1796d29d6..913706021 100644
--- a/src/display/drawing-item.h
+++ b/src/display/drawing-item.h
@@ -123,8 +123,8 @@ public:
void *data() const { return _user_data; }
void update(Geom::IntRect const &area = Geom::IntRect::infinite(), UpdateContext const &ctx = UpdateContext(), unsigned flags = STATE_ALL, unsigned reset = 0);
- unsigned render(DrawingContext &ct, Geom::IntRect const &area, unsigned flags = 0, DrawingItem *stop_at = NULL);
- void clip(DrawingContext &ct, Geom::IntRect const &area);
+ unsigned render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags = 0, DrawingItem *stop_at = NULL);
+ void clip(DrawingContext &dc, Geom::IntRect const &area);
DrawingItem *pick(Geom::Point const &p, double delta, unsigned flags = 0);
protected:
@@ -141,7 +141,7 @@ protected:
RENDER_OK = 0,
RENDER_STOP = 1
};
- void _renderOutline(DrawingContext &ct, Geom::IntRect const &area, unsigned flags);
+ void _renderOutline(DrawingContext &dc, Geom::IntRect const &area, unsigned flags);
void _markForUpdate(unsigned state, bool propagate);
void _markForRendering();
void _invalidateFilterBackground(Geom::IntRect const &area);
@@ -150,9 +150,9 @@ protected:
Geom::OptIntRect _cacheRect();
virtual unsigned _updateItem(Geom::IntRect const &/*area*/, UpdateContext const &/*ctx*/,
unsigned /*flags*/, unsigned /*reset*/) { return 0; }
- virtual unsigned _renderItem(DrawingContext &/*ct*/, Geom::IntRect const &/*area*/, unsigned /*flags*/,
+ virtual unsigned _renderItem(DrawingContext &/*dc*/, Geom::IntRect const &/*area*/, unsigned /*flags*/,
DrawingItem * /*stop_at*/) { return RENDER_OK; }
- virtual void _clipItem(DrawingContext &/*ct*/, Geom::IntRect const &/*area*/) {}
+ virtual void _clipItem(DrawingContext &/*dc*/, Geom::IntRect const &/*area*/) {}
virtual DrawingItem *_pickItem(Geom::Point const &/*p*/, double /*delta*/, unsigned /*flags*/) { return NULL; }
virtual bool _canClip() { return false; }
diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp
index 03d7f51b5..f99f9442f 100644
--- a/src/display/drawing-shape.cpp
+++ b/src/display/drawing-shape.cpp
@@ -150,7 +150,7 @@ DrawingShape::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u
}
unsigned
-DrawingShape::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at)
+DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at)
{
if (!_curve || !_style) return RENDER_OK;
if (!area.intersects(_bbox)) return RENDER_OK; // skip if not within bounding box
@@ -160,67 +160,67 @@ DrawingShape::_renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigne
if (outline) {
guint32 rgba = _drawing.outlinecolor;
- { Inkscape::DrawingContext::Save save(ct);
- ct.transform(_ctm);
- ct.path(_curve->get_pathvector());
+ { Inkscape::DrawingContext::Save save(dc);
+ dc.transform(_ctm);
+ dc.path(_curve->get_pathvector());
}
- { Inkscape::DrawingContext::Save save(ct);
- ct.setSource(rgba);
- ct.setLineWidth(0.5);
- ct.setTolerance(0.5);
- ct.stroke();
+ { Inkscape::DrawingContext::Save save(dc);
+ dc.setSource(rgba);
+ dc.setLineWidth(0.5);
+ dc.setTolerance(0.5);
+ dc.stroke();
}
} else {
bool has_stroke, has_fill;
// we assume the context has no path
- Inkscape::DrawingContext::Save save(ct);
- ct.transform(_ctm);
+ Inkscape::DrawingContext::Save save(dc);
+ dc.transform(_ctm);
// update fill and stroke paints.
// this cannot be done during nr_arena_shape_update, because we need a Cairo context
// to render svg:pattern
- has_fill = _nrstyle.prepareFill(ct, _item_bbox);
- has_stroke = _nrstyle.prepareStroke(ct, _item_bbox);
+ has_fill = _nrstyle.prepareFill(dc, _item_bbox);
+ has_stroke = _nrstyle.prepareStroke(dc, _item_bbox);
has_stroke &= (_nrstyle.stroke_width != 0);
if (has_fill || has_stroke) {
// TODO: remove segments outside of bbox when no dashes present
- ct.path(_curve->get_pathvector());
+ dc.path(_curve->get_pathvector());
if (has_fill) {
- _nrstyle.applyFill(ct);
- ct.fillPreserve();
+ _nrstyle.applyFill(dc);
+ dc.fillPreserve();
}
if (has_stroke) {
- _nrstyle.applyStroke(ct);
- ct.strokePreserve();
+ _nrstyle.applyStroke(dc);
+ dc.strokePreserve();
}
- ct.newPath(); // clear path
+ dc.newPath(); // clear path
} // has fill or stroke pattern
}
// marker rendering
for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) {
- i->render(ct, area, flags, stop_at);
+ i->render(dc, area, flags, stop_at);
}
return RENDER_OK;
}
-void DrawingShape::_clipItem(DrawingContext &ct, Geom::IntRect const & /*area*/)
+void DrawingShape::_clipItem(DrawingContext &dc, Geom::IntRect const & /*area*/)
{
if (!_curve) return;
- Inkscape::DrawingContext::Save save(ct);
+ Inkscape::DrawingContext::Save save(dc);
// handle clip-rule
if (_style) {
if (_style->clip_rule.computed == SP_WIND_RULE_EVENODD) {
- ct.setFillRule(CAIRO_FILL_RULE_EVEN_ODD);
+ dc.setFillRule(CAIRO_FILL_RULE_EVEN_ODD);
} else {
- ct.setFillRule(CAIRO_FILL_RULE_WINDING);
+ dc.setFillRule(CAIRO_FILL_RULE_WINDING);
}
}
- ct.transform(_ctm);
- ct.path(_curve->get_pathvector());
- ct.fill();
+ dc.transform(_ctm);
+ dc.path(_curve->get_pathvector());
+ dc.fill();
}
DrawingItem *
diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h
index 52496d86e..47b9e807e 100644
--- a/src/display/drawing-shape.h
+++ b/src/display/drawing-shape.h
@@ -33,9 +33,9 @@ public:
protected:
virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx,
unsigned flags, unsigned reset);
- virtual unsigned _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags,
+ virtual unsigned _renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags,
DrawingItem *stop_at);
- virtual void _clipItem(DrawingContext &ct, Geom::IntRect const &area);
+ virtual void _clipItem(DrawingContext &dc, Geom::IntRect const &area);
virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags);
virtual bool _canClip();
diff --git a/src/display/drawing-surface.cpp b/src/display/drawing-surface.cpp
index bddccbd96..94e0e1ab5 100644
--- a/src/display/drawing-surface.cpp
+++ b/src/display/drawing-surface.cpp
@@ -267,7 +267,7 @@ DrawingCache::prepare()
* parameter to the bounds of the region that must be repainted.
*/
void
-DrawingCache::paintFromCache(DrawingContext &ct, Geom::OptIntRect &area)
+DrawingCache::paintFromCache(DrawingContext &dc, Geom::OptIntRect &area)
{
if (!area) return;
@@ -296,10 +296,10 @@ DrawingCache::paintFromCache(DrawingContext &ct, Geom::OptIntRect &area)
cairo_rectangle_int_t tmp;
for (int i = 0; i < nr; ++i) {
cairo_region_get_rectangle(cache_region, i, &tmp);
- ct.rectangle(_convertRect(tmp));
+ dc.rectangle(_convertRect(tmp));
}
- ct.setSource(this);
- ct.fill();
+ dc.setSource(this);
+ dc.fill();
}
cairo_region_destroy(cache_region);
}
@@ -310,21 +310,21 @@ DrawingCache::_dumpCache(Geom::OptIntRect const &area)
{
static int dumpnr = 0;
cairo_surface_t *surface = ink_cairo_surface_copy(_surface);
- DrawingContext ct(surface, _origin);
+ DrawingContext dc(surface, _origin);
if (!cairo_region_is_empty(_clean_region)) {
- Inkscape::DrawingContext::Save save(ct);
+ Inkscape::DrawingContext::Save save(dc);
int nr = cairo_region_num_rectangles(_clean_region);
cairo_rectangle_int_t tmp;
for (int i = 0; i < nr; ++i) {
cairo_region_get_rectangle(_clean_region, i, &tmp);
- ct.rectangle(_convertRect(tmp));
+ dc.rectangle(_convertRect(tmp));
}
- ct.setSource(0,1,0,0.1);
- ct.fill();
+ dc.setSource(0,1,0,0.1);
+ dc.fill();
}
- ct.rectangle(*area);
- ct.setSource(1,0,0,0.1);
- ct.fill();
+ dc.rectangle(*area);
+ dc.setSource(1,0,0,0.1);
+ dc.fill();
char *fn = g_strdup_printf("dump%d.png", dumpnr++);
cairo_surface_write_to_png(surface, fn);
cairo_surface_destroy(surface);
diff --git a/src/display/drawing-surface.h b/src/display/drawing-surface.h
index 1ec848405..e937cca55 100644
--- a/src/display/drawing-surface.h
+++ b/src/display/drawing-surface.h
@@ -65,7 +65,7 @@ public:
void markClean(Geom::IntRect const &area = Geom::IntRect::infinite());
void scheduleTransform(Geom::IntRect const &new_area, Geom::Affine const &trans);
void prepare();
- void paintFromCache(DrawingContext &ct, Geom::OptIntRect &area);
+ void paintFromCache(DrawingContext &dc, Geom::OptIntRect &area);
protected:
cairo_region_t *_clean_region;
diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp
index f652a2970..f5a0f0af5 100644
--- a/src/display/drawing-text.cpp
+++ b/src/display/drawing-text.cpp
@@ -195,7 +195,7 @@ DrawingText::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, un
return DrawingGroup::_updateItem(area, ctx, flags, reset);
}
-void DrawingText::decorateStyle(DrawingContext &ct, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2)
+void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2)
{
double wave[16]={
0.000000, 0.382499, 0.706825, 0.923651, 1.000000, 0.923651, 0.706825, 0.382499,
@@ -235,12 +235,12 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]);
if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_ISDOUBLE){
ps -= Geom::Point(0, vextent/12.0);
pf -= Geom::Point(0, vextent/12.0);
- ct.moveTo(ps);
- ct.lineTo(pf);
+ dc.moveTo(ps);
+ dc.lineTo(pf);
ps += Geom::Point(0, vextent/6.0);
pf += Geom::Point(0, vextent/6.0);
- ct.moveTo(ps);
- ct.lineTo(pf);
+ dc.moveTo(ps);
+ dc.lineTo(pf);
}
/* The next three have a problem in that they are phase dependent. The bits of a line are not
necessarily passing through this routine in order, so we have to use the xphase information
@@ -251,14 +251,14 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]);
while(1){
if(dots[i]>0){
if(ps[Geom::X]> pf[Geom::X])break;
- ct.moveTo(ps);
+ dc.moveTo(ps);
ps += Geom::Point(step * (double)dots[i], 0.0);
if(ps[Geom::X]>= pf[Geom::X]){
- ct.lineTo(pf);
+ dc.lineTo(pf);
break;
}
else {
- ct.lineTo(ps);
+ dc.lineTo(ps);
}
ps += Geom::Point(step * 4.0, 0.0);
}
@@ -272,14 +272,14 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]);
while(1){
if(dashes[i]>0){
if(ps[Geom::X]> pf[Geom::X])break;
- ct.moveTo(ps);
+ dc.moveTo(ps);
ps += Geom::Point(step * (double)dashes[i], 0.0);
if(ps[Geom::X]>= pf[Geom::X]){
- ct.lineTo(pf);
+ dc.lineTo(pf);
break;
}
else {
- ct.lineTo(ps);
+ dc.lineTo(ps);
}
ps += Geom::Point(step * 8.0, 0.0);
}
@@ -293,23 +293,23 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]);
double amp = vextent/10.0;
double x = ps[Geom::X];
double y = ps[Geom::Y];
- ct.moveTo(Geom::Point(x, y + amp * wave[i]));
+ dc.moveTo(Geom::Point(x, y + amp * wave[i]));
while(1){
i = ((i + 1) & 15);
x += step;
- ct.lineTo(Geom::Point(x, y + amp * wave[i]));
+ dc.lineTo(Geom::Point(x, y + amp * wave[i]));
if(x >= pf[Geom::X])break;
}
}
else { // TEXT_DECORATION_STYLE_SOLID, also default in case it was not set for some reason
- ct.moveTo(ps);
- ct.lineTo(pf);
-// ct.revrectangle(Geom::Rect(ps,pf));
+ dc.moveTo(ps);
+ dc.lineTo(pf);
+// dc.revrectangle(Geom::Rect(ps,pf));
}
}
/* returns scaled line thickness */
-double DrawingText::decorateItem(DrawingContext &ct, Geom::Affine const &aff, double phase_length)
+double DrawingText::decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length)
{
double tsp_width_adj = _nrstyle.tspan_width / _nrstyle.font_size;
double tsp_asc_adj = _nrstyle.ascender / _nrstyle.font_size;
@@ -321,8 +321,8 @@ double DrawingText::decorateItem(DrawingContext &ct, Geom::Affine const &aff, do
double scale = aff.descrim();
double xphase = phase_length/ _nrstyle.font_size; // used to figure out phase of patterns
- Inkscape::DrawingContext::Save save(ct);
- ct.transform(aff); // must be leftmost affine in span
+ Inkscape::DrawingContext::Save save(dc);
+ dc.transform(aff); // must be leftmost affine in span
Geom::Point p1;
Geom::Point p2;
@@ -331,52 +331,52 @@ double DrawingText::decorateItem(DrawingContext &ct, Geom::Affine const &aff, do
if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_UNDERLINE){
p1 = Geom::Point(0.0, -_nrstyle.underline_position);
p2 = Geom::Point(tsp_width_adj,-_nrstyle.underline_position);
- decorateStyle(ct, tsp_size_adj, xphase, p1, p2);
+ decorateStyle(dc, tsp_size_adj, xphase, p1, p2);
}
if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_OVERLINE){
p1 = Geom::Point(0.0, tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness);
p2 = Geom::Point(tsp_width_adj,tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness);
- decorateStyle(ct, tsp_size_adj, xphase, p1, p2);
+ decorateStyle(dc, tsp_size_adj, xphase, p1, p2);
}
if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_LINETHROUGH){
thickness = final_line_through_thickness;
p1 = Geom::Point(0.0, _nrstyle.line_through_position);
p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position);
- decorateStyle(ct, tsp_size_adj, xphase, p1, p2);
+ decorateStyle(dc, tsp_size_adj, xphase, p1, p2);
}
// Obviously this does not blink, but it does indicate which text has been set with that attribute
if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_BLINK){
thickness = final_line_through_thickness;
p1 = Geom::Point(0.0, _nrstyle.line_through_position - 2*final_line_through_thickness);
p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position - 2*final_line_through_thickness);
- decorateStyle(ct, tsp_size_adj, xphase, p1, p2);
+ decorateStyle(dc, tsp_size_adj, xphase, p1, p2);
p1 = Geom::Point(0.0, _nrstyle.line_through_position + 2*final_line_through_thickness);
p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position + 2*final_line_through_thickness);
- decorateStyle(ct, tsp_size_adj, xphase, p1, p2);
+ decorateStyle(dc, tsp_size_adj, xphase, p1, p2);
}
thickness *= scale;
return(thickness);
}
-unsigned DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &/*area*/, unsigned /*flags*/, DrawingItem * /*stop_at*/)
+unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*area*/, unsigned /*flags*/, DrawingItem * /*stop_at*/)
{
if (_drawing.outline()) {
guint32 rgba = _drawing.outlinecolor;
- Inkscape::DrawingContext::Save save(ct);
- ct.setSource(rgba);
- ct.setTolerance(0.5); // low quality, but good enough for outline mode
+ Inkscape::DrawingContext::Save save(dc);
+ dc.setSource(rgba);
+ dc.setTolerance(0.5); // low quality, but good enough for outline mode
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);
+ Inkscape::DrawingContext::Save save(dc);
// skip glyphs with singular transforms
if (g->_ctm.isSingular()) continue;
- ct.transform(g->_ctm);
+ dc.transform(g->_ctm);
if(g->_drawable){
- ct.path(*g->_font->PathVector(g->_glyph));
- ct.fill();
+ dc.path(*g->_font->PathVector(g->_glyph));
+ dc.fill();
}
}
return RENDER_OK;
@@ -398,11 +398,11 @@ unsigned DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &/*are
// Therefore, only apply this ctm temporarily.
bool has_stroke, has_fill;
{
- Inkscape::DrawingContext::Save save(ct);
- ct.transform(_ctm);
+ Inkscape::DrawingContext::Save save(dc);
+ dc.transform(_ctm);
- has_fill = _nrstyle.prepareFill( ct, _item_bbox);
- has_stroke = _nrstyle.prepareStroke(ct, _item_bbox);
+ has_fill = _nrstyle.prepareFill( dc, _item_bbox);
+ has_stroke = _nrstyle.prepareStroke(dc, _item_bbox);
}
if (has_fill || has_stroke) {
@@ -418,11 +418,11 @@ unsigned DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &/*are
invset = true;
}
- Inkscape::DrawingContext::Save save(ct);
+ Inkscape::DrawingContext::Save save(dc);
if (g->_ctm.isSingular()) continue;
- ct.transform(g->_ctm);
+ dc.transform(g->_ctm);
if (g->_drawable) {
- ct.path(*g->_font->PathVector(g->_glyph));
+ dc.path(*g->_font->PathVector(g->_glyph));
}
// get the leftmost affine transform (leftmost defined with respect to the x axis of the first transform).
// That way the decoration will work no matter what mix of L->R, R->L text is in the span.
@@ -448,17 +448,17 @@ unsigned DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &/*are
// draw the text itself
// we need to apply this object's ctm again
- Inkscape::DrawingContext::Save save(ct);
- ct.transform(_ctm);
+ Inkscape::DrawingContext::Save save(dc);
+ dc.transform(_ctm);
if (has_fill) {
- _nrstyle.applyFill(ct);
- ct.fillPreserve();
+ _nrstyle.applyFill(dc);
+ dc.fillPreserve();
}
if (has_stroke) {
- _nrstyle.applyStroke(ct);
- ct.strokePreserve();
+ _nrstyle.applyStroke(dc);
+ dc.strokePreserve();
}
- ct.newPath(); // clear path
+ dc.newPath(); // clear path
// draw text decoration
if (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR && decorate) {
@@ -477,27 +477,27 @@ unsigned DrawingText::_renderItem(DrawingContext &ct, Geom::IntRect const &/*are
_nrstyle.fill.color.v.c[2],
1.0);
}
- ct.setSource(ergba);
- ct.setTolerance(0.5);
- double thickness = decorateItem(ct, aff, phase_length);
- ct.setLineWidth(thickness);
- ct.strokePreserve();
- ct.newPath(); // clear path
+ dc.setSource(ergba);
+ dc.setTolerance(0.5);
+ double thickness = decorateItem(dc, aff, phase_length);
+ dc.setLineWidth(thickness);
+ dc.strokePreserve();
+ dc.newPath(); // clear path
}
}
return RENDER_OK;
}
-void DrawingText::_clipItem(DrawingContext &ct, Geom::IntRect const &/*area*/)
+void DrawingText::_clipItem(DrawingContext &dc, Geom::IntRect const &/*area*/)
{
- Inkscape::DrawingContext::Save save(ct);
+ Inkscape::DrawingContext::Save save(dc);
// handle clip-rule
if (_style) {
if (_style->clip_rule.computed == SP_WIND_RULE_EVENODD) {
- ct.setFillRule(CAIRO_FILL_RULE_EVEN_ODD);
+ dc.setFillRule(CAIRO_FILL_RULE_EVEN_ODD);
} else {
- ct.setFillRule(CAIRO_FILL_RULE_WINDING);
+ dc.setFillRule(CAIRO_FILL_RULE_WINDING);
}
}
@@ -507,13 +507,13 @@ void DrawingText::_clipItem(DrawingContext &ct, Geom::IntRect const &/*area*/)
throw InvalidItemException();
}
- Inkscape::DrawingContext::Save save(ct);
- ct.transform(g->_ctm);
+ Inkscape::DrawingContext::Save save(dc);
+ dc.transform(g->_ctm);
if(g->_drawable){
- ct.path(*g->_font->PathVector(g->_glyph));
+ dc.path(*g->_font->PathVector(g->_glyph));
}
}
- ct.fill();
+ dc.fill();
}
DrawingItem *
diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h
index fd122b54b..b863ca2a4 100644
--- a/src/display/drawing-text.h
+++ b/src/display/drawing-text.h
@@ -62,14 +62,14 @@ public:
protected:
virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx,
unsigned flags, unsigned reset);
- virtual unsigned _renderItem(DrawingContext &ct, Geom::IntRect const &area, unsigned flags,
+ virtual unsigned _renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigned flags,
DrawingItem *stop_at);
- virtual void _clipItem(DrawingContext &ct, Geom::IntRect const &area);
+ virtual void _clipItem(DrawingContext &dc, Geom::IntRect const &area);
virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags);
virtual bool _canClip();
- double decorateItem(DrawingContext &ct, Geom::Affine const &aff, double phase_length);
- void decorateStyle(DrawingContext &ct, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2);
+ double decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length);
+ void decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2);
NRStyle _nrstyle;
friend class DrawingGlyphs;
diff --git a/src/display/drawing.cpp b/src/display/drawing.cpp
index c192e4565..6e728b03d 100644
--- a/src/display/drawing.cpp
+++ b/src/display/drawing.cpp
@@ -167,22 +167,22 @@ Drawing::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigned fl
}
void
-Drawing::render(DrawingContext &ct, Geom::IntRect const &area, unsigned flags)
+Drawing::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags)
{
if (_root) {
- _root->render(ct, area, flags);
+ _root->render(dc, area, flags);
}
if (colorMode() == COLORMODE_GRAYSCALE) {
// apply grayscale filter on top of everything
- cairo_surface_t *input = ct.rawTarget();
+ cairo_surface_t *input = dc.rawTarget();
cairo_surface_t *out = ink_cairo_surface_create_identical(input);
ink_cairo_surface_filter(input, out, _grayscale_colormatrix);
- Geom::Point origin = ct.targetLogicalBounds().min();
- ct.setSource(out, origin[Geom::X], origin[Geom::Y]);
- ct.setOperator(CAIRO_OPERATOR_SOURCE);
- ct.paint();
- ct.setOperator(CAIRO_OPERATOR_OVER);
+ Geom::Point origin = dc.targetLogicalBounds().min();
+ dc.setSource(out, origin[Geom::X], origin[Geom::Y]);
+ dc.setOperator(CAIRO_OPERATOR_SOURCE);
+ dc.paint();
+ dc.setOperator(CAIRO_OPERATOR_OVER);
cairo_surface_destroy(out);
}
diff --git a/src/display/drawing.h b/src/display/drawing.h
index 74ab57fae..cc74833ba 100644
--- a/src/display/drawing.h
+++ b/src/display/drawing.h
@@ -68,7 +68,7 @@ public:
void setGrayscaleMatrix(gdouble value_matrix[20]);
void update(Geom::IntRect const &area = Geom::IntRect::infinite(), UpdateContext const &ctx = UpdateContext(), unsigned flags = DrawingItem::STATE_ALL, unsigned reset = 0);
- void render(DrawingContext &ct, Geom::IntRect const &area, unsigned flags = 0);
+ void render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags = 0);
DrawingItem *pick(Geom::Point const &p, double delta, unsigned flags);
sigc::signal<void, DrawingItem *> signal_request_update;
diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp
index 92bb9dcaa..154d1ab32 100644
--- a/src/display/nr-filter-image.cpp
+++ b/src/display/nr-filter-image.cpp
@@ -108,17 +108,17 @@ void FilterImage::render_cairo(FilterSlot &slot)
Geom::Rect sa = slot.get_slot_area();
cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
sa.width(), sa.height());
- Inkscape::DrawingContext ct(out, sa.min());
- ct.transform(user2pb); // we are now in primitive units
- ct.translate(feImageX, feImageY);
-// ct.scale(scaleX, scaleY); No scaling should be done
+ Inkscape::DrawingContext dc(out, sa.min());
+ dc.transform(user2pb); // we are now in primitive units
+ dc.translate(feImageX, feImageY);
+// dc.scale(scaleX, scaleY); No scaling should be done
Geom::IntRect render_rect = area.roundOutwards();
- ct.translate(render_rect.min());
+ dc.translate(render_rect.min());
// Update to renderable state
drawing.update(render_rect);
- drawing.render(ct, render_rect);
+ drawing.render(dc, render_rect);
SVGElem->invoke_hide(key);
// For the moment, we'll assume that any image is in sRGB color space
diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp
index 755a30a74..e4c2f048e 100644
--- a/src/display/nr-filter-slot.cpp
+++ b/src/display/nr-filter-slot.cpp
@@ -25,13 +25,13 @@
namespace Inkscape {
namespace Filters {
-FilterSlot::FilterSlot(DrawingItem *item, DrawingContext *bgct,
+FilterSlot::FilterSlot(DrawingItem *item, DrawingContext *bgdc,
DrawingContext &graphic, FilterUnits const &u)
: _item(item)
, _source_graphic(graphic.rawTarget())
- , _background_ct(bgct ? bgct->raw() : NULL)
+ , _background_ct(bgdc ? bgdc->raw() : NULL)
, _source_graphic_area(graphic.targetLogicalBounds().roundOutwards()) // fixme
- , _background_area(bgct ? bgct->targetLogicalBounds().roundOutwards() : Geom::IntRect()) // fixme
+ , _background_area(bgdc ? bgdc->targetLogicalBounds().roundOutwards() : Geom::IntRect()) // fixme
, _units(u)
, _last_out(NR_FILTER_SOURCEGRAPHIC)
, filterquality(FILTER_QUALITY_BEST)
diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h
index 805027bfe..f3c98b8d9 100644
--- a/src/display/nr-filter-slot.h
+++ b/src/display/nr-filter-slot.h
@@ -28,7 +28,7 @@ namespace Filters {
class FilterSlot {
public:
/** Creates a new FilterSlot object. */
- FilterSlot(DrawingItem *item, DrawingContext *bgct,
+ FilterSlot(DrawingItem *item, DrawingContext *bgdc,
DrawingContext &graphic, FilterUnits const &u);
/** Destroys the FilterSlot object and all its contents */
virtual ~FilterSlot();
diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp
index af9c15cd8..11984ba76 100644
--- a/src/display/nr-filter.cpp
+++ b/src/display/nr-filter.cpp
@@ -98,7 +98,7 @@ Filter::~Filter()
}
-int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, DrawingContext *bgct)
+int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, DrawingContext *bgdc)
{
if (_primitive.empty()) {
// when no primitives are defined, clear source graphic
@@ -150,7 +150,7 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D
}
}
- FilterSlot slot(const_cast<Inkscape::DrawingItem*>(item), bgct, graphic, units);
+ FilterSlot slot(const_cast<Inkscape::DrawingItem*>(item), bgdc, graphic, units);
slot.set_quality(filterquality);
slot.set_blurquality(blurquality);
diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h
index 5df38ffe9..f9dcf1d84 100644
--- a/src/display/nr-filter.h
+++ b/src/display/nr-filter.h
@@ -28,12 +28,12 @@ namespace Filters {
class Filter {
public:
- /** Given background state from @a bgct and an intermediate rendering from the surface
+ /** Given background state from @a bgdc and an intermediate rendering from the surface
* backing @a graphic, modify the contents of the surface backing @a graphic to represent
* the results of filter rendering. @a bgarea and @a area specify bounding boxes
* of both surfaces in world coordinates; Cairo contexts are assumed to be in default state
* (0,0 = surface origin, no path, OVER operator) */
- int render(Inkscape::DrawingItem const *item, DrawingContext &graphic, DrawingContext *bgct);
+ int render(Inkscape::DrawingItem const *item, DrawingContext &graphic, DrawingContext *bgdc);
/**
* Creates a new filter primitive under this filter object.
diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp
index 317f38635..403b139e0 100644
--- a/src/display/nr-style.cpp
+++ b/src/display/nr-style.cpp
@@ -207,14 +207,14 @@ void NRStyle::set(SPStyle *style)
update();
}
-bool NRStyle::prepareFill(Inkscape::DrawingContext &ct, Geom::OptRect const &paintbox)
+bool NRStyle::prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox)
{
// update fill pattern
if (!fill_pattern) {
switch (fill.type) {
case PAINT_SERVER: {
- //fill_pattern = sp_paint_server_create_pattern(fill.server, ct.raw(), paintbox, fill.opacity);
- fill_pattern = fill.server->pattern_new(ct.raw(), paintbox, fill.opacity);
+ //fill_pattern = sp_paint_server_create_pattern(fill.server, dc.raw(), paintbox, fill.opacity);
+ fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity);
} break;
case PAINT_COLOR: {
@@ -229,19 +229,19 @@ bool NRStyle::prepareFill(Inkscape::DrawingContext &ct, Geom::OptRect const &pai
return true;
}
-void NRStyle::applyFill(Inkscape::DrawingContext &ct)
+void NRStyle::applyFill(Inkscape::DrawingContext &dc)
{
- ct.setSource(fill_pattern);
- ct.setFillRule(fill_rule);
+ dc.setSource(fill_pattern);
+ dc.setFillRule(fill_rule);
}
-bool NRStyle::prepareStroke(Inkscape::DrawingContext &ct, Geom::OptRect const &paintbox)
+bool NRStyle::prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox)
{
if (!stroke_pattern) {
switch (stroke.type) {
case PAINT_SERVER: {
- //stroke_pattern = sp_paint_server_create_pattern(stroke.server, ct.raw(), paintbox, stroke.opacity);
- stroke_pattern = stroke.server->pattern_new(ct.raw(), paintbox, stroke.opacity);
+ //stroke_pattern = sp_paint_server_create_pattern(stroke.server, dc.raw(), paintbox, stroke.opacity);
+ stroke_pattern = stroke.server->pattern_new(dc.raw(), paintbox, stroke.opacity);
} break;
case PAINT_COLOR: {
@@ -256,14 +256,14 @@ bool NRStyle::prepareStroke(Inkscape::DrawingContext &ct, Geom::OptRect const &p
return true;
}
-void NRStyle::applyStroke(Inkscape::DrawingContext &ct)
+void NRStyle::applyStroke(Inkscape::DrawingContext &dc)
{
- ct.setSource(stroke_pattern);
- ct.setLineWidth(stroke_width);
- ct.setLineCap(line_cap);
- ct.setLineJoin(line_join);
- ct.setMiterLimit(miter_limit);
- cairo_set_dash(ct.raw(), dash, n_dash, dash_offset); // fixme
+ dc.setSource(stroke_pattern);
+ dc.setLineWidth(stroke_width);
+ dc.setLineCap(line_cap);
+ dc.setLineJoin(line_join);
+ dc.setMiterLimit(miter_limit);
+ cairo_set_dash(dc.raw(), dash, n_dash, dash_offset); // fixme
}
void NRStyle::update()
diff --git a/src/display/nr-style.h b/src/display/nr-style.h
index 8fd736cc3..e54eef547 100644
--- a/src/display/nr-style.h
+++ b/src/display/nr-style.h
@@ -28,10 +28,10 @@ struct NRStyle {
~NRStyle();
void set(SPStyle *);
- bool prepareFill(Inkscape::DrawingContext &ct, Geom::OptRect const &paintbox);
- bool prepareStroke(Inkscape::DrawingContext &ct, Geom::OptRect const &paintbox);
- void applyFill(Inkscape::DrawingContext &ct);
- void applyStroke(Inkscape::DrawingContext &ct);
+ bool prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox);
+ bool prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox);
+ void applyFill(Inkscape::DrawingContext &dc);
+ void applyStroke(Inkscape::DrawingContext &dc);
void update();
enum PaintType {
diff --git a/src/document.cpp b/src/document.cpp
index 634462001..470d0cc5a 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -381,16 +381,6 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
rroot->setAttribute("inkscape:version", Inkscape::version_string);
/* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */
- /* Quick hack 2 - get default image size into document */
- if (!rroot->attribute("width")) rroot->setAttribute("width", "100%");
- if (!rroot->attribute("height")) rroot->setAttribute("height", "100%");
- /* End of quick hack 2 */
-
- /* Quick hack 3 - Set uri attributes */
-// if (uri) { // this is done in do_change_uri()
-// rroot->setAttribute("sodipodi:docname", uri);
-// }
- /* End of quick hack 3 */
/* Eliminate obsolete sodipodi:docbase, for privacy reasons */
rroot->setAttribute("sodipodi:docbase", NULL);
@@ -483,7 +473,7 @@ SPDocument *SPDocument::createChildDoc(std::string const &uri)
SPDocument *parent = this;
SPDocument *document = NULL;
- while(parent != NULL && document == NULL) {
+ while(parent != NULL && parent->getURI() != NULL && document == NULL) {
// Check myself and any parents int he chain
if(uri == parent->getURI()) {
document = parent;
diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp
index cca541c5b..276dee362 100644
--- a/src/extension/internal/emf-inout.cpp
+++ b/src/extension/internal/emf-inout.cpp
@@ -4,6 +4,7 @@
/* Authors:
* Ulf Erikson <ulferikson@users.sf.net>
* Jon A. Cruz <jon@joncruz.org>
+ * David Mathog
* Abhishek Sharma
*
* Copyright (C) 2006-2008 Authors
@@ -1563,6 +1564,7 @@ int Emf::myEnhMetaFileProc(char *contents, unsigned int length, PEMF_CALLBACK_DA
tsp.vadvance = 0.0; /* meaningful only when a complex contains two or more lines */
tsp.taln = ALILEFT + ALIBASE;
tsp.ldir = LDIR_LR;
+ tsp.spaces = 0; // this field is only used for debugging
tsp.color.Red = 0; /* RGB Black */
tsp.color.Green = 0; /* RGB Black */
tsp.color.Blue = 0; /* RGB Black */
diff --git a/src/extension/internal/emf-inout.h b/src/extension/internal/emf-inout.h
index 97f93e71b..a97cb0a54 100644
--- a/src/extension/internal/emf-inout.h
+++ b/src/extension/internal/emf-inout.h
@@ -3,6 +3,7 @@
*/
/* Authors:
* Ulf Erikson <ulferikson@users.sf.net>
+ * David Mathog
*
* Copyright (C) 2006-2008 Authors
*
diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp
index 2680718cf..6d5bb6f4b 100644
--- a/src/extension/internal/emf-print.cpp
+++ b/src/extension/internal/emf-print.cpp
@@ -124,7 +124,7 @@ unsigned int PrintEmf::begin(Inkscape::Extension::Print *mod, SPDocument *doc)
char *rec;
gchar const *utf8_fn = mod->get_param_string("destination");
- // Typially PX2WORLD is 1200/90, using inkscape's default dpi
+ // Typically PX2WORLD is 1200/90, using inkscape's default dpi
PX2WORLD = 1200.0 / Inkscape::Util::Quantity::convert(1.0, "in", "px");
FixPPTCharPos = mod->get_param_bool("FixPPTCharPos");
FixPPTDashLine = mod->get_param_bool("FixPPTDashLine");
@@ -848,7 +848,7 @@ Geom::Path PrintEmf::pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect,
int vertices;
Geom::Path pR = pathv_to_simple_polygon(pathv, &vertices);
*is_rect = false;
- if(vertices==4){ // or else it cannot be a rectangle rectangle
+ if(vertices==4){ // or else it cannot be a rectangle
int vertex_count=0;
/* Get the ends of the LAST line segment.
Find minimum rotation to align rectangle with X,Y axes. (Very degenerate if it is rotated 45 degrees.) */
@@ -862,12 +862,17 @@ Geom::Path PrintEmf::pathv_to_rect(Geom::PathVector const &pathv, bool *is_rect,
if(fabs(ang) < fabs(*angle))*angle = -ang; // y increases down, flips sign on angle
}
}
+
+ /* For increased numerical stability, snap the angle to the nearest 1/100th of a degree. */
+ double convert = 36000.0/ (2.0 * M_PI);
+ *angle = round(*angle * convert)/convert;
for(Geom::Path::const_iterator cit = pR.begin(); cit != pR.end_open();++cit) {
P1_lead = cit->finalPoint();
v1 = unit_vector(P1 - P1_trail);
v2 = unit_vector(P1_lead - P1 );
- if(!Geom::are_near(dot(v1,v2), 0.0, 1e-5))break; // P1 is center of a turn that is not 90 degrees
+ // P1 is center of a turn that is not 90 degrees. Limit comes from cos(89.9) = .001745
+ if(!Geom::are_near(dot(v1,v2), 0.0, 2e-3))break;
P1_trail = P1;
P1 = P1_lead;
vertex_count++;
@@ -985,12 +990,13 @@ unsigned int PrintEmf::fill(
int rectDir=0;
Geom::Path pathRect;
if(FixPPTLinGrad && brush_stat && gv.mode == DRAW_LINEAR_GRADIENT){
- pathRect = pathv_to_rect(pathv, &is_Rect, &angle);
+ Geom::PathVector pvr = pathv * fill_transform;
+ pathRect = pathv_to_rect(pvr, &is_Rect, &angle);
if(is_Rect){
/* Gradientfill records can only be used if the gradient is parallel to the sides of the rectangle.
That must be checked here so that we can fall back to another form of gradient fill if it is not
the case. */
- rectDir = vector_rect_alignment(angle, gv.p2 - gv.p1);
+ rectDir = vector_rect_alignment(angle, (gv.p2 - gv.p1) * fill_transform);
if(!rectDir)is_Rect = false;
}
if(!is_Rect && !FixPPTGrad2Polys)brush_stat=0; // fall all the way back to a solid fill
@@ -1094,26 +1100,27 @@ unsigned int PrintEmf::fill(
U_XFORM tmpTransform;
double wRect, hRect;
- /* coordinates, w,h and transform for the ENTIRE retangle */
- ul = get_pathrect_corner(pathRect, angle, 0) * fill_transform * PX2WORLD;
- ur = get_pathrect_corner(pathRect, angle, 1) * fill_transform * PX2WORLD;
- lr = get_pathrect_corner(pathRect, angle, 2) * fill_transform * PX2WORLD;
+ /* coordinates: upper left, upper right, and lower right corners of the rectangle.
+ inkscape transform already applied, but needs to be scaled to EMF coordinates. */
+ ul = get_pathrect_corner(pathRect, angle, 0) * PX2WORLD;
+ ur = get_pathrect_corner(pathRect, angle, 1) * PX2WORLD;
+ lr = get_pathrect_corner(pathRect, angle, 2) * PX2WORLD;
wRect = Geom::distance(ul,ur);
hRect = Geom::distance(ur,lr);
/* The basic rectangle for all of these is placed with its UL corner at 0,0 with a size wRect,hRect.
Apply a world transform to place/scale it into the appropriate position on the drawing.
Actual gradientfill records are either this entire rectangle or slices of it as defined by the stops.
+ This rectangle has already been transformed by tf (whatever rotation/scale) Inkscape had applied to it.
*/
Geom::Affine tf2 = Geom::Rotate(-angle); // the rectangle may be drawn skewed to the coordinate system
- tf2 *= tf; // the coordinate system of the rectangular path may be rotated
tmpTransform.eM11 = tf2[0];
tmpTransform.eM12 = tf2[1];
tmpTransform.eM21 = tf2[2];
tmpTransform.eM22 = tf2[3];
- tmpTransform.eDx = (ul)[Geom::X];
- tmpTransform.eDy = (ul)[Geom::Y];
+ tmpTransform.eDx = round((ul)[Geom::X]); // use explicit round for better stability
+ tmpTransform.eDy = round((ul)[Geom::Y]);
rec = U_EMRSAVEDC_set();
if (!rec || emf_append((PU_ENHMETARECORD)rec, et, U_REC_FREE)) {
@@ -1138,10 +1145,10 @@ unsigned int PrintEmf::fill(
gMode = U_GRADIENT_FILL_RECT_V;
}
doff_base = doff_range;
- rcb.left = outUL[X];
- rcb.top = outUL[Y];
- rcb.right = outLR[X];
- rcb.bottom = outLR[Y];
+ rcb.left = round(outUL[X]); // use explicit round for better stability
+ rcb.top = round(outUL[Y]);
+ rcb.right = round(outLR[X]);
+ rcb.bottom = round(outLR[Y]);
sp_color_get_rgb_floatv(&tg->vector.stops[istop].color, rgb);
opa = tg->vector.stops[istop].opacity;
c2 = U_RGBA(255 * rgb[0], 255 * rgb[1], 255 * rgb[2], 255 * opa);
@@ -1157,7 +1164,6 @@ unsigned int PrintEmf::fill(
c1 = c2; // for next stop
ug4.UpperLeft = 0;
ug4.LowerRight= 1;
- /* NEED to push world transform here for rotations */
rec = U_EMRGRADIENTFILL_set(rcb, 2, 1, gMode, ut, (uint32_t *) &ug4 );
if (!rec || emf_append((PU_ENHMETARECORD)rec, et, U_REC_FREE)) {
g_error("Fatal programming error in PrintEmf::fill at U_EMRGRADIENTFILL_set");
diff --git a/src/extension/internal/emf-print.h b/src/extension/internal/emf-print.h
index 8fc9908e3..1e4970a46 100644
--- a/src/extension/internal/emf-print.h
+++ b/src/extension/internal/emf-print.h
@@ -1,8 +1,9 @@
/** @file
* @brief Enhanced Metafile printing - implementation
*/
-/* Author:
+/* Authors:
* Ulf Erikson <ulferikson@users.sf.net>
+ * David Mathog
*
* Copyright (C) 2006-2008 Authors
*
diff --git a/src/extension/internal/image-resolution.cpp b/src/extension/internal/image-resolution.cpp
index aee46aaba..18eb97f80 100644
--- a/src/extension/internal/image-resolution.cpp
+++ b/src/extension/internal/image-resolution.cpp
@@ -322,6 +322,12 @@ void ImageResolution::readjfif(char const *fn) {
y_ = cinfo.Y_density * 2.54;
ok_ = true;
}
+ /* According to http://www.jpeg.org/public/jfif.pdf (page 7):
+ * "Xdensity and Ydensity should always be non-zero".
+ * but in some cases, they are (see LP bug #1275443) */
+ if (x_ == 0 or y_ == 0) {
+ ok_ = false;
+ }
}
jpeg_destroy_decompress(&cinfo);
fclose(ifd);
diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c
index cd84910fc..e28e5effb 100644
--- a/src/extension/internal/text_reassemble.c
+++ b/src/extension/internal/text_reassemble.c
@@ -67,11 +67,11 @@ Optional compiler switches for development:
File: text_reassemble.c
-Version: 0.0.10
-Date: 06-MAY-2013
+Version: 0.0.12
+Date: 07-FEB-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
@@ -665,7 +665,7 @@ FT_INFO *ftinfo_clear(FT_INFO *fti){
free(fsp->file); /* release memory holding copies of paths */
free(fsp->fontspec); /* release memory holding copies of font names */
FcPatternDestroy(fsp->fpat); /* release memory for FontConfig fpats */
- FcFontSetDestroy(fti->fonts[i].fontset);
+ FcFontSetDestroy(fsp->fontset);
if(fsp->alts){ free(fsp->alts); }
}
free(fti->fonts);
@@ -726,9 +726,10 @@ int ftinfo_find_loaded_by_src(const FT_INFO *fti, const uint8_t *filename){
*/
int ftinfo_load_fontname(FT_INFO *fti, const char *fontspec){
- FcPattern *pattern, *fpat;
- FcFontSet *fontset;
- FcResult result = FcResultMatch;
+ FcPattern *pattern = NULL;
+ FcPattern *fpat = NULL;
+ FcFontSet *fontset = NULL;
+ FcResult result = FcResultMatch;
char *filename;
double fd;
FNT_SPECS *fsp;
@@ -738,38 +739,45 @@ int ftinfo_load_fontname(FT_INFO *fti, const char *fontspec){
if(!fti)return(-1);
/* If it is already loaded, do not load it again */
- if((status = ftinfo_find_loaded_by_spec(fti, (uint8_t *) fontspec))>=0){
- return(status);
- }
+ status = ftinfo_find_loaded_by_spec(fti, (uint8_t *) fontspec);
+ if(status >= 0){ return(status); }
+ status = 0; /* was -1, reset to 0 */
ftinfo_make_insertable(fti);
fi_idx = fti->used;
- if(!(pattern = FcNameParse((const FcChar8 *)fontspec)) )return(2);
- if(!FcConfigSubstitute(NULL, pattern, FcMatchPattern) )return(3);
- FcDefaultSubstitute(pattern);
- /* get a fontset, trimmed to only those with new glyphs as needed, so that missing glyph's may be handled */
- if(!(fontset = FcFontSort (NULL,pattern, FcTrue, NULL, &result))
- || result != FcResultMatch)return(4);
- if(!(fpat = FcFontRenderPrepare(NULL, pattern, fontset->fonts[0])) )return(405);
- if(FcPatternGetString( fpat, FC_FILE, 0, (FcChar8 **)&filename) != FcResultMatch)return(5);
- if(FcPatternGetDouble( fpat, FC_SIZE, 0, &fd) != FcResultMatch)return(6);
-
- /* copy these into memory for external use */
- fsp = &(fti->fonts[fti->used]);
- fsp->fontset = fontset;
- fsp->alts = NULL; /* Initially no links to alternate fonts */
- fsp->space = 0;
- fsp->file = (uint8_t *) U_strdup((char *) filename);
- fsp->fontspec = (uint8_t *) U_strdup((char *) fontspec);
- fsp->fpat = fpat;
- fsp->fsize = fd;
-
+ pattern = FcNameParse((const FcChar8 *)fontspec);
+ while(1) { /* this is NOT a loop, it uses breaks to avoid gotos and deep nesting */
+ if(!(pattern)){ status = -2; break; }
+ if(!FcConfigSubstitute(NULL, pattern, FcMatchPattern)){ status = -3; break; };
+ FcDefaultSubstitute(pattern);
+ /* get a fontset, trimmed to only those with new glyphs as needed, so that missing glyph's may be handled */
+ if(!(fontset = FcFontSort (NULL,pattern, FcTrue, NULL, &result)) || (result != FcResultMatch)){ status = -4; break; }
+ if(!(fpat = FcFontRenderPrepare(NULL, pattern, fontset->fonts[0]))){ status = -405; break; }
+ if(FcPatternGetString( fpat, FC_FILE, 0, (FcChar8 **)&filename) != FcResultMatch){ status = -5; break; }
+ if(FcPatternGetDouble( fpat, FC_SIZE, 0, &fd) != FcResultMatch){ status = -6; break; }
+
+ /* copy these into memory for external use */
+ fsp = &(fti->fonts[fti->used]);
+ fsp->fontset = fontset;
+ fsp->alts = NULL; /* Initially no links to alternate fonts */
+ fsp->space = 0;
+ fsp->file = (uint8_t *) U_strdup((char *) filename);
+ fsp->fontspec = (uint8_t *) U_strdup((char *) fontspec);
+ fsp->fpat = fpat;
+ fsp->fsize = fd;
+ break;
+ }
/* release FC's own memory related to this call that does not need to be kept around so that face will work */
- FcPatternDestroy(pattern);
+ if(pattern)FcPatternDestroy(pattern); /* done with this memory */
+ if(status<0){
+ if(fontset)FcFontSetDestroy(fontset);
+ if(fpat)FcPatternDestroy(fpat);
+ return(status);
+ }
/* get the current face */
- if(FT_New_Face( fti->library, (const char *) fsp->file, 0, &(fsp->face) )){ return(8); }
+ if(FT_New_Face( fti->library, (const char *) fsp->file, 0, &(fsp->face) )){ return(-8); }
if(FT_Set_Char_Size(
fsp->face, /* handle to face object */
@@ -777,12 +785,12 @@ int ftinfo_load_fontname(FT_INFO *fti, const char *fontspec){
fd*64, /* char_height in 1/64th of points */
72, /* horizontal device resolution, DPI */
72) /* vebrical device resolution, DPI */
- ){ return(9); }
+ ){ return(-9); }
/* The space advance is needed in various places. Get it now, and get it in the font units,
so that it can be scaled later with the text size */
status = TR_getadvance(fti, fsp,' ',0,FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP, FT_KERNING_UNSCALED, NULL, NULL);
- if(status < 0)return(7);
+ if(status < 0)return(-7);
fsp->spcadv = ((double) status)/(64.0);
fti->used++;
@@ -1380,7 +1388,7 @@ printf("Overlap rprect (LL,UR) dst:(%lf,%lf),(%lf,%lf) src:(%lf,%lf),(%lf,%lf)\n
}
/**
- \brief Check for a text element upstream from the start element and in the reversed direction.
+ \brief Check for various sorts of invalid text elements upstream (language dir changes, draw order backwards from language direction)
\returns 0 on success (not upstream), 1 if upstream, anything else is an error.
\param bri pointer to the BR_INFO structure
\param dst index of the destination bounding rectangle.
@@ -1405,6 +1413,12 @@ int brinfo_upstream(BR_INFO *bri, int dst, int src, int ddir, int sdir){
else if( ddir == LDIR_LR && sdir == LDIR_RL){
if((br_src->xll + br_src->xur)/2.0 <= br_dst->xll ){ status = 1; }
}
+ else if( ddir == LDIR_RL && sdir == LDIR_RL){
+ if(br_dst->xur <= (br_src->xll + br_src->xur)/2.0){ status = 1; }
+ }
+ else if( ddir == LDIR_LR && sdir == LDIR_LR){
+ if((br_src->xll + br_src->xur)/2.0 <= br_dst->xll ){ status = 1; }
+ }
return(status);
}
@@ -1490,13 +1504,19 @@ TR_INFO *trinfo_init(TR_INFO *tri){
!(tri->bri = brinfo_init()) ||
!(tri->cxi = cxinfo_init())
){ tri = trinfo_release(tri); }
+ tri->out = NULL; /* This will allocate as needed, it might not ever be needed. */
+ tri->qe = 0.0;
+ tri->esc = 0.0;
+ tri->x = DBL_MAX;
+ tri->y = DBL_MAX;
+ tri->dirty = 0;
tri->use_kern = 1;
- tri->usebk = BKCLR_NONE;
tri->load_flags = FT_LOAD_NO_SCALE;
tri->kern_mode = FT_KERNING_UNSCALED;
- tri->out = NULL; /* This will allocate as needed, it might not ever be needed. */
tri->outspace = 0;
tri->outused = 0;
+ tri->usebk = BKCLR_NONE;
+ memset(&(tri->bkcolor),0,sizeof(TRCOLORREF));
return(tri);
}
@@ -1552,9 +1572,6 @@ TR_INFO *trinfo_release_except_FC(TR_INFO *tri){
*/
TR_INFO *trinfo_clear(TR_INFO *tri){
if(tri){
- tri->dirty = 0; /* set these back to their defaults */
- tri->esc = 0.0;
- /* Do NOT modify use_kern, usebk, load_flags, or kern_mode */
if(tri->bri)tri->bri=brinfo_release(tri->bri);
if(tri->tpi)tri->tpi=tpinfo_release(tri->tpi);
@@ -1565,6 +1582,11 @@ TR_INFO *trinfo_clear(TR_INFO *tri){
tri->outused = 0;
tri->outspace = 0;
};
+ /* Do NOT modify: qe, use_kern, usebk, load_flags, kern_mode, or bkcolor. Set the rest back to their defaults */
+ tri->esc = 0.0;
+ tri->x = DBL_MAX;
+ tri->y = DBL_MAX;
+ tri->dirty = 0;
if(!(tri->tpi = tpinfo_init()) || /* re-init the pieces just released */
!(tri->bri = brinfo_init()) ||
!(tri->cxi = cxinfo_init())
@@ -1958,7 +1980,7 @@ void TR_layout_2_svg(TR_INFO *tri){
cutat=strcspn((char *)fti->fonts[tsp->fi_idx].fontspec,":");
sprintf(obuf,"font-family:%.*s;",cutat,fti->fonts[tsp->fi_idx].fontspec);
TRPRINT(tri, obuf);
- sprintf(obuf,"\n\">%s</text>\n",tsp->string);
+ sprintf(obuf,"\n\">%s</text>\n",&tsp->string[tsp->spaces]);
TRPRINT(tri, obuf);
#endif /* DBG_TR_INPUT debugging code, original text objects */
}
@@ -2278,7 +2300,10 @@ int TR_layout_analyze(TR_INFO *tri){
next logical piece of text is "upstream" positionally of its logical predecessor. The meaning of such
a construct is at best ambiguous. The test is only applied with respect to the first text chunk. This sort
of construct may appear when a valid initial construct like [1->English][2<-Hebrew][3->English] is edited
- and the leading chunk of text removed.
+ and the leading chunk of text removed.
+
+ Also reject reversed order text as in (English) <A><B><C> (draw order) arranged as <C><B><A>. This happens
+ if the language direction field is incorrect, perhaps due to a corrupt or malformed input file.
*/
if(brinfo_upstream(bri,
dst_rt, /* index into bri for dst */
@@ -2422,10 +2447,28 @@ int TR_layout_analyze(TR_INFO *tri){
}
}
- /* if x or y kern is less than the quantization error it is probably noise, set it to zero */
- if(fabs(tspj->xkern)<tri->qe)tspj->xkern = 0.0;
- if(fabs(tspj->ykern)<tri->qe)tspj->ykern = 0.0;
-
+ /* if x or y kern is less than twice the quantization error it is probably noise, set it to zero */
+ if(fabs(tspj->xkern) <= 2.0*tri->qe)tspj->xkern = 0.0;
+ if(fabs(tspj->ykern) <= 2.0*tri->qe)tspj->ykern = 0.0;
+
+ /* reintroduce spaces on the leading edge of text "j" if the kerning can be in part or in whole replaced
+ with 1 or 2 spaces */
+ if(tspj->ykern == 0.0){
+ double spaces = tspj->xkern/spcadv; /* negative on RL language, positive on LR */
+ if((ldir == LDIR_RL && (spaces <= -0.9 && spaces >= -2.1)) ||
+ (ldir == LDIR_LR && (spaces >= 0.9 && spaces <= 2.1)) ){
+ int ispaces = lround(spaces);
+ tspj->xkern -= ((double)ispaces*spcadv);
+ if(ispaces<0)ispaces=-ispaces;
+ size_t slen = strlen((char *)tspj->string);
+ uint8_t *newstring = malloc(1 + ispaces + slen);
+ sprintf((char *)newstring," "); /* start with two spaces, possibly overwrite one in the next line */
+ memcpy(newstring+ispaces,tspj->string,slen+1); /* copy existing string to proper position */
+ free(tspj->string);
+ tspj->string = newstring;
+ tspj->spaces = ispaces; // only needed to fix optional debugging SVG output later
+ }
+ }
tspi = tspj;
lastldir = ldir;
@@ -2699,7 +2742,7 @@ int main(int argc, char *argv[]){
tsp.weight = 80;
tsp.condensed = 100;
tsp.decoration = 0; /* none */
- tsp.co = 0;
+ tsp.spaces = 0; /* none */
tsp.fi_idx = -1; /* set to an invalid */
tsp.rt_tidx = -1; /* set to an invalid */
tsp.xkern = tsp.ykern = 0.0;
diff --git a/src/extension/internal/text_reassemble.h b/src/extension/internal/text_reassemble.h
index d85b233be..6c1acafe5 100644
--- a/src/extension/internal/text_reassemble.h
+++ b/src/extension/internal/text_reassemble.h
@@ -4,11 +4,11 @@
See text_reassemble.c for notes
File: text_reassemble.h
-Version: 0.0.12
-Date: 14-MAY-2013
+Version: 0.0.13
+Date: 06-FEB-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifndef _TEXT_REASSEMBLE_
@@ -189,6 +189,7 @@ typedef struct {
int weight; /**< weight, as in FontConfig */
int condensed; /**< condensed, as in FontConfig */
int decoration; /**< text decorations, ignored during assembly, used during output */
+ int spaces; /**< count of spaces converted from wide kerning (1 or 2) */
TRCOLORREF decColor; /**< text decoration color, ignored during assembly, used during output */
int co; /**< condensed override, if set Font name included narrow */
int rt_tidx; /**< index of rectangle that contains it */
diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp
index a72c16a88..fc54350df 100644
--- a/src/extension/internal/wmf-inout.cpp
+++ b/src/extension/internal/wmf-inout.cpp
@@ -4,6 +4,7 @@
/* Authors:
* Ulf Erikson <ulferikson@users.sf.net>
* Jon A. Cruz <jon@joncruz.org>
+ * David Mathog
* Abhishek Sharma
*
* Copyright (C) 2006-2008 Authors
@@ -1079,6 +1080,28 @@ Wmf::select_brush(PWMF_CALLBACK_DATA d, int index)
g_message("Please send WMF file to developers - select_brush U_WMR_DIBCREATEPATTERNBRUSH not bm16 or dib, not handled");
}
}
+ else if(iType == U_WMR_CREATEPATTERNBRUSH){
+ uint32_t tidx;
+ int cbPx;
+ U_BITMAP16 Bm16h;
+ const char *px;
+ if(U_WMRCREATEPATTERNBRUSH_get(record, &Bm16h, &cbPx, &px)){
+ tidx = add_bm16_image(d, Bm16h, px);
+ if(tidx == 0xFFFFFFFF){ // Problem with the image, for instance, an unsupported bitmap16 type
+ double r, g, b;
+ r = SP_COLOR_U_TO_F( U_RGBAGetR(d->dc[d->level].textColor));
+ g = SP_COLOR_U_TO_F( U_RGBAGetG(d->dc[d->level].textColor));
+ b = SP_COLOR_U_TO_F( U_RGBAGetB(d->dc[d->level].textColor));
+ d->dc[d->level].style.fill.value.color.set( r, g, b );
+ d->dc[d->level].fill_mode = DRAW_PAINT;
+ }
+ else {
+ d->dc[d->level].fill_idx = tidx;
+ d->dc[d->level].fill_mode = DRAW_IMAGE;
+ }
+ d->dc[d->level].fill_set = true;
+ }
+ }
}
@@ -1488,6 +1511,7 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK
tsp.vadvance = 0.0; /* meaningful only when a complex contains two or more lines */
tsp.taln = ALILEFT + ALIBASE;
tsp.ldir = LDIR_LR;
+ tsp.spaces = 0; // this field is only used for debugging
tsp.color.Red = 0; /* RGB Black */
tsp.color.Green = 0; /* RGB Black */
tsp.color.Blue = 0; /* RGB Black */
@@ -1498,6 +1522,7 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK
tsp.condensed = 100;
tsp.co = 0;
tsp.fi_idx = -1; /* set to an invalid */
+ tsp.rt_tidx = -1; /* set to an invalid */
SVGOStringStream dbg_str;
@@ -1568,7 +1593,10 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK
d->dc[d->level].sizeView.x = d->dc[d->level].sizeWnd.x = 0;
d->dc[d->level].sizeView.y = d->dc[d->level].sizeWnd.y = 0;
- // Upper left corner in device units, usually both 0, but not always
+ /* Upper left corner in device units, usually both 0, but not always.
+ If a placeable header is used, and later a windoworg/windowext are found, then
+ the placeable information will be ignored.
+ */
d->ulCornerInX = Placeable.Dst.left;
d->ulCornerInY = Placeable.Dst.top;
@@ -1805,6 +1833,8 @@ std::cout << "BEFORE DRAW"
{
dbg_str << "<!-- U_WMR_SETWINDOWORG -->\n";
nSize = U_WMRSETWINDOWORG_get(contents, &d->dc[d->level].winorg);
+ d->ulCornerOutX = 0.0; // In the examples seen to date if this record is used with a placeable header, that header is ignored
+ d->ulCornerOutY = 0.0;
break;
}
case U_WMR_SETWINDOWEXT:
@@ -2322,12 +2352,12 @@ std::cout << "BEFORE DRAW"
break;
case U_WMR_CREATEBRUSHINDIRECT:
case U_WMR_DIBCREATEPATTERNBRUSH:
+ case U_WMR_CREATEPATTERNBRUSH: // <- this one did not display properly on XP, DIBCREATEPATTERNBRUSH works
select_brush(d, index);
break;
case U_WMR_CREATEFONTINDIRECT:
select_font(d, index);
break;
- case U_WMR_CREATEPATTERNBRUSH: // <- this one did not display properly on XP, DIBCREATEPATTERNBRUSH works
case U_WMR_CREATEPALETTE:
case U_WMR_CREATEBITMAPINDIRECT:
case U_WMR_CREATEBITMAP:
@@ -2376,6 +2406,7 @@ std::cout << "BEFORE DRAW"
if(iType == U_WMR_TEXTOUT){
dbg_str << "<!-- U_WMR_TEXTOUT -->\n";
nSize = U_WMRTEXTOUT_get(contents, &Dst, &tlen, &text);
+ Opts=0;
}
else {
dbg_str << "<!-- U_WMR_EXTTEXTOUT -->\n";
@@ -3053,7 +3084,14 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri )
// Scale and translate objects
double scale = Inkscape::Util::Quantity::convert(1, "px", doc_unit);
ShapeEditor::blockSetItem(true);
- doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, doc->getHeight().value("px")));
+ double dh;
+ if(SP_ACTIVE_DOCUMENT){ // for file menu open or import, or paste from clipboard
+ dh = SP_ACTIVE_DOCUMENT->getHeight().value("px");
+ }
+ else { // for open via --file on command line
+ dh = doc->getHeight().value("px");
+ }
+ doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, dh));
ShapeEditor::blockSetItem(false);
Inkscape::DocumentUndo::setUndoSensitive(doc, saved);
diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp
index cd4f539ec..1ba6628c5 100644
--- a/src/helper/pixbuf-ops.cpp
+++ b/src/helper/pixbuf-ops.cpp
@@ -140,10 +140,10 @@ Inkscape::Pixbuf *sp_generate_internal_bitmap(SPDocument *doc, gchar const */*fi
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
if (cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS) {
- Inkscape::DrawingContext ct(surface, Geom::Point(0,0));
+ Inkscape::DrawingContext dc(surface, Geom::Point(0,0));
// render items
- drawing.render(ct, final_bbox, Inkscape::DrawingItem::RENDER_BYPASS_CACHE);
+ drawing.render(dc, final_bbox, Inkscape::DrawingItem::RENDER_BYPASS_CACHE);
inkpb = new Inkscape::Pixbuf(surface);
}
diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp
index a16fe8e12..a7ebe7423 100644
--- a/src/helper/png-write.cpp
+++ b/src/helper/png-write.cpp
@@ -335,14 +335,14 @@ sp_export_get_rows(guchar const **rows, void **to_free, int row, int num_rows, v
cairo_surface_t *s = cairo_image_surface_create_for_data(
px, CAIRO_FORMAT_ARGB32, ebp->width, num_rows, stride);
- Inkscape::DrawingContext ct(s, bbox.min());
- ct.setSource(ebp->background);
- ct.setOperator(CAIRO_OPERATOR_SOURCE);
- ct.paint();
- ct.setOperator(CAIRO_OPERATOR_OVER);
+ Inkscape::DrawingContext dc(s, bbox.min());
+ dc.setSource(ebp->background);
+ dc.setOperator(CAIRO_OPERATOR_SOURCE);
+ dc.paint();
+ dc.setOperator(CAIRO_OPERATOR_OVER);
/* Render */
- ebp->drawing->render(ct, bbox);
+ ebp->drawing->render(dc, bbox);
cairo_surface_destroy(s);
*to_free = px;
diff --git a/src/libuemf/README b/src/libuemf/README
index 4c23cdd52..cfa322178 100644
--- a/src/libuemf/README
+++ b/src/libuemf/README
@@ -366,6 +366,12 @@ History
(Note, version numbers in files represent the libUEMF release where it was last modified, so not
all files will show the same version numbers in each release.)
+0.1.11 2014-01-29
+ Fixed bug in uwmf.c (wrong minimum record size on U_WMRTEXTOUT)
+ Fixed bug in uwmf.c (U_WMRCREATEPATTERNBRUSH not right)
+ Added error handling to uemf_utf.c for cases where src is a null pointer.
+ Added a test of createpatternbrush to testlib_wmf
+
0.1.10 2014-01-14
Slight changes in documentation for uemf.h.
Fixed typo in uemf_endian.c.
diff --git a/src/libuemf/uemf_utf.c b/src/libuemf/uemf_utf.c
index f329e74d9..bce60af4d 100644
--- a/src/libuemf/uemf_utf.c
+++ b/src/libuemf/uemf_utf.c
@@ -12,11 +12,11 @@
/*
File: uemf_utf.c
-Version: 0.0.4
-Date: 19-MAR-2013
+Version: 0.0.5
+Date: 29-JAN-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
@@ -68,9 +68,14 @@ These functions are used for development and debugging and should be be includie
void wchar8show(
const char *src
){
- printf("char show\n");
- size_t srclen = 0;
- while(*src){ printf("%d %d %x\n",(int) srclen,*src,*src); srclen++; src++; }
+ if(!src){
+ printf("char show <NULL>\n");
+ }
+ else {
+ printf("char show\n");
+ size_t srclen = 0;
+ while(*src){ printf("%d %d %x\n",(int) srclen,*src,*src); srclen++; src++; }
+ }
}
/**
@@ -80,9 +85,14 @@ void wchar8show(
void wchar16show(
const uint16_t *src
){
- printf("uint16_t show\n");
- size_t srclen = 0;
- while(*src){ printf("%d %d %x\n",(int) srclen,*src,*src); srclen++; src++; }
+ if(!src){
+ printf("uint16_t show <NULL>\n");
+ }
+ else {
+ printf("uint16_t show\n");
+ size_t srclen = 0;
+ while(*src){ printf("%d %d %x\n",(int) srclen,*src,*src); srclen++; src++; }
+ }
}
/**
@@ -91,9 +101,14 @@ void wchar16show(
void wchar32show(
const uint32_t *src
){
- printf("uint32_t show\n");
- size_t srclen = 0;
- while(*src){ printf("%d %d %x\n",(int) srclen,*src,*src); srclen++; src++; }
+ if(!src){
+ printf("uint32_t show <NULL>\n");
+ }
+ else {
+ printf("uint32_t show\n");
+ size_t srclen = 0;
+ while(*src){ printf("%d %d %x\n",(int) srclen,*src,*src); srclen++; src++; }
+ }
}
/**
@@ -104,13 +119,19 @@ void wchartshow(
const wchar_t *src
){
uint32_t val;
- printf("wchar_t show\n");
- size_t srclen = 0;
- while(*src){
- val = *src; // because *src is wchar_t is not strictly an integer type, can cause warnings on next line
- printf("%d %d %x\n",(int) srclen,val,val);
- srclen++;
- src++;
+ if(!src){
+ printf("wchar_t show <NULL>\n");
+ }
+ else {
+ printf("wchar_t show\n");
+ size_t srclen = 0;
+ if(!src)return;
+ while(*src){
+ val = *src; // because *src is wchar_t is not strictly an integer type, can cause warnings on next line
+ printf("%d %d %x\n",(int) srclen,val,val);
+ srclen++;
+ src++;
+ }
}
}
@@ -127,7 +148,9 @@ size_t wchar16len(
const uint16_t *src
){
size_t srclen = 0;
- while(*src){ srclen++; src++; }
+ if(src){
+ while(*src){ srclen++; src++; }
+ }
return(srclen);
}
@@ -139,7 +162,9 @@ size_t wchar32len(
const uint32_t *src
){
size_t srclen = 0;
- while(*src){ srclen++; src++; }
+ if(src){
+ while(*src){ srclen++; src++; }
+ }
return(srclen);
}
@@ -154,9 +179,11 @@ void wchar16strncpy(
const uint16_t *src,
size_t nchars
){
- for(;nchars;nchars--,dst++,src++){
- *dst = *src;
- if(!*src)break;
+ if(src){
+ for(;nchars;nchars--,dst++,src++){
+ *dst = *src;
+ if(!*src)break;
+ }
}
}
@@ -172,8 +199,10 @@ void wchar16strncpypad(
const uint16_t *src,
size_t nchars
){
- for(;*src && nchars;nchars--,dst++,src++){ *dst = *src; }
- for(;nchars;nchars--,dst++){ *dst = 0; } // Pad the remainder
+ if(src){
+ for(;*src && nchars;nchars--,dst++,src++){ *dst = *src; }
+ for(;nchars;nchars--,dst++){ *dst = 0; } // Pad the remainder
+ }
}
/* For the following converstion functions, remember that iconv() modifies ALL of its parameters,
@@ -197,6 +226,7 @@ uint16_t *U_Utf32leToUtf16le(
char *dst,*dst2;
size_t srclen,dstlen,status;
+ if(!src)return(NULL);
if(max){ srclen = 4*max; }
else { srclen = 4 + 4*wchar32len(src); } //include terminator, length in BYTES
@@ -226,6 +256,8 @@ uint32_t *U_Utf16leToUtf32le(
char *dst,*dst2;
char *src2 = (char *) src;
size_t srclen,dstlen,status;
+
+ if(!src)return(NULL);
if(max){ srclen = 2*max; }
else { srclen = 2*wchar16len(src)+2; } // include terminator, length in BYTES
dstlen = 2*(2 + srclen); // This should always work
@@ -261,6 +293,8 @@ uint32_t *U_Latin1ToUtf32le(
char *dst,*dst2;
char *src2 = (char *) src;
size_t srclen,dstlen,status;
+
+ if(!src)return(NULL);
if(max){ srclen = max; }
else { srclen = strlen(src)+1; } // include terminator, length in BYTES
dstlen = sizeof(uint32_t)*(1 + srclen); // This should always work but might waste some space
@@ -290,6 +324,8 @@ uint32_t *U_Utf8ToUtf32le(
char *dst,*dst2;
char *src2 = (char *) src;
size_t srclen,dstlen,status;
+
+ if(!src)return(NULL);
if(max){ srclen = max; }
else { srclen = strlen(src)+1; } // include terminator, length in BYTES
dstlen = sizeof(uint32_t)*(1 + srclen); // This should always work but might waste some space
@@ -319,6 +355,8 @@ char *U_Utf32leToUtf8(
char *dst,*dst2;
char *src2 = (char *) src;
size_t srclen,dstlen,status;
+
+ if(!src)return(NULL);
if(max){ srclen = 4*max; }
else { srclen = 4*(1 + wchar32len(src)); } //include terminator, length in BYTES
dstlen = 1 + srclen; // This should always work but might waste some space
@@ -349,6 +387,7 @@ uint16_t *U_Utf8ToUtf16le(
size_t srclen,dstlen,status;
iconv_t conv;
+ if(!src)return(NULL);
if(max){ srclen = max; }
else { srclen = strlen(src)+1; } // include terminator, length in BYTES
dstlen = 2 * (1 + srclen); // this will always work, but may waste space
@@ -378,6 +417,8 @@ char *U_Utf16leToUtf8(
char *dst, *dst2;
char *ret=NULL;
size_t srclen,dstlen,status;
+
+ if(!src)return(NULL);
if(max){ srclen = 2*max; }
else { srclen = 2*(1 +wchar16len(src)); } //include terminator, length in BYTES
dstlen = 1 + 2*srclen; // this will always work, but may waste space
@@ -410,6 +451,8 @@ char *U_Utf16leToLatin1(
char *dst, *dst2;
char *ret=NULL;
size_t srclen,dstlen,status;
+
+ if(!src)return(NULL);
if(max){ srclen = 2*max; }
else { srclen = 2*(1 +wchar16len(src)); } //include terminator, length in BYTES
dstlen = 1 + srclen; // this will always work as latin1 is always 1 byte/character
diff --git a/src/libuemf/uwmf.c b/src/libuemf/uwmf.c
index a6ac963cb..be1feadea 100644
--- a/src/libuemf/uwmf.c
+++ b/src/libuemf/uwmf.c
@@ -19,11 +19,11 @@
/*
File: uwmf.c
-Version: 0.0.12
-Date: 25-NOV-2013
+Version: 0.0.13
+Date: 30-JAN-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
@@ -4271,13 +4271,12 @@ char *U_WMRCREATEPATTERNBRUSH_set(
if(!Bm16 || !Pattern)return(NULL);
cbPat = (((Bm16->Width * Bm16->BitsPixel + 15) >> 4) << 1) * Bm16->Height;
- irecsize = U_SIZE_METARECORD + 14 + 4 + 18 + cbPat; /* core WMR + truncated Bm16 + pattern */
+ irecsize = U_SIZE_METARECORD + 14 + 18 + cbPat; /* core WMR + truncated Bm16 + 18 spaces bytes + pattern */
record = malloc(irecsize);
if(record){
U_WMRCORE_SETRECHEAD(record,irecsize,U_WMR_CREATEPATTERNBRUSH);
off = U_SIZE_METARECORD;
- memcpy(record + off, Bm16, 14); off+=14; /* Truncated bitmap16 object*/
- memset(record + off, 0, 4); off+=4; /* 4 bytes of its "bits", which are ignored */
+ memcpy(record + off, Bm16, 14); off+=14; /* Truncated bitmap16 object, last 4 bytes are to be ignored*/
memset(record + off, 0, 18); off+=18; /* 18 bytes of zero, which are ignored */
memcpy(record + off, Pattern, cbPat); /* The pattern array */
}
@@ -5359,7 +5358,7 @@ int U_WMRTEXTOUT_get(
){
int16_t L2;
int off;
- int size = U_WMRCORE_RECSAFE_get(contents, (U_SIZE_WMRPATBLT));
+ int size = U_WMRCORE_RECSAFE_get(contents, (U_SIZE_WMRTEXTOUT));
if(!size)return(0);
*Length = *(int16_t *)(contents + offsetof(U_WMRTEXTOUT, Length));
*string = contents + offsetof(U_WMRTEXTOUT, String); /* May not be null terminated!!! */
@@ -6851,12 +6850,15 @@ int U_WMRCREATEPATTERNBRUSH_get(
const char **Pattern
){
int off = U_SIZE_METARECORD;
- int size = U_WMRCORE_RECSAFE_get(contents, (U_SIZE_WMRSETDIBTODEV));
+ /* size in next one is
+ 6 (core header) + 14 (truncated bitmap16) + 18 bytes reserved + 2 bytes (at least) for data */
+ int size = U_WMRCORE_RECSAFE_get(contents, (U_SIZE_METARECORD + 14 + 18 + 2));
if(!size)return(0);
memset(Bm16, 0, U_SIZE_BITMAP16);
- memcpy(Bm16, contents + off, 14); /* BM16 is truncated in this record type */
+ /* BM16 is truncated in this record type to 14 bytes, last 4 bytes must be ignored, so they are not even copied */
+ memcpy(Bm16, contents + off, 10);
*pasize = (((Bm16->Width * Bm16->BitsPixel + 15) >> 4) << 1) * Bm16->Height;
- off += 36; /* skip [truncated bitmap16 object and 18 bytes of reserved */
+ off += 32; /* skip [14 bytes of truncated bitmap16 object and 18 bytes of reserved */
*Pattern = (contents + off);
return(size);
}
diff --git a/src/marker.cpp b/src/marker.cpp
index b9464186d..900f8a2ca 100644
--- a/src/marker.cpp
+++ b/src/marker.cpp
@@ -47,18 +47,15 @@ namespace {
bool markerRegistered = SPFactory::instance().registerObject("svg:marker", createMarker);
}
-SPMarker::SPMarker() : SPGroup() {
- this->aspect_clip = 0;
- this->aspect_align = 0;
- this->aspect_set = 0;
- this->markerUnits = 0;
- this->orient_auto = 0;
- this->markerUnits_set = 0;
- this->orient_set = 0;
- this->orient = 0;
-
- this->viewBox = Geom::OptRect();
- this->c2p.setIdentity();
+SPMarker::SPMarker() : SPGroup(), SPViewBox() {
+
+ this->markerUnits = 0;
+ this->markerUnits_set = 0;
+
+ this->orient_auto = 0;
+ this->orient_set = 0;
+ this->orient = 0;
+
this->views = NULL;
}
@@ -177,133 +174,14 @@ void SPMarker::set(unsigned int key, const gchar* value) {
break;
case SP_ATTR_VIEWBOX:
- this->viewBox = Geom::OptRect();
-
- if (value) {
- double x, y, width, height;
- char *eptr;
-
- /* fixme: We have to take original item affine into account */
- /* fixme: Think (Lauris) */
- eptr = (gchar *) value;
- x = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- y = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- width = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- height = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- if ((width > 0) && (height > 0)) {
- /* Set viewbox */
- this->viewBox = Geom::Rect(Geom::Point(x, y), Geom::Point(x + width, y + height));
- }
- }
-
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
- break;
+ set_viewBox( value );
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
+ break;
case SP_ATTR_PRESERVEASPECTRATIO:
- /* Do setup before, so we can use break to escape */
- this->aspect_set = FALSE;
- this->aspect_align = SP_ASPECT_NONE;
- this->aspect_clip = SP_ASPECT_MEET;
-
- this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
-
- if (value) {
- int len;
- gchar c[256];
- const gchar *p, *e;
- unsigned int align, clip;
- p = value;
-
- while (*p && *p == 32) {
- p += 1;
- }
-
- if (!*p) {
- break;
- }
-
- e = p;
-
- while (*e && *e != 32) {
- e += 1;
- }
-
- len = e - p;
-
- if (len > 8) {
- break;
- }
-
- memcpy (c, value, len);
-
- c[len] = 0;
-
- /* Now the actual part */
- if (!strcmp (c, "none")) {
- align = SP_ASPECT_NONE;
- } else if (!strcmp (c, "xMinYMin")) {
- align = SP_ASPECT_XMIN_YMIN;
- } else if (!strcmp (c, "xMidYMin")) {
- align = SP_ASPECT_XMID_YMIN;
- } else if (!strcmp (c, "xMaxYMin")) {
- align = SP_ASPECT_XMAX_YMIN;
- } else if (!strcmp (c, "xMinYMid")) {
- align = SP_ASPECT_XMIN_YMID;
- } else if (!strcmp (c, "xMidYMid")) {
- align = SP_ASPECT_XMID_YMID;
- } else if (!strcmp (c, "xMaxYMid")) {
- align = SP_ASPECT_XMAX_YMID;
- } else if (!strcmp (c, "xMinYMax")) {
- align = SP_ASPECT_XMIN_YMAX;
- } else if (!strcmp (c, "xMidYMax")) {
- align = SP_ASPECT_XMID_YMAX;
- } else if (!strcmp (c, "xMaxYMax")) {
- align = SP_ASPECT_XMAX_YMAX;
- } else {
- break;
- }
-
- clip = SP_ASPECT_MEET;
-
- while (*e && *e == 32) {
- e += 1;
- }
-
- if (*e) {
- if (!strcmp (e, "meet")) {
- clip = SP_ASPECT_MEET;
- } else if (!strcmp (e, "slice")) {
- clip = SP_ASPECT_SLICE;
- } else {
- break;
- }
- }
-
- this->aspect_set = TRUE;
- this->aspect_align = align;
- this->aspect_clip = clip;
- }
- break;
+ set_preserveAspectRatio( value );
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
+ break;
default:
SPGroup::set(key, value);
@@ -312,112 +190,23 @@ void SPMarker::set(unsigned int key, const gchar* value) {
}
void SPMarker::update(SPCtx *ctx, guint flags) {
- SPItemCtx rctx;
- // fixme: We have to set up clip here too
+ SPItemCtx ictx;
// Copy parent context
- rctx.flags = ctx->flags;
+ ictx.flags = ctx->flags;
// Initialize transformations
- rctx.i2doc = Geom::identity();
- rctx.i2vp = Geom::identity();
+ ictx.i2doc = Geom::identity();
+ ictx.i2vp = Geom::identity();
// Set up viewport
- rctx.viewport = Geom::Rect::from_xywh(0, 0, this->markerWidth.computed, this->markerHeight.computed);
-
- // Start with identity transform
- this->c2p.setIdentity();
-
- // Viewbox is always present, either implicitly or explicitly
- Geom::Rect vb;
- if (this->viewBox) {
- vb = *this->viewBox;
- } else {
- vb = rctx.viewport;
- }
-
- // Now set up viewbox transformation
-
- // Determine actual viewbox in viewport coordinates
- // double x = 0;
- // double y = 0;
- double width = 0;
- double height = 0;
-
- if (this->aspect_align == SP_ASPECT_NONE) {
- // x = 0.0;
- // y = 0.0;
- width = rctx.viewport.width();
- height = rctx.viewport.height();
- } else {
- double scalex, scaley, scale;
- // Things are getting interesting
- scalex = rctx.viewport.width() / (vb.width());
- scaley = rctx.viewport.height() / (vb.height());
- scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley);
- width = (vb.width()) * scale;
- height = (vb.height()) * scale;
-
- // Now place viewbox to requested position
- /*switch (marker->aspect_align) {
- case SP_ASPECT_XMIN_YMIN:
- x = 0.0;
- y = 0.0;
- break;
- case SP_ASPECT_XMID_YMIN:
- x = 0.5 * (rctx.viewport.width() - width);
- y = 0.0;
- break;
- case SP_ASPECT_XMAX_YMIN:
- x = 1.0 * (rctx.viewport.width() - width);
- y = 0.0;
- break;
- case SP_ASPECT_XMIN_YMID:
- x = 0.0;
- y = 0.5 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMID_YMID:
- x = 0.5 * (rctx.viewport.width() - width);
- y = 0.5 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMAX_YMID:
- x = 1.0 * (rctx.viewport.width() - width);
- y = 0.5 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMIN_YMAX:
- x = 0.0;
- y = 1.0 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMID_YMAX:
- x = 0.5 * (rctx.viewport.width() - width);
- y = 1.0 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMAX_YMAX:
- x = 1.0 * (rctx.viewport.width() - width);
- y = 1.0 * (rctx.viewport.height() - height);
- break;
- default:
- x = 0.0;
- y = 0.0;
- break;
- }*/
- }
-
- // TODO fixme: all that work is done to figure out x and y, which are just ignored. Check why.
+ ictx.viewport = Geom::Rect::from_xywh(0, 0, this->markerWidth.computed, this->markerHeight.computed);
- // viewbox transformation and reference translation
- this->c2p = Geom::Translate(-this->refX.computed, -this->refY.computed) *
- Geom::Scale(width / vb.width(), height / vb.height());
+ SPItemCtx rctx = get_rctx( &ictx );
- rctx.i2doc = this->c2p * rctx.i2doc;
-
- // If viewBox is set reinitialize child viewport
- // Otherwise it already correct
- if (this->viewBox) {
- rctx.viewport = *this->viewBox;
- rctx.i2vp = Geom::identity();
- }
+ // Shift according to refX, refY
+ this->c2p = Geom::Translate(this->viewBox.left()-this->refX.computed, this->viewBox.top()-this->refY.computed) * this->c2p;
// And invoke parent method
SPGroup::update((SPCtx *) &rctx, flags);
@@ -494,8 +283,12 @@ Inkscape::XML::Node* SPMarker::write(Inkscape::XML::Document *xml_doc, Inkscape:
}
Inkscape::DrawingItem* SPMarker::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) {
- // CPPIFY: correct?
- return SPGroup::show(drawing, key, flags);
+ // Markers in tree are never shown directly even if outside of <defs>.
+ return 0;
+}
+
+Inkscape::DrawingItem* SPMarker::private_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) {
+ return SPGroup::show(drawing, key, flags);
}
void SPMarker::hide(unsigned int key) {
@@ -575,7 +368,7 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent,
}
if (!v->items[pos]) {
/* Parent class ::show method */
- v->items[pos] = marker->show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS);
+ v->items[pos] = marker->private_show(parent->drawing(), key, SP_ITEM_REFERENCE_FLAGS);
if (v->items[pos]) {
/* fixme: Position (Lauris) */
diff --git a/src/marker.h b/src/marker.h
index b780950de..21ad63a41 100644
--- a/src/marker.h
+++ b/src/marker.h
@@ -31,8 +31,9 @@ struct SPMarkerView;
#include "sp-item-group.h"
#include "sp-marker-loc.h"
#include "uri-references.h"
+#include "viewbox.h"
-class SPMarker : public SPGroup {
+class SPMarker : public SPGroup, public SPViewBox {
public:
SPMarker();
virtual ~SPMarker();
@@ -54,17 +55,6 @@ public:
unsigned int orient_auto : 1;
float orient;
- /* viewBox; */
- Geom::OptRect viewBox;
-
- /* preserveAspectRatio */
- unsigned int aspect_set : 1;
- unsigned int aspect_align : 4;
- unsigned int aspect_clip : 1;
-
- /* Child to parent additional transform */
- Geom::Affine c2p;
-
/* Private views */
SPMarkerView *views;
@@ -75,6 +65,7 @@ public:
virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags);
virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
+ virtual Inkscape::DrawingItem* private_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
virtual void hide(unsigned int key);
virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type) const;
diff --git a/src/sp-image.cpp b/src/sp-image.cpp
index 8f7a60ca6..5f630f7b7 100644
--- a/src/sp-image.cpp
+++ b/src/sp-image.cpp
@@ -119,14 +119,12 @@ SPObject* createImage() {
bool imageRegistered = SPFactory::instance().registerObject("svg:image", createImage);
}
-SPImage::SPImage() : SPItem() {
- this->aspect_clip = 0;
+SPImage::SPImage() : SPItem(), SPViewBox() {
this->x.unset();
this->y.unset();
this->width.unset();
this->height.unset();
- this->aspect_align = SP_ASPECT_NONE;
this->clipbox = Geom::Rect();
this->sx = this->sy = 1.0;
this->ox = this->oy = 0.0;
@@ -195,8 +193,8 @@ void SPImage::set(unsigned int key, const gchar* value) {
break;
case SP_ATTR_X:
- if (!this->x.readAbsolute(value)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
+ /* ex, em not handled correctly. */
+ if (!this->x.read(value)) {
this->x.unset();
}
@@ -204,8 +202,8 @@ void SPImage::set(unsigned int key, const gchar* value) {
break;
case SP_ATTR_Y:
- if (!this->y.readAbsolute(value)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
+ /* ex, em not handled correctly. */
+ if (!this->y.read(value)) {
this->y.unset();
}
@@ -213,8 +211,8 @@ void SPImage::set(unsigned int key, const gchar* value) {
break;
case SP_ATTR_WIDTH:
- if (!this->width.readAbsolute(value)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
+ /* ex, em not handled correctly. */
+ if (!this->width.read(value)) {
this->width.unset();
}
@@ -222,8 +220,8 @@ void SPImage::set(unsigned int key, const gchar* value) {
break;
case SP_ATTR_HEIGHT:
- if (!this->height.readAbsolute(value)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
+ /* ex, em not handled correctly. */
+ if (!this->height.read(value)) {
this->height.unset();
}
@@ -231,67 +229,8 @@ void SPImage::set(unsigned int key, const gchar* value) {
break;
case SP_ATTR_PRESERVEASPECTRATIO:
- /* Do setup before, so we can use break to escape */
- this->aspect_align = SP_ASPECT_NONE;
- this->aspect_clip = SP_ASPECT_MEET;
+ set_preserveAspectRatio( value );
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
-
- if (value) {
- int len;
- gchar c[256];
- const gchar *p, *e;
- unsigned int align, clip;
- p = value;
- while (*p && *p == 32) p += 1;
- if (!*p) break;
- e = p;
- while (*e && *e != 32) e += 1;
- len = e - p;
- if (len > 8) break;
- memcpy (c, value, len);
- c[len] = 0;
- /* Now the actual part */
- if (!strcmp (c, "none")) {
- align = SP_ASPECT_NONE;
- } else if (!strcmp (c, "xMinYMin")) {
- align = SP_ASPECT_XMIN_YMIN;
- } else if (!strcmp (c, "xMidYMin")) {
- align = SP_ASPECT_XMID_YMIN;
- } else if (!strcmp (c, "xMaxYMin")) {
- align = SP_ASPECT_XMAX_YMIN;
- } else if (!strcmp (c, "xMinYMid")) {
- align = SP_ASPECT_XMIN_YMID;
- } else if (!strcmp (c, "xMidYMid")) {
- align = SP_ASPECT_XMID_YMID;
- } else if (!strcmp (c, "xMaxYMid")) {
- align = SP_ASPECT_XMAX_YMID;
- } else if (!strcmp (c, "xMinYMax")) {
- align = SP_ASPECT_XMIN_YMAX;
- } else if (!strcmp (c, "xMidYMax")) {
- align = SP_ASPECT_XMID_YMAX;
- } else if (!strcmp (c, "xMaxYMax")) {
- align = SP_ASPECT_XMAX_YMAX;
- } else {
- break;
- }
-
- clip = SP_ASPECT_MEET;
-
- while (*e && *e == 32) e += 1;
-
- if (*e) {
- if (!strcmp (e, "meet")) {
- clip = SP_ASPECT_MEET;
- } else if (!strcmp (e, "slice")) {
- clip = SP_ASPECT_SLICE;
- } else {
- break;
- }
- }
-
- this->aspect_align = align;
- this->aspect_clip = clip;
- }
break;
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
@@ -322,7 +261,79 @@ void SPImage::set(unsigned int key, const gchar* value) {
sp_image_set_curve(this); //creates a curve at the image's boundary for snapping
}
+// BLIP
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+void SPImage::apply_profile(Inkscape::Pixbuf *pixbuf) {
+
+ // TODO: this will prevent using MIME data when exporting.
+ // Integrate color correction into loading.
+ pixbuf->ensurePixelFormat(Inkscape::Pixbuf::PF_GDK);
+ int imagewidth = pixbuf->width();
+ int imageheight = pixbuf->height();
+ int rowstride = pixbuf->rowstride();;
+ guchar* px = pixbuf->pixels();
+
+ if ( px ) {
+ DEBUG_MESSAGE( lcmsFive, "in <image>'s sp_image_update. About to call colorprofile_get_handle()" );
+
+ guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN;
+ cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( this->document,
+ &profIntent,
+ this->color_profile );
+ if ( prof ) {
+ cmsProfileClassSignature profileClass = cmsGetDeviceClass( prof );
+ if ( profileClass != cmsSigNamedColorClass ) {
+ int intent = INTENT_PERCEPTUAL;
+
+ switch ( profIntent ) {
+ case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC:
+ intent = INTENT_RELATIVE_COLORIMETRIC;
+ break;
+ case Inkscape::RENDERING_INTENT_SATURATION:
+ intent = INTENT_SATURATION;
+ break;
+ case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
+ intent = INTENT_ABSOLUTE_COLORIMETRIC;
+ break;
+ case Inkscape::RENDERING_INTENT_PERCEPTUAL:
+ case Inkscape::RENDERING_INTENT_UNKNOWN:
+ case Inkscape::RENDERING_INTENT_AUTO:
+ default:
+ intent = INTENT_PERCEPTUAL;
+ }
+
+ cmsHPROFILE destProf = cmsCreate_sRGBProfile();
+ cmsHTRANSFORM transf = cmsCreateTransform( prof,
+ TYPE_RGBA_8,
+ destProf,
+ TYPE_RGBA_8,
+ intent, 0 );
+ if ( transf ) {
+ guchar* currLine = px;
+ for ( int y = 0; y < imageheight; y++ ) {
+ // Since the types are the same size, we can do the transformation in-place
+ cmsDoTransform( transf, currLine, currLine, imagewidth );
+ currLine += rowstride;
+ }
+
+ cmsDeleteTransform( transf );
+ } else {
+ DEBUG_MESSAGE( lcmsSix, "in <image>'s sp_image_update. Unable to create LCMS transform." );
+ }
+
+ cmsCloseProfile( destProf );
+ } else {
+ DEBUG_MESSAGE( lcmsSeven, "in <image>'s sp_image_update. Profile type is named color. Can't transform." );
+ }
+ } else {
+ DEBUG_MESSAGE( lcmsEight, "in <image>'s sp_image_update. No profile found." );
+ }
+ }
+}
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
void SPImage::update(SPCtx *ctx, unsigned int flags) {
+
SPDocument *doc = this->document;
SPItem::update(ctx, flags);
@@ -339,170 +350,84 @@ void SPImage::update(SPCtx *ctx, unsigned int flags) {
doc->getBase());
if (pixbuf) {
-// BLIP
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- if ( this->color_profile )
- {
- // TODO: this will prevent using MIME data when exporting.
- // Integrate color correction into loading.
- pixbuf->ensurePixelFormat(Inkscape::Pixbuf::PF_GDK);
- int imagewidth = pixbuf->width();
- int imageheight = pixbuf->height();
- int rowstride = pixbuf->rowstride();;
- guchar* px = pixbuf->pixels();
-
- if ( px ) {
- DEBUG_MESSAGE( lcmsFive, "in <image>'s sp_image_update. About to call colorprofile_get_handle()" );
-
- guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN;
- cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( this->document,
- &profIntent,
- this->color_profile );
- if ( prof ) {
- cmsProfileClassSignature profileClass = cmsGetDeviceClass( prof );
- if ( profileClass != cmsSigNamedColorClass ) {
- int intent = INTENT_PERCEPTUAL;
-
- switch ( profIntent ) {
- case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC:
- intent = INTENT_RELATIVE_COLORIMETRIC;
- break;
- case Inkscape::RENDERING_INTENT_SATURATION:
- intent = INTENT_SATURATION;
- break;
- case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
- intent = INTENT_ABSOLUTE_COLORIMETRIC;
- break;
- case Inkscape::RENDERING_INTENT_PERCEPTUAL:
- case Inkscape::RENDERING_INTENT_UNKNOWN:
- case Inkscape::RENDERING_INTENT_AUTO:
- default:
- intent = INTENT_PERCEPTUAL;
- }
-
- cmsHPROFILE destProf = cmsCreate_sRGBProfile();
- cmsHTRANSFORM transf = cmsCreateTransform( prof,
- TYPE_RGBA_8,
- destProf,
- TYPE_RGBA_8,
- intent, 0 );
- if ( transf ) {
- guchar* currLine = px;
- for ( int y = 0; y < imageheight; y++ ) {
- // Since the types are the same size, we can do the transformation in-place
- cmsDoTransform( transf, currLine, currLine, imagewidth );
- currLine += rowstride;
- }
-
- cmsDeleteTransform( transf );
- } else {
- DEBUG_MESSAGE( lcmsSix, "in <image>'s sp_image_update. Unable to create LCMS transform." );
- }
-
- cmsCloseProfile( destProf );
- } else {
- DEBUG_MESSAGE( lcmsSeven, "in <image>'s sp_image_update. Profile type is named color. Can't transform." );
- }
- } else {
- DEBUG_MESSAGE( lcmsEight, "in <image>'s sp_image_update. No profile found." );
- }
- }
- }
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
+ if ( this->color_profile ) apply_profile( pixbuf );
+#endif
this->pixbuf = pixbuf;
}
}
}
+ SPItemCtx *ictx = (SPItemCtx *) ctx;
+
+ // Why continue without a pixbuf? So we can display "Missing Image" png.
+ // Eventually, we should properly support SVG image type (i.e. render it ourselves).
+
if (this->pixbuf) {
- /* fixme: We are slightly violating spec here (Lauris) */
+ if (!this->x._set) {
+ this->x.unit = SVGLength::PX;
+ this->x.computed = 0;
+ }
+
+ if (!this->y._set) {
+ this->y.unit = SVGLength::PX;
+ this->y.computed = 0;
+ }
+
if (!this->width._set) {
+ this->width.unit = SVGLength::PX;
this->width.computed = this->pixbuf->width();
}
if (!this->height._set) {
+ this->height.unit = SVGLength::PX;
this->height.computed = this->pixbuf->height();
}
}
- this->clipbox = Geom::Rect::from_xywh(
- this->x.computed, this->y.computed,
- this->width.computed, this->height.computed);
+
+ // Calculate x, y, width, height from parent/initial viewport, see sp-root.cpp
+ if (this->x.unit == SVGLength::PERCENT) {
+ this->x.computed = this->x.value * ictx->viewport.width();
+ }
+
+ if (this->y.unit == SVGLength::PERCENT) {
+ this->y.computed = this->y.value * ictx->viewport.height();
+ }
+
+ if (this->width.unit == SVGLength::PERCENT) {
+ this->width.computed = this->width.value * ictx->viewport.width();
+ }
+
+ if (this->height.unit == SVGLength::PERCENT) {
+ this->height.computed = this->height.value * ictx->viewport.height();
+ }
+
+ // Image creates a new viewport
+ ictx->viewport= Geom::Rect::from_xywh( this->x.computed, this->y.computed,
+ this->width.computed, this->height.computed);
+
+ this->clipbox = ictx->viewport;
this->ox = this->x.computed;
this->oy = this->y.computed;
if (this->pixbuf) {
- int pixwidth = this->pixbuf->width();
- int pixheight = this->pixbuf->height();
-
- this->sx = this->width.computed / pixwidth;
- this->sy = this->height.computed / pixheight;
-
- // preserveAspectRatio calculate bounds / clipping rectangle -- EAF
- if (this->aspect_align != SP_ASPECT_NONE) {
- double x, y;
-
- switch (this->aspect_align) {
- case SP_ASPECT_XMIN_YMIN:
- x = 0.0;
- y = 0.0;
- break;
- case SP_ASPECT_XMID_YMIN:
- x = 0.5;
- y = 0.0;
- break;
- case SP_ASPECT_XMAX_YMIN:
- x = 1.0;
- y = 0.0;
- break;
- case SP_ASPECT_XMIN_YMID:
- x = 0.0;
- y = 0.5;
- break;
- case SP_ASPECT_XMID_YMID:
- x = 0.5;
- y = 0.5;
- break;
- case SP_ASPECT_XMAX_YMID:
- x = 1.0;
- y = 0.5;
- break;
- case SP_ASPECT_XMIN_YMAX:
- x = 0.0;
- y = 1.0;
- break;
- case SP_ASPECT_XMID_YMAX:
- x = 0.5;
- y = 1.0;
- break;
- case SP_ASPECT_XMAX_YMAX:
- x = 1.0;
- y = 1.0;
- break;
- default:
- x = 0.0;
- y = 0.0;
- break;
- }
- if (this->aspect_clip == SP_ASPECT_SLICE) {
- double scale = std::max(this->sx, this->sy);
- this->sx = scale;
- this->sy = scale;
- } else {
- double scale = std::min(this->sx, this->sy);
- this->sx = scale;
- this->sy = scale;
- }
+ // Viewbox is either from SVG (not supported) or dimensions of pixbuf (PNG, JPG)
+ this->viewBox = Geom::Rect::from_xywh(0, 0, this->pixbuf->width(), this->pixbuf->height());
+ this->viewBox_set = true;
- double vw = pixwidth * this->sx;
- double vh = pixheight * this->sy;
- this->ox += x * (this->width.computed - vw);
- this->oy += y * (this->height.computed - vh);
- }
+ // SPItemCtx rctx =
+ get_rctx( ictx );
+
+ this->ox = c2p[4];
+ this->oy = c2p[5];
+ this->sx = c2p[0];
+ this->sy = c2p[3];
}
+
+ // TODO: eliminate ox, oy, sx, sy
sp_image_update_canvas_image ((SPImage *) this);
}
diff --git a/src/sp-image.h b/src/sp-image.h
index 3b7208487..50eb731d7 100644
--- a/src/sp-image.h
+++ b/src/sp-image.h
@@ -18,6 +18,7 @@
#include <glibmm/ustring.h>
#include "svg/svg-length.h"
#include "sp-shape.h"
+#include "viewbox.h"
#define SP_IMAGE(obj) (dynamic_cast<SPImage*>((SPObject*)obj))
#define SP_IS_IMAGE(obj) (dynamic_cast<const SPImage*>((SPObject*)obj) != NULL)
@@ -25,7 +26,7 @@
#define SP_IMAGE_HREF_MODIFIED_FLAG SP_OBJECT_USER_MODIFIED_FLAG_A
namespace Inkscape { class Pixbuf; }
-class SPImage : public SPItem {
+class SPImage : public SPItem, public SPViewBox {
public:
SPImage();
virtual ~SPImage();
@@ -39,13 +40,6 @@ public:
double sx, sy;
double ox, oy;
- // Added by EAF
- /* preserveAspectRatio */
- unsigned int aspect_align : 4;
- unsigned int aspect_clip : 1;
- //int trimx, trimy, trimwidth, trimheight;
- //double viewx, viewy, viewwidth, viewheight;
-
SPCurve *curve; // This curve is at the image's boundary for snapping
gchar *href;
@@ -69,6 +63,10 @@ public:
virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags);
virtual void snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const;
virtual Geom::Affine set_transform(Geom::Affine const &transform);
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ void apply_profile(Inkscape::Pixbuf *pixbuf);
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
};
/* Return duplicate of curve or NULL */
diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp
index 5a204e8b0..ab14e75d2 100644
--- a/src/sp-mesh-array.cpp
+++ b/src/sp-mesh-array.cpp
@@ -1925,10 +1925,10 @@ guint SPMeshNodeArray::color_pick( std::vector<guint> icorners, SPItem* item ) {
/* Find visible area */
cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height());
- Inkscape::DrawingContext ct(s, ibox.min());
+ Inkscape::DrawingContext dc(s, ibox.min());
/* Render copy and pick color */
- pick_drawing->render(ct, ibox);
+ pick_drawing->render(dc, ibox);
double R = 0, G = 0, B = 0, A = 0;
ink_cairo_surface_average_color(s, R, G, B, A);
cairo_surface_destroy(s);
diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp
index ad5449f34..425ca9efa 100644
--- a/src/sp-pattern.cpp
+++ b/src/sp-pattern.cpp
@@ -53,7 +53,7 @@ namespace {
bool patternRegistered = SPFactory::instance().registerObject("svg:pattern", createPattern);
}
-SPPattern::SPPattern() : SPPaintServer() {
+SPPattern::SPPattern() : SPPaintServer(), SPViewBox() {
this->href = NULL;
this->ref = new SPPatternReference(this);
@@ -72,8 +72,6 @@ SPPattern::SPPattern() : SPPaintServer() {
this->y.unset();
this->width.unset();
this->height.unset();
-
- this->viewBox_set = FALSE;
}
SPPattern::~SPPattern() {
@@ -90,6 +88,7 @@ void SPPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) {
this->readAttr( "width" );
this->readAttr( "height" );
this->readAttr( "viewBox" );
+ this->readAttr( "preserveAspectRatio" );
this->readAttr( "xlink:href" );
/* Register ourselves */
@@ -180,50 +179,16 @@ void SPPattern::set(unsigned int key, const gchar* value) {
this->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
- case SP_ATTR_VIEWBOX: {
- /* fixme: Think (Lauris) */
- double x, y, width, height;
- char *eptr;
-
- if (value) {
- eptr = (gchar *) value;
- x = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- y = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- width = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- height = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
+ case SP_ATTR_VIEWBOX:
+ set_viewBox( value );
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
+ break;
- if ((width > 0) && (height > 0)) {
- this->viewBox = Geom::Rect::from_xywh(x, y, width, height);
- this->viewBox_set = TRUE;
- } else {
- this->viewBox_set = FALSE;
- }
- } else {
- this->viewBox_set = FALSE;
- }
+ case SP_ATTR_PRESERVEASPECTRATIO:
+ set_preserveAspectRatio( value );
+ this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
+ break;
- this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
- break;
- }
case SP_ATTR_XLINK_HREF:
if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) {
/* Href unchanged, do nothing. */
@@ -674,25 +639,25 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
// Create drawing surface with size of pattern tile (in tile space) but with number of pixels
// based on required resolution (c).
Inkscape::DrawingSurface pattern_surface(pattern_tile, c.ceil());
- Inkscape::DrawingContext ct(pattern_surface);
+ Inkscape::DrawingContext dc(pattern_surface);
pattern_tile *= pattern_surface.drawingTransform();
Geom::IntRect one_tile = pattern_tile.roundOutwards();
// render pattern.
if (needs_opacity) {
- ct.pushGroup(); // this group is for pattern + opacity
+ dc.pushGroup(); // this group is for pattern + opacity
}
// TODO: make sure there are no leaks.
Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm!
ctx.ctm = vb2ps * pattern_surface.drawingTransform();
- ct.transform( pattern_surface.drawingTransform().inverse() );
+ dc.transform( pattern_surface.drawingTransform().inverse() );
drawing.update(Geom::IntRect::infinite(), ctx);
// Render drawing to pattern_surface via drawing context, this calls root->render
// which is really DrawingItem->render().
- drawing.render(ct, one_tile);
+ drawing.render(dc, one_tile);
for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) {
if (SP_IS_ITEM (child)) {
SP_ITEM(child)->invoke_hide(dkey);
@@ -708,8 +673,8 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
// cairo_surface_write_to_png( pattern_surface.raw(), "sp-pattern.png" );
if (needs_opacity) {
- ct.popGroupToSource(); // pop raw pattern
- ct.paint(opacity); // apply opacity
+ dc.popGroupToSource(); // pop raw pattern
+ dc.paint(opacity); // apply opacity
}
cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw());
diff --git a/src/sp-pattern.h b/src/sp-pattern.h
index 4e3657ccf..f69ba10b3 100644
--- a/src/sp-pattern.h
+++ b/src/sp-pattern.h
@@ -25,12 +25,13 @@ class SPPatternReference;
#include "svg/svg-length.h"
#include "sp-paint-server.h"
#include "uri-references.h"
+#include "viewbox.h"
#include <stddef.h>
#include <sigc++/connection.h>
-class SPPattern : public SPPaintServer {
+class SPPattern : public SPPaintServer, public SPViewBox {
public:
SPPattern();
virtual ~SPPattern();
@@ -52,9 +53,6 @@ public:
SVGLength y;
SVGLength width;
SVGLength height;
- /* VieBox */
- Geom::Rect viewBox;
- guint viewBox_set : 1;
sigc::connection modified_connection;
diff --git a/src/sp-root.cpp b/src/sp-root.cpp
index 5466649a2..bc870b116 100644
--- a/src/sp-root.cpp
+++ b/src/sp-root.cpp
@@ -42,12 +42,9 @@ SPObject *createRoot()
bool rootRegistered = SPFactory::instance().registerObject("svg:svg", createRoot);
}
-SPRoot::SPRoot() : SPGroup()
+SPRoot::SPRoot() : SPGroup(), SPViewBox()
{
- this->aspect_set = 0;
- this->aspect_align = 0;
this->onload = NULL;
- this->aspect_clip = 0;
static Inkscape::Version const zero_version(0, 0);
@@ -57,15 +54,11 @@ SPRoot::SPRoot() : SPGroup()
this->version.inkscape = zero_version;
this->original.inkscape = zero_version;
- this->x.unset();
- this->y.unset();
+ this->x.unset(SVGLength::PERCENT, 0.0, 0.0); // Ignored for root SVG element
+ this->y.unset(SVGLength::PERCENT, 0.0, 0.0);
this->width.unset(SVGLength::PERCENT, 1.0, 1.0);
this->height.unset(SVGLength::PERCENT, 1.0, 1.0);
- this->viewBox_set = false;
-
- this->c2p.setIdentity();
-
this->defs = NULL;
}
@@ -129,9 +122,9 @@ void SPRoot::set(unsigned int key, const gchar *value)
break;
case SP_ATTR_X:
- if (!this->x.readAbsolute(value)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
- this->x.unset();
+ /* Valid for non-root SVG elements; ex, em not handled correctly. */
+ if (!this->x.read(value)) {
+ this->x.unset(SVGLength::PERCENT, 0.0, 0.0);
}
/* fixme: I am almost sure these do not require viewport flag (Lauris) */
@@ -139,9 +132,9 @@ void SPRoot::set(unsigned int key, const gchar *value)
break;
case SP_ATTR_Y:
- if (!this->y.readAbsolute(value)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
- this->y.unset();
+ /* Valid for non-root SVG elements; ex, em not handled correctly. */
+ if (!this->y.read(value)) {
+ this->y.unset(SVGLength::PERCENT, 0.0, 0.0);
}
/* fixme: I am almost sure these do not require viewport flag (Lauris) */
@@ -149,153 +142,27 @@ void SPRoot::set(unsigned int key, const gchar *value)
break;
case SP_ATTR_WIDTH:
- if (!this->width.readAbsolute(value) || !(this->width.computed > 0.0)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
+ if (!this->width.read(value) || !(this->width.computed > 0.0)) {
this->width.unset(SVGLength::PERCENT, 1.0, 1.0);
}
-
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
break;
case SP_ATTR_HEIGHT:
- if (!this->height.readAbsolute(value) || !(this->height.computed > 0.0)) {
- /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */
+ if (!this->height.read(value) || !(this->height.computed > 0.0)) {
this->height.unset(SVGLength::PERCENT, 1.0, 1.0);
}
-
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
break;
case SP_ATTR_VIEWBOX:
- if (value) {
- double x, y, width, height;
- char *eptr;
-
- /* fixme: We have to take original item affine into account */
- /* fixme: Think (Lauris) */
- eptr = (gchar *) value;
- x = g_ascii_strtod(eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- y = g_ascii_strtod(eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- width = g_ascii_strtod(eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- height = g_ascii_strtod(eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- if ((width > 0) && (height > 0)) {
- /* Set viewbox */
- this->viewBox = Geom::Rect::from_xywh(x, y, width, height);
- this->viewBox_set = TRUE;
- } else {
- this->viewBox_set = FALSE;
- }
- } else {
- this->viewBox_set = FALSE;
- }
-
+ set_viewBox( value );
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
break;
case SP_ATTR_PRESERVEASPECTRATIO:
- /* Do setup before, so we can use break to escape */
- this->aspect_set = FALSE;
- this->aspect_align = SP_ASPECT_XMID_YMID;
- this->aspect_clip = SP_ASPECT_MEET;
-
+ set_preserveAspectRatio( value );
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
-
- if (value) {
- int len;
- gchar c[256];
- gchar const *p, *e;
- unsigned int align, clip;
- p = value;
-
- while (*p && *p == 32) {
- p += 1;
- }
-
- if (!*p) {
- break;
- }
-
- e = p;
-
- while (*e && *e != 32) {
- e += 1;
- }
-
- len = e - p;
-
- if (len > 8) {
- break;
- }
-
- memcpy(c, value, len);
-
- c[len] = 0;
-
- /* Now the actual part */
- if (!strcmp(c, "none")) {
- align = SP_ASPECT_NONE;
- } else if (!strcmp(c, "xMinYMin")) {
- align = SP_ASPECT_XMIN_YMIN;
- } else if (!strcmp(c, "xMidYMin")) {
- align = SP_ASPECT_XMID_YMIN;
- } else if (!strcmp(c, "xMaxYMin")) {
- align = SP_ASPECT_XMAX_YMIN;
- } else if (!strcmp(c, "xMinYMid")) {
- align = SP_ASPECT_XMIN_YMID;
- } else if (!strcmp(c, "xMidYMid")) {
- align = SP_ASPECT_XMID_YMID;
- } else if (!strcmp(c, "xMaxYMid")) {
- align = SP_ASPECT_XMAX_YMID;
- } else if (!strcmp(c, "xMinYMax")) {
- align = SP_ASPECT_XMIN_YMAX;
- } else if (!strcmp(c, "xMidYMax")) {
- align = SP_ASPECT_XMID_YMAX;
- } else if (!strcmp(c, "xMaxYMax")) {
- align = SP_ASPECT_XMAX_YMAX;
- } else {
- break;
- }
-
- clip = SP_ASPECT_MEET;
-
- while (*e && *e == 32) {
- e += 1;
- }
-
- if (*e) {
- if (!strcmp(e, "meet")) {
- clip = SP_ASPECT_MEET;
- } else if (!strcmp(e, "slice")) {
- clip = SP_ASPECT_SLICE;
- } else {
- break;
- }
- }
-
- this->aspect_set = TRUE;
- this->aspect_align = align;
- this->aspect_clip = clip;
- }
break;
case SP_ATTR_ONLOAD:
@@ -356,141 +223,75 @@ void SPRoot::update(SPCtx *ctx, guint flags)
{
SPItemCtx *ictx = (SPItemCtx *) ctx;
- /* fixme: This will be invoked too often (Lauris) */
- /* fixme: We should calculate only if parent viewport has changed (Lauris) */
- /* If position is specified as percentage, calculate actual values */
- if (this->x.unit == SVGLength::PERCENT) {
- this->x.computed = this->x.value * ictx->viewport.width();
- }
-
- if (this->y.unit == SVGLength::PERCENT) {
- this->y.computed = this->y.value * ictx->viewport.height();
- }
-
- if (this->width.unit == SVGLength::PERCENT) {
- this->width.computed = this->width.value * ictx->viewport.width();
- }
-
- if (this->height.unit == SVGLength::PERCENT) {
- this->height.computed = this->height.value * ictx->viewport.height();
- }
-
- /* Create copy of item context */
- SPItemCtx rctx = *ictx;
-
- /* Calculate child to parent transformation */
- this->c2p.setIdentity();
+ if( !this->parent ) {
- if (this->parent) {
/*
- * fixme: I am not sure whether setting x and y does or does not
- * fixme: translate the content of inner SVG.
- * fixme: Still applying translation and setting viewport to width and
- * fixme: height seems natural, as this makes the inner svg element
- * fixme: self-contained. The spec is vague here.
+ * This is the root SVG element:
+ *
+ * x, y, width, and height apply to positioning the SVG element inside a parent.
+ * For the root SVG in Inkscape there is no parent, thus special rules apply:
+ * If width, height not set, width = 100%, height = 100% (as always).
+ * If width and height are in percent, they are percent of viewBox width/height.
+ * If width, height, and viewBox are not set... pick "random" width/height.
+ * x, y are ignored.
+ * initial viewport = (0 0 width height)
*/
- this->c2p = Geom::Affine(Geom::Translate(this->x.computed, this->y.computed));
- }
-
- if (this->viewBox_set) {
- double x, y, width, height;
- /* Determine actual viewbox in viewport coordinates */
- if (this->aspect_align == SP_ASPECT_NONE) {
- x = 0.0;
- y = 0.0;
- width = this->width.computed;
- height = this->height.computed;
- } else {
- double scalex, scaley, scale;
- /* Things are getting interesting */
- scalex = this->width.computed / this->viewBox.width();
- scaley = this->height.computed / this->viewBox.height();
- scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN(scalex, scaley) : MAX(scalex, scaley);
- width = this->viewBox.width() * scale;
- height = this->viewBox.height() * scale;
-
- /* Now place viewbox to requested position */
- /* todo: Use an array lookup to find the 0.0/0.5/1.0 coefficients,
- as is done for dialogs/align.cpp. */
- switch (this->aspect_align) {
- case SP_ASPECT_XMIN_YMIN:
- x = 0.0;
- y = 0.0;
- break;
-
- case SP_ASPECT_XMID_YMIN:
- x = 0.5 * (this->width.computed - width);
- y = 0.0;
- break;
-
- case SP_ASPECT_XMAX_YMIN:
- x = 1.0 * (this->width.computed - width);
- y = 0.0;
- break;
-
- case SP_ASPECT_XMIN_YMID:
- x = 0.0;
- y = 0.5 * (this->height.computed - height);
- break;
-
- case SP_ASPECT_XMID_YMID:
- x = 0.5 * (this->width.computed - width);
- y = 0.5 * (this->height.computed - height);
- break;
+ if( this->viewBox_set ) {
- case SP_ASPECT_XMAX_YMID:
- x = 1.0 * (this->width.computed - width);
- y = 0.5 * (this->height.computed - height);
- break;
+ if( this->width._set ) {
+ // Check if this is necessary
+ if (this->width.unit == SVGLength::PERCENT) {
+ this->width.computed = this->width.value * this->viewBox.width();
+ }
+ } else {
+ this->width.set( SVGLength::PX, this->viewBox.width(), this->viewBox.width() );
+ }
- case SP_ASPECT_XMIN_YMAX:
- x = 0.0;
- y = 1.0 * (this->height.computed - height);
- break;
+ if( this->height._set ) {
+ if (this->height.unit == SVGLength::PERCENT) {
+ this->height.computed = this->height.value * this->viewBox.height();
+ }
+ } else {
+ this->height.set(SVGLength::PX, this->viewBox.height(), this->viewBox.height() );
+ }
- case SP_ASPECT_XMID_YMAX:
- x = 0.5 * (this->width.computed - width);
- y = 1.0 * (this->height.computed - height);
- break;
+ } else {
- case SP_ASPECT_XMAX_YMAX:
- x = 1.0 * (this->width.computed - width);
- y = 1.0 * (this->height.computed - height);
- break;
+ if( !this->width._set ) {
+ this->width.set( SVGLength::PX, 100, 100 ); // Random default
+ }
- default:
- x = 0.0;
- y = 0.0;
- break;
+ if( !this->height._set ) {
+ this->height.set( SVGLength::PX, 100, 100 ); // Random default
}
}
- /* Compose additional transformation from scale and position */
- Geom::Scale const viewBox_length(this->viewBox.dimensions());
- Geom::Scale const new_length(width, height);
+ // Ignore x, y values for root element
+ this->x.unset(SVGLength::PERCENT, 0.0, 0.0);
+ this->y.unset(SVGLength::PERCENT, 0.0, 0.0);
+ }
- /* Append viewbox transformation */
- /* TODO: The below looks suspicious to me (pjrm): I wonder whether the RHS
- expression should have c2p at the beginning rather than at the end. Test it. */
- this->c2p = Geom::Translate(-this->viewBox.min()) * (new_length * viewBox_length.inverse()) * Geom::Translate(x, y) * this->c2p;
+ // Calculate x, y, width, height from parent/initial viewport
+ if (this->x.unit == SVGLength::PERCENT) {
+ this->x.computed = this->x.value * ictx->viewport.width();
}
- rctx.i2doc = this->c2p * rctx.i2doc;
+ if (this->y.unit == SVGLength::PERCENT) {
+ this->y.computed = this->y.value * ictx->viewport.height();
+ }
- /* Initialize child viewport */
- if (this->viewBox_set) {
- rctx.viewport = this->viewBox;
- } else {
- /* fixme: I wonder whether this logic is correct (Lauris) */
- Geom::Point minp(0, 0);
- if (this->parent) {
- minp = Geom::Point(this->x.computed, this->y.computed);
- }
+ if (this->width.unit == SVGLength::PERCENT) {
+ this->width.computed = this->width.value * ictx->viewport.width();
+ }
- rctx.viewport = Geom::Rect::from_xywh(minp[Geom::X], minp[Geom::Y], this->width.computed, this->height.computed);
+ if (this->height.unit == SVGLength::PERCENT) {
+ this->height.computed = this->height.value * ictx->viewport.height();
}
- rctx.i2vp = Geom::identity();
+ // Calculate new viewport
+ ictx->viewport = Geom::Rect::from_xywh( this->x.computed, this->y.computed,
+ this->width.computed, this->height.computed );
+ SPItemCtx rctx = get_rctx( ictx );
/* And invoke parent method */
SPGroup::update((SPCtx *) &rctx, flags);
diff --git a/src/sp-root.h b/src/sp-root.h
index 2931391ff..1c9faed9b 100644
--- a/src/sp-root.h
+++ b/src/sp-root.h
@@ -18,6 +18,7 @@
#include "svg/svg-length.h"
#include "enums.h"
#include "sp-item-group.h"
+#include "viewbox.h"
#define SP_ROOT(obj) (dynamic_cast<SPRoot*>((SPObject*)obj))
#define SP_IS_ROOT(obj) (dynamic_cast<const SPRoot*>((SPObject*)obj) != NULL)
@@ -25,7 +26,7 @@
class SPDefs;
/** \<svg\> element */
-class SPRoot : public SPGroup {
+class SPRoot : public SPGroup, public SPViewBox {
public:
SPRoot();
virtual ~SPRoot();
@@ -40,18 +41,6 @@ public:
SVGLength width;
SVGLength height;
- /* viewBox; */
- bool viewBox_set;
- Geom::Rect viewBox;
-
- /* preserveAspectRatio */
- unsigned int aspect_set : 1;
- unsigned int aspect_align : 4;
- unsigned int aspect_clip : 1;
-
- /** Child to parent additional transform. */
- Geom::Affine c2p;
-
gchar *onload;
/**
diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp
index 8ffc2ab2c..817411a32 100644
--- a/src/sp-symbol.cpp
+++ b/src/sp-symbol.cpp
@@ -36,13 +36,7 @@ namespace {
bool symbolRegistered = SPFactory::instance().registerObject("svg:symbol", createSymbol);
}
-SPSymbol::SPSymbol() : SPGroup() {
- this->aspect_align = 0;
- this->aspect_clip = 0;
- this->aspect_set = 0;
-
- this->viewBox_set = FALSE;
- this->c2p = Geom::identity();
+SPSymbol::SPSymbol() : SPGroup(), SPViewBox() {
}
SPSymbol::~SPSymbol() {
@@ -62,134 +56,15 @@ void SPSymbol::release() {
void SPSymbol::set(unsigned int key, const gchar* value) {
switch (key) {
case SP_ATTR_VIEWBOX:
- if (value) {
- double x, y, width, height;
- char *eptr;
-
- /* fixme: We have to take original item affine into account */
- /* fixme: Think (Lauris) */
- eptr = (gchar *) value;
- x = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- y = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- width = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- height = g_ascii_strtod (eptr, &eptr);
-
- while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
- eptr++;
- }
-
- if ((width > 0) && (height > 0)) {
- /* Set viewbox */
- this->viewBox = Geom::Rect::from_xywh(x, y, width, height);
- this->viewBox_set = TRUE;
- } else {
- this->viewBox_set = FALSE;
- }
- } else {
- this->viewBox_set = FALSE;
- }
-
+ set_viewBox( value );
+ std::cout << "Symbol: ViewBox: " << viewBox << std::endl;
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
break;
case SP_ATTR_PRESERVEASPECTRATIO:
- /* Do setup before, so we can use break to escape */
- this->aspect_set = FALSE;
- this->aspect_align = SP_ASPECT_NONE;
- this->aspect_clip = SP_ASPECT_MEET;
+ set_preserveAspectRatio( value );
+ std::cout << "Symbol: Preserve aspect ratio: " << aspect_align << ", " << aspect_clip << std::endl;
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
-
- if (value) {
- int len;
- gchar c[256];
- const gchar *p, *e;
- unsigned int align, clip;
- p = value;
-
- while (*p && *p == 32) {
- p += 1;
- }
-
- if (!*p) {
- break;
- }
-
- e = p;
-
- while (*e && *e != 32) {
- e += 1;
- }
-
- len = e - p;
-
- if (len > 8) {
- break;
- }
-
- memcpy (c, value, len);
-
- c[len] = 0;
-
- /* Now the actual part */
- if (!strcmp (c, "none")) {
- align = SP_ASPECT_NONE;
- } else if (!strcmp (c, "xMinYMin")) {
- align = SP_ASPECT_XMIN_YMIN;
- } else if (!strcmp (c, "xMidYMin")) {
- align = SP_ASPECT_XMID_YMIN;
- } else if (!strcmp (c, "xMaxYMin")) {
- align = SP_ASPECT_XMAX_YMIN;
- } else if (!strcmp (c, "xMinYMid")) {
- align = SP_ASPECT_XMIN_YMID;
- } else if (!strcmp (c, "xMidYMid")) {
- align = SP_ASPECT_XMID_YMID;
- } else if (!strcmp (c, "xMaxYMid")) {
- align = SP_ASPECT_XMAX_YMID;
- } else if (!strcmp (c, "xMinYMax")) {
- align = SP_ASPECT_XMIN_YMAX;
- } else if (!strcmp (c, "xMidYMax")) {
- align = SP_ASPECT_XMID_YMAX;
- } else if (!strcmp (c, "xMaxYMax")) {
- align = SP_ASPECT_XMAX_YMAX;
- } else {
- break;
- }
-
- clip = SP_ASPECT_MEET;
-
- while (*e && *e == 32) {
- e += 1;
- }
-
- if (*e) {
- if (!strcmp (e, "meet")) {
- clip = SP_ASPECT_MEET;
- } else if (!strcmp (e, "slice")) {
- clip = SP_ASPECT_SLICE;
- } else {
- break;
- }
- }
-
- this->aspect_set = TRUE;
- this->aspect_align = align;
- this->aspect_clip = clip;
- }
break;
default:
@@ -204,105 +79,10 @@ void SPSymbol::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
void SPSymbol::update(SPCtx *ctx, guint flags) {
- SPItemCtx *ictx = (SPItemCtx *) ctx;
- SPItemCtx rctx;
-
if (this->cloned) {
- /* Cloned <symbol> is actually renderable */
-
- /* fixme: We have to set up clip here too */
-
- /* Create copy of item context */
- rctx = *ictx;
-
- /* Calculate child to parent transformation */
- /* Apply parent <use> translation (set up as vewport) */
- this->c2p = Geom::Translate(rctx.viewport.min());
-
- if (this->viewBox_set) {
- double x, y, width, height;
-
- /* Determine actual viewbox in viewport coordinates */
- if (this->aspect_align == SP_ASPECT_NONE) {
- x = 0.0;
- y = 0.0;
- width = rctx.viewport.width();
- height = rctx.viewport.height();
- } else {
- double scalex, scaley, scale;
- /* Things are getting interesting */
- scalex = rctx.viewport.width() / this->viewBox.width();
- scaley = rctx.viewport.height() / this->viewBox.height();
- scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley);
- width = this->viewBox.width() * scale;
- height = this->viewBox.height() * scale;
-
- /* Now place viewbox to requested position */
- switch (this->aspect_align) {
- case SP_ASPECT_XMIN_YMIN:
- x = 0.0;
- y = 0.0;
- break;
- case SP_ASPECT_XMID_YMIN:
- x = 0.5 * (rctx.viewport.width() - width);
- y = 0.0;
- break;
- case SP_ASPECT_XMAX_YMIN:
- x = 1.0 * (rctx.viewport.width() - width);
- y = 0.0;
- break;
- case SP_ASPECT_XMIN_YMID:
- x = 0.0;
- y = 0.5 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMID_YMID:
- x = 0.5 * (rctx.viewport.width() - width);
- y = 0.5 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMAX_YMID:
- x = 1.0 * (rctx.viewport.width() - width);
- y = 0.5 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMIN_YMAX:
- x = 0.0;
- y = 1.0 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMID_YMAX:
- x = 0.5 * (rctx.viewport.width() - width);
- y = 1.0 * (rctx.viewport.height() - height);
- break;
- case SP_ASPECT_XMAX_YMAX:
- x = 1.0 * (rctx.viewport.width() - width);
- y = 1.0 * (rctx.viewport.height() - height);
- break;
- default:
- x = 0.0;
- y = 0.0;
- break;
- }
- }
-
- /* Compose additional transformation from scale and position */
- Geom::Affine q;
- q[0] = width / this->viewBox.width();
- q[1] = 0.0;
- q[2] = 0.0;
- q[3] = height / this->viewBox.height();
- q[4] = -this->viewBox.left() * q[0] + x;
- q[5] = -this->viewBox.top() * q[3] + y;
-
- /* Append viewbox transformation */
- this->c2p = q * this->c2p;
- }
- rctx.i2doc = this->c2p * (Geom::Affine)rctx.i2doc;
-
- /* If viewBox is set initialize child viewport */
- /* Otherwise <use> has set it up already */
- if (this->viewBox_set) {
- rctx.viewport = this->viewBox;
- rctx.i2vp = Geom::identity();
- }
+ SPItemCtx *ictx = (SPItemCtx *) ctx;
+ SPItemCtx rctx = get_rctx( ictx );
// And invoke parent method
SPGroup::update((SPCtx *) &rctx, flags);
diff --git a/src/sp-symbol.h b/src/sp-symbol.h
index 7a43ed658..d1e62e923 100644
--- a/src/sp-symbol.h
+++ b/src/sp-symbol.h
@@ -25,24 +25,13 @@
#include "svg/svg-length.h"
#include "enums.h"
#include "sp-item-group.h"
+#include "viewbox.h"
-class SPSymbol : public SPGroup {
+class SPSymbol : public SPGroup, public SPViewBox {
public:
SPSymbol();
virtual ~SPSymbol();
- /* viewBox; */
- unsigned int viewBox_set : 1;
- Geom::Rect viewBox;
-
- /* preserveAspectRatio */
- unsigned int aspect_set : 1;
- unsigned int aspect_align : 4;
- unsigned int aspect_clip : 1;
-
- /* Child to parent additional transform */
- Geom::Affine c2p;
-
virtual void build(SPDocument *document, Inkscape::XML::Node *repr);
virtual void release();
virtual void set(unsigned int key, gchar const* value);
diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp
index a09489f6d..f1d6304cb 100644
--- a/src/ui/cache/svg_preview_cache.cpp
+++ b/src/ui/cache/svg_preview_cache.cpp
@@ -56,9 +56,9 @@ GdkPixbuf* render_pixbuf(Inkscape::Drawing &drawing, double scale_factor, Geom::
/* Render */
cairo_surface_t *s = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32, psize, psize);
- Inkscape::DrawingContext ct(s, area.min());
+ Inkscape::DrawingContext dc(s, area.min());
- drawing.render(ct, area, Inkscape::DrawingItem::RENDER_BYPASS_CACHE);
+ drawing.render(dc, area, Inkscape::DrawingItem::RENDER_BYPASS_CACHE);
cairo_surface_flush(s);
GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s);
diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp
index 87c399339..fb131d8da 100644
--- a/src/ui/dialog/clonetiler.cpp
+++ b/src/ui/dialog/clonetiler.cpp
@@ -2063,9 +2063,9 @@ guint32 CloneTiler::clonetiler_trace_pick(Geom::Rect box)
/* Find visible area */
cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height());
- Inkscape::DrawingContext ct(s, ibox.min());
+ Inkscape::DrawingContext dc(s, ibox.min());
/* Render */
- trace_drawing->render(ct, ibox);
+ trace_drawing->render(dc, ibox);
double R = 0, G = 0, B = 0, A = 0;
ink_cairo_surface_average_color(s, R, G, B, A);
cairo_surface_destroy(s);
diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp
index 0b72bc9f2..4e29b8856 100644
--- a/src/ui/tools/flood-tool.cpp
+++ b/src/ui/tools/flood-tool.cpp
@@ -794,7 +794,7 @@ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, boo
cairo_surface_t *s = cairo_image_surface_create_for_data(
px, CAIRO_FORMAT_ARGB32, width, height, stride);
- Inkscape::DrawingContext ct(s, Geom::Point(0,0));
+ Inkscape::DrawingContext dc(s, Geom::Point(0,0));
// cairo_translate not necessary here - surface origin is at 0,0
SPNamedView *nv = sp_desktop_namedview(desktop);
@@ -802,12 +802,12 @@ static void sp_flood_do_flood_fill(ToolBase *event_context, GdkEvent *event, boo
// bgcolor is 0xrrggbbaa, we need 0xaarrggbb
dtc = (bgcolor >> 8) | (bgcolor << 24);
- ct.setSource(bgcolor);
- ct.setOperator(CAIRO_OPERATOR_SOURCE);
- ct.paint();
- ct.setOperator(CAIRO_OPERATOR_OVER);
+ dc.setSource(bgcolor);
+ dc.setOperator(CAIRO_OPERATOR_SOURCE);
+ dc.paint();
+ dc.setOperator(CAIRO_OPERATOR_OVER);
- drawing.render(ct, final_bbox);
+ drawing.render(dc, final_bbox);
//cairo_surface_write_to_png( s, "cairo.png" );
diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp
index 91c606e8e..4ea482461 100644
--- a/src/ui/tools/spray-tool.cpp
+++ b/src/ui/tools/spray-tool.cpp
@@ -453,7 +453,7 @@ static bool sp_spray_recursive(SPDesktop *desktop,
Geom::OptRect a = parent_item->documentVisualBounds();
if (a) {
- if (i == 2) {
+ if (i == 1) {
Inkscape::XML::Node *copy1 = old_repr->duplicate(xml_doc);
parent->appendChild(copy1);
SPObject *new_obj1 = doc->getObjectByRepr(copy1);
diff --git a/src/uri-references.cpp b/src/uri-references.cpp
index abe16ec9d..ea8078b28 100644
--- a/src/uri-references.cpp
+++ b/src/uri-references.cpp
@@ -58,7 +58,7 @@ void URIReference::attach(const URI &uri) throw(BadURIException)
// The path contains references to seperate document files to load.
if(document && uri.getPath()) {
- std::string base = std::string(document->getBase());
+ std::string base = document->getBase() ? document->getBase() : "";
std::string path = uri.getFullPath(base);
if(!path.empty())
document = document->createChildDoc(path);
@@ -184,3 +184,14 @@ sp_uri_reference_resolve (SPDocument *document, const gchar *uri)
return ref;
}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/viewbox.cpp b/src/viewbox.cpp
new file mode 100644
index 000000000..2314cbf6a
--- /dev/null
+++ b/src/viewbox.cpp
@@ -0,0 +1,277 @@
+/*
+ * viewBox helper class, common code used by root, symbol, marker, pattern, image, view
+ *
+ * Authors:
+ * Lauris Kaplinski <lauris@kaplinski.com> (code extracted from symbol.cpp)
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2013 Tavmjong Bah, authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ *
+ */
+
+#include <2geom/transforms.h>
+
+#include "viewbox.h"
+#include "attributes.h"
+#include "enums.h"
+#include "sp-item.h"
+
+SPViewBox::SPViewBox() {
+
+ this->viewBox_set = FALSE;
+
+ this->aspect_set = FALSE;
+ this->aspect_align = SP_ASPECT_XMID_YMID; // Default per spec;
+ this->aspect_clip = SP_ASPECT_MEET;
+
+ this->c2p = Geom::identity();
+}
+
+SPViewBox::~SPViewBox() {
+}
+
+void SPViewBox::set_viewBox(const gchar* value) {
+
+ if (value) {
+ double x, y, width, height;
+ char *eptr;
+
+ eptr = (gchar *) value;
+ x = g_ascii_strtod (eptr, &eptr);
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
+ y = g_ascii_strtod (eptr, &eptr);
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
+ width = g_ascii_strtod (eptr, &eptr);
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
+ height = g_ascii_strtod (eptr, &eptr);
+
+ while (*eptr && ((*eptr == ',') || (*eptr == ' '))) {
+ eptr++;
+ }
+
+ if ((width > 0) && (height > 0)) {
+ /* Set viewbox */
+ this->viewBox = Geom::Rect::from_xywh(x, y, width, height);
+ this->viewBox_set = TRUE;
+ } else {
+ this->viewBox_set = FALSE;
+ }
+ } else {
+ this->viewBox_set = FALSE;
+ }
+
+ // The C++ way?
+ // std::string sv( value );
+ // std::replace( sv.begin(), sv.end(), ',', ' ');
+ // std::stringstream ss( sv );
+ // double x, y, width, height;
+ // ss >> x >> y >> width >> height;
+}
+
+void SPViewBox::set_preserveAspectRatio(const gchar* value) {
+
+ /* Do setup before, so we can use break to escape */
+ this->aspect_set = FALSE;
+ this->aspect_align = SP_ASPECT_XMID_YMID; // Default per spec
+ this->aspect_clip = SP_ASPECT_MEET;
+
+ if (value) {
+ int len;
+ gchar c[256];
+ const gchar *p, *e;
+ unsigned int align, clip;
+ p = value;
+
+ while (*p && *p == 32) {
+ p += 1;
+ }
+
+ if (!*p) {
+ return;
+ }
+
+ e = p;
+
+ while (*e && *e != 32) {
+ e += 1;
+ }
+
+ len = e - p;
+
+ if (len > 8) {
+ return;
+ }
+
+ memcpy (c, value, len);
+
+ c[len] = 0;
+
+ /* Now the actual part */
+ if (!strcmp (c, "none")) {
+ align = SP_ASPECT_NONE;
+ } else if (!strcmp (c, "xMinYMin")) {
+ align = SP_ASPECT_XMIN_YMIN;
+ } else if (!strcmp (c, "xMidYMin")) {
+ align = SP_ASPECT_XMID_YMIN;
+ } else if (!strcmp (c, "xMaxYMin")) {
+ align = SP_ASPECT_XMAX_YMIN;
+ } else if (!strcmp (c, "xMinYMid")) {
+ align = SP_ASPECT_XMIN_YMID;
+ } else if (!strcmp (c, "xMidYMid")) {
+ align = SP_ASPECT_XMID_YMID;
+ } else if (!strcmp (c, "xMaxYMid")) {
+ align = SP_ASPECT_XMAX_YMID;
+ } else if (!strcmp (c, "xMinYMax")) {
+ align = SP_ASPECT_XMIN_YMAX;
+ } else if (!strcmp (c, "xMidYMax")) {
+ align = SP_ASPECT_XMID_YMAX;
+ } else if (!strcmp (c, "xMaxYMax")) {
+ align = SP_ASPECT_XMAX_YMAX;
+ } else {
+ return;
+ }
+
+ clip = SP_ASPECT_MEET;
+
+ while (*e && *e == 32) {
+ e += 1;
+ }
+
+ if (*e) {
+ if (!strcmp (e, "meet")) {
+ clip = SP_ASPECT_MEET;
+ } else if (!strcmp (e, "slice")) {
+ clip = SP_ASPECT_SLICE;
+ } else {
+ return;
+ }
+ }
+
+ this->aspect_set = TRUE;
+ this->aspect_align = align;
+ this->aspect_clip = clip;
+ }
+}
+
+// Apply scaling from viewbox
+void SPViewBox::apply_viewbox(const Geom::Rect& in) {
+
+ /* Determine actual viewbox in viewport coordinates */
+ double x = 0.0;
+ double y = 0.0;
+ double width = in.width();
+ double height = in.height();
+ // std::cout << " width: " << width << " height: " << height << std::endl;
+
+ if (this->aspect_align != SP_ASPECT_NONE) {
+ double scalex, scaley, scale;
+ /* Things are getting interesting */
+ scalex = in.width() / this->viewBox.width();
+ scaley = in.height() / this->viewBox.height();
+ scale = (this->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley);
+ width = this->viewBox.width() * scale;
+ height = this->viewBox.height() * scale;
+
+ /* Now place viewbox to requested position */
+ switch (this->aspect_align) {
+ case SP_ASPECT_XMIN_YMIN:
+ break;
+ case SP_ASPECT_XMID_YMIN:
+ x = 0.5 * (in.width() - width);
+ break;
+ case SP_ASPECT_XMAX_YMIN:
+ x = 1.0 * (in.width() - width);
+ break;
+ case SP_ASPECT_XMIN_YMID:
+ y = 0.5 * (in.height() - height);
+ break;
+ case SP_ASPECT_XMID_YMID:
+ x = 0.5 * (in.width() - width);
+ y = 0.5 * (in.height() - height);
+ break;
+ case SP_ASPECT_XMAX_YMID:
+ x = 1.0 * (in.width() - width);
+ y = 0.5 * (in.height() - height);
+ break;
+ case SP_ASPECT_XMIN_YMAX:
+ y = 1.0 * (in.height() - height);
+ break;
+ case SP_ASPECT_XMID_YMAX:
+ x = 0.5 * (in.width() - width);
+ y = 1.0 * (in.height() - height);
+ break;
+ case SP_ASPECT_XMAX_YMAX:
+ x = 1.0 * (in.width() - width);
+ y = 1.0 * (in.height() - height);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Viewbox transform from scale and position */
+ Geom::Affine q;
+ q[0] = width / this->viewBox.width();
+ q[1] = 0.0;
+ q[2] = 0.0;
+ q[3] = height / this->viewBox.height();
+ q[4] = -this->viewBox.left() * q[0] + x;
+ q[5] = -this->viewBox.top() * q[3] + y;
+
+ // std::cout << " q\n" << q << std::endl;
+
+ /* Append viewbox transformation */
+ this->c2p = q * this->c2p;
+}
+
+SPItemCtx SPViewBox::get_rctx(const SPItemCtx* ictx) {
+
+ /* Create copy of item context */
+ SPItemCtx rctx = *ictx;
+
+ /* Calculate child to parent transformation */
+ /* Apply parent translation (set up as viewport) */
+ this->c2p = Geom::Translate(rctx.viewport.min());
+
+ if (this->viewBox_set) {
+ // Adjusts c2p for viewbox
+ apply_viewbox( rctx.viewport );
+ }
+
+ rctx.i2doc = this->c2p * rctx.i2doc;
+
+ /* If viewBox is set initialize child viewport */
+ /* Otherwise it is already correct */
+ if (this->viewBox_set) {
+ rctx.viewport = this->viewBox;
+ rctx.i2vp = Geom::identity();
+ }
+
+ return rctx;
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-basic-offset:2
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2:fileencoding=utf-8:textwidth=99 :
diff --git a/src/viewbox.h b/src/viewbox.h
new file mode 100644
index 000000000..24356ed17
--- /dev/null
+++ b/src/viewbox.h
@@ -0,0 +1,66 @@
+#ifndef __SP_VIEWBOX_H__
+#define __SP_VIEWBOX_H__
+
+/*
+ * viewBox helper class, common code used by root, symbol, marker, pattern, image, view
+ *
+ * Authors:
+ * Lauris Kaplinski <lauris@kaplinski.com> (code extracted from sp-symbol.h)
+ * Tavmjong Bah
+ *
+ * Copyright (C) 2013 Tavmjong Bah, authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ *
+ */
+
+#include <2geom/rect.h>
+#include <glib.h>
+
+namespace Geom {
+class Rect;
+}
+class SPItemCtx;
+
+class SPViewBox {
+
+ public:
+
+ SPViewBox();
+ ~SPViewBox();
+
+ /* viewBox; */
+ unsigned int viewBox_set : 1;
+ Geom::Rect viewBox; // Could use optrect
+
+ /* preserveAspectRatio */
+ unsigned int aspect_set : 1;
+ unsigned int aspect_align : 4;
+ unsigned int aspect_clip : 1;
+
+ /* Child to parent additional transform */
+ Geom::Affine c2p;
+
+ void set_viewBox(const gchar* value);
+ void set_preserveAspectRatio(const gchar* value);
+
+ /* Adjusts c2p for viewbox */
+ void apply_viewbox(const Geom::Rect& in);
+
+ SPItemCtx get_rctx( const SPItemCtx* ictx);
+
+};
+
+#endif
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-basic-offset:2
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2:fileencoding=utf-8:textwidth=99 :
diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp
index a059c100c..a96f47124 100644
--- a/src/widgets/icon.cpp
+++ b/src/widgets/icon.cpp
@@ -1191,9 +1191,9 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::Drawing &drawing,
/* Render */
cairo_surface_t *s = cairo_image_surface_create_for_data(px,
CAIRO_FORMAT_ARGB32, psize, psize, stride);
- Inkscape::DrawingContext ct(s, ua.min());
+ Inkscape::DrawingContext dc(s, ua.min());
- drawing.render(ct, ua);
+ drawing.render(dc, ua);
cairo_surface_destroy(s);
// convert to GdkPixbuf format