diff options
| author | Felipe Corr??a da Silva Sanches <juca@members.fsf.org> | 2008-02-25 05:09:02 +0000 |
|---|---|---|
| committer | jucablues <jucablues@users.sourceforge.net> | 2008-02-25 05:09:02 +0000 |
| commit | b9b73b9df4d0d728b5f95b18b35eb998c97ee284 (patch) | |
| tree | 05cba866bbe8c5976b5cca5a11c2cd938e1feeb5 /src/display | |
| parent | Whitespace cleanup (diff) | |
| download | inkscape-b9b73b9df4d0d728b5f95b18b35eb998c97ee284.tar.gz inkscape-b9b73b9df4d0d728b5f95b18b35eb998c97ee284.zip | |
svg element referenced by id part of feImage filter rendering.
This commit introduces some known bugs. I will fill a bug report about it, so that we don't forget it.
Nominally they are:
* seems to leak memory. I haven't found out how. Needs review.
* it works when you create and use the filter, but it crashes when trying to open a file that already contains a
filter using feImage referencing an svgelement.
(bzr r4844)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/nr-filter-image.cpp | 78 | ||||
| -rw-r--r-- | src/display/nr-filter-image.h | 4 |
2 files changed, 78 insertions, 4 deletions
diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp index 78e5ef8ec..42b78fa16 100644 --- a/src/display/nr-filter-image.cpp +++ b/src/display/nr-filter-image.cpp @@ -10,10 +10,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ #include "document.h" +#include "sp-item.h" +#include "display/nr-arena.h" #include "display/nr-arena-item.h" #include "display/nr-filter.h" #include "display/nr-filter-image.h" #include "display/nr-filter-units.h" +#include "libnr/nr-matrix.h" +#include "libnr/nr-rect-l.h" namespace NR { @@ -36,6 +40,64 @@ FilterImage::~FilterImage() int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { if (!feImageHref) return 0; + NRPixBlock* pb; + bool free_pb_on_exit = false; + + if(from_element){ + if (!SVGElem) return 0; + + // prep the document + sp_document_ensure_up_to_date(document); + NRArena* arena = NRArena::create(); + unsigned const key = sp_item_display_key_new(1); + NRArenaItem* ai = sp_item_invoke_show(SVGElem, arena, key, SP_ITEM_SHOW_DISPLAY); + if (!ai) { + g_warning("feImage renderer: error creating NRArenaItem for SVG Element"); + g_free(arena); + return 0; + } + pb = new NRPixBlock; + free_pb_on_exit = true; + + Matrix identity(1.0, 0.0, + 0.0, 1.0, + 0.0, 0.0); + NR::Maybe<NR::Rect> area = SVGElem->getBounds(identity); + + NRRectL rect; + rect.x0=area->min()[NR::X]; + rect.x1=area->max()[NR::X]; + rect.y0=area->min()[NR::Y]; + rect.y1=area->max()[NR::Y]; + + width = (int)(rect.x1-rect.x0); + height = (int)(rect.y1-rect.y0); + + if (image_pixbuf) g_free(image_pixbuf); + image_pixbuf = g_new(unsigned char, 4 * width * height); + memset(image_pixbuf, 0x00, 4 * width * height); + + NRGC gc(NULL); + /* Update to renderable state */ + double sf = 1.0; + NRMatrix t; + nr_matrix_set_scale(&t, sf, sf); + nr_arena_item_set_transform(ai, &t); + nr_matrix_set_identity(&gc.transform); + nr_arena_item_invoke_update( ai, NULL, &gc, + NR_ARENA_ITEM_STATE_ALL, + NR_ARENA_ITEM_STATE_NONE ); + nr_pixblock_setup_extern(pb, NR_PIXBLOCK_MODE_R8G8B8A8N, + (int)rect.x0, (int)rect.y0, (int)rect.x1, (int)rect.y1, + image_pixbuf, 4 * width, FALSE, FALSE ); + + nr_arena_item_invoke_render(NULL, ai, &rect, pb, NR_ARENA_ITEM_RENDER_NO_CACHE); + + nr_arena_item_unref(ai); + nr_object_unref((NRObject *) arena); + } + + if (!image_pixbuf){ try { gchar *fullname = feImageHref; @@ -116,13 +178,21 @@ int FilterImage::render(FilterSlot &slot, FilterUnits const &units) { coordx = ( indexX >= 0 ? int( indexX ) : -1 ); coordy = ( indexY >= 0 ? int( indexY ) : -1 ); if (coordx >= 0 && coordx < width && coordy >= 0 && coordy < height){ - out_data[4*((x - x0)+w*(y - y0))] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy]; //Red - out_data[4*((x - x0)+w*(y - y0)) + 1] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy + 1]; //Green - out_data[4*((x - x0)+w*(y - y0)) + 2] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy + 2]; //Blue - out_data[4*((x - x0)+w*(y - y0)) + 3] = 255; //Alpha + if (from_element){ + out_data[4*((x - x0)+w*(y - y0))] = (unsigned char) image_pixbuf[4*(coordx + width*coordy)]; //Red + out_data[4*((x - x0)+w*(y - y0)) + 1] = (unsigned char) image_pixbuf[4*(coordx + width*coordy) + 1]; //Green + out_data[4*((x - x0)+w*(y - y0)) + 2] = (unsigned char) image_pixbuf[4*(coordx + width*coordy) + 2]; //Blue + out_data[4*((x - x0)+w*(y - y0)) + 3] = (unsigned char) image_pixbuf[4*(coordx + width*coordy) + 3]; //Alpha + } else { + out_data[4*((x - x0)+w*(y - y0))] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy]; //Red + out_data[4*((x - x0)+w*(y - y0)) + 1] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy + 1]; //Green + out_data[4*((x - x0)+w*(y - y0)) + 2] = (unsigned char) image_pixbuf[3*coordx + rowstride*coordy + 2]; //Blue + out_data[4*((x - x0)+w*(y - y0)) + 3] = 255; //Alpha + } } } } + if (free_pb_on_exit) nr_pixblock_release(pb); out->empty = FALSE; slot.set(_output, out); diff --git a/src/display/nr-filter-image.h b/src/display/nr-filter-image.h index afa9f798c..42e7f089a 100644 --- a/src/display/nr-filter-image.h +++ b/src/display/nr-filter-image.h @@ -16,6 +16,7 @@ #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" #include <gtkmm.h> +#include "sp-item.h" namespace NR { @@ -30,6 +31,9 @@ public: void set_document( SPDocument *document ); void set_href(const gchar *href); void set_region(SVGLength x, SVGLength y, SVGLength width, SVGLength height); + bool from_element; + SPItem* SVGElem; + private: SPDocument *document; gchar *feImageHref; |
