From 328fad57dbfb65e3bd31062021d5cc3081e68515 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 22 Jul 2011 04:09:27 +0200 Subject: Replace direct use of Cairo contexts and surfaces in the rendering tree with wrappers which keep some extra information about the surface, amd NRRect and NRRectL use with Geom::Rect and Geom::IntRect. Should simplify implementing filter primitive subregions. (bzr r10347.1.17) --- src/widgets/icon.cpp | 66 +++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 95cb23a22..bb2029bcf 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -31,6 +31,7 @@ #include "document.h" #include "sp-item.h" #include "display/cairo-utils.h" +#include "display/drawing-context.h" #include "display/nr-arena.h" #include "display/nr-arena-item.h" #include "io/sys.h" @@ -1073,6 +1074,19 @@ GdkPixbuf *IconImpl::loadPixmap(gchar const *name, unsigned /*lsize*/, unsigned return pb; } +static Geom::IntRect round_rect(Geom::Rect const &r) +{ + using Geom::X; + using Geom::Y; + Geom::IntPoint a, b; + a[X] = round(r.left()); + a[Y] = round(r.top()); + b[X] = round(r.right()); + b[Y] = round(r.bottom()); + Geom::IntRect ret(a, b); + return ret; +} + // takes doc, root, icon, and icon name to produce pixels extern "C" guchar * sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, @@ -1102,23 +1116,20 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, double sf = 1.0; nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); gc.transform.setIdentity(); - nr_arena_item_invoke_update( root, NULL, &gc, + nr_arena_item_invoke_update( root, Geom::IntRect::infinite(), &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE ); /* Item integer bbox in points */ - NRRectL ibox; - ibox.x0 = (int) floor(sf * dbox->min()[Geom::X] + 0.5); - ibox.y0 = (int) floor(sf * dbox->min()[Geom::Y] + 0.5); - ibox.x1 = (int) floor(sf * dbox->max()[Geom::X] + 0.5); - ibox.y1 = (int) floor(sf * dbox->max()[Geom::Y] + 0.5); + // NOTE: previously, each rect coordinate was rounded using floor(c + 0.5) + Geom::IntRect ibox = round_rect(*dbox); if ( dump ) { - g_message( " box --'%s' (%f,%f)-(%f,%f)", name, (double)ibox.x0, (double)ibox.y0, (double)ibox.x1, (double)ibox.y1 ); + g_message( " box --'%s' (%f,%f)-(%f,%f)", name, (double)ibox.left(), (double)ibox.top(), (double)ibox.right(), (double)ibox.bottom() ); } /* Find button visible area */ - int width = ibox.x1 - ibox.x0; - int height = ibox.y1 - ibox.y0; + int width = ibox.width(); + int height = ibox.height(); if ( dump ) { g_message( " vis --'%s' (%d,%d)", name, width, height ); @@ -1134,49 +1145,38 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); gc.transform.setIdentity(); - nr_arena_item_invoke_update( root, NULL, &gc, + nr_arena_item_invoke_update( root, Geom::IntRect::infinite(), &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE ); - /* Item integer bbox in points */ - ibox.x0 = (int) floor(sf * dbox->min()[Geom::X] + 0.5); - ibox.y0 = (int) floor(sf * dbox->min()[Geom::Y] + 0.5); - ibox.x1 = (int) floor(sf * dbox->max()[Geom::X] + 0.5); - ibox.y1 = (int) floor(sf * dbox->max()[Geom::Y] + 0.5); + ibox = round_rect(*dbox * Geom::Scale(sf)); if ( dump ) { - g_message( " box2 --'%s' (%f,%f)-(%f,%f)", name, (double)ibox.x0, (double)ibox.y0, (double)ibox.x1, (double)ibox.y1 ); + g_message( " box2 --'%s' (%f,%f)-(%f,%f)", name, (double)ibox.left(), (double)ibox.top(), (double)ibox.right(), (double)ibox.bottom() ); } /* Find button visible area */ - width = ibox.x1 - ibox.x0; - height = ibox.y1 - ibox.y0; + width = ibox.width(); + height = ibox.height(); if ( dump ) { g_message( " vis2 --'%s' (%d,%d)", name, width, height ); } } } + Geom::IntPoint pdim(psize, psize); int dx, dy; //dx = (psize - width) / 2; //dy = (psize - height) / 2; dx=dy=psize; dx=(dx-width)/2; // watch out for psize, since 'unsigned'-'signed' can cause problems if the result is negative dy=(dy-height)/2; - NRRectL area; - area.x0 = ibox.x0 - dx; - area.y0 = ibox.y0 - dy; - area.x1 = area.x0 + psize; - area.y1 = area.y0 + psize; + Geom::IntRect area = Geom::IntRect::from_xywh(ibox.min() - Geom::IntPoint(dx,dy), pdim); /* Actual renderable area */ - NRRectL ua; - ua.x0 = MAX(ibox.x0, area.x0); - ua.y0 = MAX(ibox.y0, area.y0); - ua.x1 = MIN(ibox.x1, area.x1); - ua.y1 = MIN(ibox.y1, area.y1); + Geom::IntRect ua = *Geom::intersect(ibox, area); if ( dump ) { - g_message( " area --'%s' (%f,%f)-(%f,%f)", name, (double)area.x0, (double)area.y0, (double)area.x1, (double)area.y1 ); - g_message( " ua --'%s' (%f,%f)-(%f,%f)", name, (double)ua.x0, (double)ua.y0, (double)ua.x1, (double)ua.y1 ); + g_message( " area --'%s' (%f,%f)-(%f,%f)", name, (double)area.left(), (double)area.top(), (double)area.right(), (double)area.bottom() ); + g_message( " ua --'%s' (%f,%f)-(%f,%f)", name, (double)ua.left(), (double)ua.top(), (double)ua.right(), (double)ua.bottom() ); } stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, psize); @@ -1188,12 +1188,10 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, /* Render */ cairo_surface_t *s = cairo_image_surface_create_for_data(px, CAIRO_FORMAT_ARGB32, psize, psize, stride); - cairo_t *ct = cairo_create(s); - cairo_translate(ct, -ua.x0, -ua.y0); + Inkscape::DrawingContext ct(s, ua.min()); - nr_arena_item_invoke_render(ct, root, &ua, NULL, + nr_arena_item_invoke_render(ct, root, ua, NR_ARENA_ITEM_RENDER_NO_CACHE ); - cairo_destroy(ct); cairo_surface_destroy(s); // convert to GdkPixbuf format -- cgit v1.2.3 From 4dd33aa4d5c57706c7f64f63391174954160a308 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 6 Aug 2011 14:18:32 +0200 Subject: Rewrite NRArenaItem hierarchy into C++ (bzr r10347.1.21) --- src/widgets/desktop-widget.cpp | 4 ++-- src/widgets/icon.cpp | 28 ++++++++++------------------ src/widgets/stroke-style.cpp | 7 ++++--- 3 files changed, 16 insertions(+), 23 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 7958a9d07..af329f3fc 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -641,10 +641,10 @@ SPDesktopWidget::updateTitle(gchar const* uri) gchar const *colormodename = ""; gchar const *colormodenamecomma = ""; - if (this->desktop->getColorMode() == Inkscape::COLORRENDERMODE_GRAYSCALE) { + if (this->desktop->getColorMode() == Inkscape::COLORMODE_GRAYSCALE) { colormodename = grayscalename; colormodenamecomma = grayscalenamecomma; - } else if (this->desktop->getColorMode() == Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW) { + } else if (this->desktop->getColorMode() == Inkscape::COLORMODE_PRINT_COLORS_PREVIEW) { colormodename = printcolorsname; colormodenamecomma = printcolorsnamecomma; } diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index c6823e2d8..fea825444 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -32,8 +32,8 @@ #include "sp-item.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" +#include "display/drawing-item.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "io/sys.h" #include "sp-root.h" @@ -1090,7 +1090,7 @@ static Geom::IntRect round_rect(Geom::Rect const &r) // takes doc, root, icon, and icon name to produce pixels extern "C" guchar * -sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, +sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, gchar const *name, unsigned psize, unsigned &stride) { @@ -1113,14 +1113,10 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, /* This is in document coordinates, i.e. pixels */ if ( dbox ) { - NRGC gc(NULL); /* Update to renderable state */ double sf = 1.0; - nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); - gc.transform.setIdentity(); - nr_arena_item_invoke_update( root, Geom::IntRect::infinite(), &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE ); + root->setTransform(Geom::Scale(sf)); + root->update(); /* Item integer bbox in points */ // NOTE: previously, each rect coordinate was rounded using floor(c + 0.5) Geom::IntRect ibox = round_rect(*dbox); @@ -1145,11 +1141,8 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, } sf = (double)psize / (double)block; - nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); - gc.transform.setIdentity(); - nr_arena_item_invoke_update( root, Geom::IntRect::infinite(), &gc, - NR_ARENA_ITEM_STATE_ALL, - NR_ARENA_ITEM_STATE_NONE ); + root->setTransform(Geom::Scale(sf)); + root->update(); ibox = round_rect(*dbox * Geom::Scale(sf)); if ( dump ) { @@ -1192,8 +1185,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, CAIRO_FORMAT_ARGB32, psize, psize, stride); Inkscape::DrawingContext ct(s, ua.min()); - nr_arena_item_invoke_render(ct, root, ua, - NR_ARENA_ITEM_RENDER_NO_CACHE ); + root->render(ct, ua, Inkscape::DrawingItem::RENDER_BYPASS_CACHE); cairo_surface_destroy(s); // convert to GdkPixbuf format @@ -1214,9 +1206,9 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, class SVGDocCache { public: - SVGDocCache( SPDocument *doc, NRArenaItem *root ) : doc(doc), root(root) {} + SVGDocCache( SPDocument *doc, Inkscape::DrawingItem *root ) : doc(doc), root(root) {} SPDocument *doc; - NRArenaItem *root; + Inkscape::DrawingItem *root; }; static std::map doc_cache; @@ -1294,7 +1286,7 @@ guchar *IconImpl::load_svg_pixels(std::list const &names, // fixme: Memory manage root if needed (Lauris) // This needs to be fixed indeed; this leads to a memory leak of a few megabytes these days // because shapes are being rendered which are not being freed - NRArenaItem *root = doc->getRoot()->invoke_show( arena, visionkey, SP_ITEM_SHOW_DISPLAY ); + Inkscape::DrawingItem *root = doc->getRoot()->invoke_show( arena, visionkey, SP_ITEM_SHOW_DISPLAY ); // store into the cache info = new SVGDocCache(doc, root); diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 8b5582163..4f6466ce8 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -28,8 +28,8 @@ #include "desktop-style.h" #include "dialogs/dialog-events.h" #include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_* +#include "display/display-forward.h" #include "display/nr-arena.h" -#include "display/nr-arena-item.h" #include "document-private.h" #include "gradient-chemistry.h" #include "helper/stock-items.h" @@ -153,7 +153,8 @@ sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon, static Gtk::Image * sp_marker_prev_new(unsigned psize, gchar const *mname, SPDocument *source, SPDocument *sandbox, - gchar const *menu_id, NRArena const * /*arena*/, unsigned /*visionkey*/, NRArenaItem *root) + gchar const *menu_id, NRArena const * /*arena*/, unsigned /*visionkey*/, + Inkscape::DrawingItem *root) { // Retrieve the marker named 'mname' from the source SVG document SPObject const *marker = source->getObjectById(mname); @@ -250,7 +251,7 @@ sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPD // Do this here, outside of loop, to speed up preview generation: NRArena const *arena = NRArena::create(); unsigned const visionkey = SPItem::display_key_new(1); - NRArenaItem *root = sandbox->getRoot()->invoke_show((NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY); + Inkscape::DrawingItem *root = sandbox->getRoot()->invoke_show((NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY); for (; marker_list != NULL; marker_list = marker_list->next) { Inkscape::XML::Node *repr = reinterpret_cast(marker_list->data)->getRepr(); -- cgit v1.2.3 From 75976ea07dba9b97186667524d0a76603de416af Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 7 Aug 2011 12:53:12 +0200 Subject: Rewrite NRArena -> Inkscape::Drawing. Call render and update methods on the Drawing rather than on the root DrawingItem. (bzr r10347.1.25) --- src/widgets/desktop-widget.cpp | 1 - src/widgets/icon.cpp | 49 +++++++++++++++++++++--------------------- src/widgets/stroke-style.cpp | 14 ++++++------ 3 files changed, 30 insertions(+), 34 deletions(-) (limited to 'src/widgets') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index af329f3fc..08f0eadfb 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -36,7 +36,6 @@ #include "desktop-widget.h" #include "display/sp-canvas.h" #include "display/canvas-arena.h" -#include "display/nr-arena.h" #include "document.h" #include "ege-color-prof-tracker.h" #include "ege-select-one-action.h" diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index fea825444..a57b56b5c 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -33,7 +33,7 @@ #include "display/cairo-utils.h" #include "display/drawing-context.h" #include "display/drawing-item.h" -#include "display/nr-arena.h" +#include "display/drawing.h" #include "io/sys.h" #include "sp-root.h" @@ -1088,9 +1088,9 @@ static Geom::IntRect round_rect(Geom::Rect const &r) return ret; } -// takes doc, root, icon, and icon name to produce pixels +// takes doc, drawing, icon, and icon name to produce pixels extern "C" guchar * -sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, +sp_icon_doc_icon( SPDocument *doc, Inkscape::Drawing &drawing, gchar const *name, unsigned psize, unsigned &stride) { @@ -1115,8 +1115,8 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, if ( dbox ) { /* Update to renderable state */ double sf = 1.0; - root->setTransform(Geom::Scale(sf)); - root->update(); + drawing.root()->setTransform(Geom::Scale(sf)); + drawing.update(); /* Item integer bbox in points */ // NOTE: previously, each rect coordinate was rounded using floor(c + 0.5) Geom::IntRect ibox = round_rect(*dbox); @@ -1141,8 +1141,8 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, } sf = (double)psize / (double)block; - root->setTransform(Geom::Scale(sf)); - root->update(); + drawing.root()->setTransform(Geom::Scale(sf)); + drawing.update(); ibox = round_rect(*dbox * Geom::Scale(sf)); if ( dump ) { @@ -1185,7 +1185,7 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, CAIRO_FORMAT_ARGB32, psize, psize, stride); Inkscape::DrawingContext ct(s, ua.min()); - root->render(ct, ua, Inkscape::DrawingItem::RENDER_BYPASS_CACHE); + drawing.render(ct, ua); cairo_surface_destroy(s); // convert to GdkPixbuf format @@ -1206,9 +1206,21 @@ sp_icon_doc_icon( SPDocument *doc, Inkscape::DrawingItem *root, class SVGDocCache { public: - SVGDocCache( SPDocument *doc, Inkscape::DrawingItem *root ) : doc(doc), root(root) {} + SVGDocCache( SPDocument *doc ) + : doc(doc) + , visionkey(SPItem::display_key_new(1)) + { + doc->doRef(); + doc->ensureUpToDate(); + drawing.setRoot(doc->getRoot()->invoke_show(drawing, visionkey, SP_ITEM_SHOW_DISPLAY )); + } + ~SVGDocCache() { + doc->getRoot()->invoke_hide(visionkey); + doc->doUnref(); + } SPDocument *doc; - Inkscape::DrawingItem *root; + Inkscape::Drawing drawing; + unsigned visionkey; }; static std::map doc_cache; @@ -1275,27 +1287,14 @@ guchar *IconImpl::load_svg_pixels(std::list const &names, if ( dump ) { g_message("Loaded icon file %s", doc_filename); } - // prep the document - doc->ensureUpToDate(); - - // Create new arena - NRArena *arena = NRArena::create(); - - // Create ArenaItem and set transform - unsigned visionkey = SPItem::display_key_new(1); - // fixme: Memory manage root if needed (Lauris) - // This needs to be fixed indeed; this leads to a memory leak of a few megabytes these days - // because shapes are being rendered which are not being freed - Inkscape::DrawingItem *root = doc->getRoot()->invoke_show( arena, visionkey, SP_ITEM_SHOW_DISPLAY ); - // store into the cache - info = new SVGDocCache(doc, root); + info = new SVGDocCache(doc); doc_cache[key] = info; } } if (info) { for (std::list::const_iterator it = names.begin(); !px && (it != names.end()); ++it ) { - px = sp_icon_doc_icon( info->doc, info->root, it->c_str(), psize, stride ); + px = sp_icon_doc_icon( info->doc, info->drawing, it->c_str(), psize, stride ); } } } diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 4f6466ce8..8d9b9b429 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -29,7 +29,7 @@ #include "dialogs/dialog-events.h" #include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_* #include "display/display-forward.h" -#include "display/nr-arena.h" +#include "display/drawing.h" #include "document-private.h" #include "gradient-chemistry.h" #include "helper/stock-items.h" @@ -153,8 +153,7 @@ sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon, static Gtk::Image * sp_marker_prev_new(unsigned psize, gchar const *mname, SPDocument *source, SPDocument *sandbox, - gchar const *menu_id, NRArena const * /*arena*/, unsigned /*visionkey*/, - Inkscape::DrawingItem *root) + gchar const *menu_id, Inkscape::Drawing &drawing, unsigned /*visionkey*/) { // Retrieve the marker named 'mname' from the source SVG document SPObject const *marker = source->getObjectById(mname); @@ -209,7 +208,7 @@ sp_marker_prev_new(unsigned psize, gchar const *mname, Glib::RefPtr pixbuf = Glib::wrap(svg_preview_cache.get_preview_from_cache(key)); if (!pixbuf) { - pixbuf = Glib::wrap(render_pixbuf(root, sf, *dbox, psize)); + pixbuf = Glib::wrap(render_pixbuf(drawing, sf, *dbox, psize)); svg_preview_cache.set_preview_in_cache(key, pixbuf->gobj()); } @@ -249,9 +248,9 @@ static void sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPDocument *sandbox, gchar const *menu_id) { // Do this here, outside of loop, to speed up preview generation: - NRArena const *arena = NRArena::create(); + Inkscape::Drawing drawing; unsigned const visionkey = SPItem::display_key_new(1); - Inkscape::DrawingItem *root = sandbox->getRoot()->invoke_show((NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY); + drawing.setRoot(sandbox->getRoot()->invoke_show(drawing, visionkey, SP_ITEM_SHOW_DISPLAY)); for (; marker_list != NULL; marker_list = marker_list->next) { Inkscape::XML::Node *repr = reinterpret_cast(marker_list->data)->getRepr(); @@ -272,7 +271,7 @@ sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPD // generate preview - Gtk::Image *prv = sp_marker_prev_new (22, markid, source, sandbox, menu_id, arena, visionkey, root); + Gtk::Image *prv = sp_marker_prev_new (22, markid, source, sandbox, menu_id, drawing, visionkey); prv->show(); hb->pack_start(*prv, false, false, 6); @@ -290,7 +289,6 @@ sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPD } sandbox->getRoot()->invoke_hide(visionkey); - nr_object_unref((NRObject *) arena); } /** -- cgit v1.2.3