summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 74ed5bd)
raw | patch | inline | side by side (parent: 74ed5bd)
| author | jucablues <jucablues@users.sourceforge.net> | |
| Mon, 25 Feb 2008 05:09:02 +0000 (05:09 +0000) | ||
| committer | jucablues <jucablues@users.sourceforge.net> | |
| Mon, 25 Feb 2008 05:09:02 +0000 (05:09 +0000) |
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.
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.
index 78e5ef8ecf7741e4729b4ad342875f0f4127166f..42b78fa16ad2ec4e244d59b973a17cc14d933b89 100644 (file)
* 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 {
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;
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);
index afa9f798c87b3d8b5a9d92e9a8cb72ffffad8a83..42e7f089aca77d25fc84117595b969d002f109a7 100644 (file)
#include "display/nr-filter-slot.h"
#include "display/nr-filter-units.h"
#include <gtkmm.h>
+#include "sp-item.h"
namespace NR {
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;
diff --git a/src/sp-feimage.cpp b/src/sp-feimage.cpp
index 271baa5914a9a978a33b4307541aa013812e5050..d72435f2c5415cc77b1895fabcd2384504cd73da 100644 (file)
--- a/src/sp-feimage.cpp
+++ b/src/sp-feimage.cpp
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-
+#include "uri.h"
+#include "uri-references.h"
#include "attributes.h"
#include "svg/svg.h"
#include "sp-feimage.h"
{
SPFeImage *feImage = SP_FEIMAGE(object);
(void)feImage;
-
+ Inkscape::URI* SVGElem_uri;
+ Inkscape::URIReference* SVGElemRef;
switch(key) {
/*DEAL WITH SETTING ATTRIBUTES HERE*/
case SP_ATTR_XLINK_HREF:
if (feImage->href) g_free(feImage->href);
feImage->href = (value) ? g_strdup (value) : NULL;
- object->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
+ if (!feImage->href) return;
+ try{
+ SVGElem_uri = new Inkscape::URI(feImage->href);
+ SVGElemRef = new Inkscape::URIReference(feImage->document);
+ feImage->from_element = true;
+ SVGElemRef->attach(*SVGElem_uri);
+ feImage->SVGElem = SP_ITEM(SVGElemRef->getObject());
+
+ g_free(SVGElem_uri);
+ g_free(SVGElemRef);
+ //TODO: maybe keeping SVGElemRef we can observe changes to the
+ // referenced object and trigger updates of the filtered object
+ object->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ }
+ catch(const Inkscape::UnsupportedURIException & e)
+ {
+ feImage->from_element = false;
+ g_warning("caught Inkscape::UnsupportedURIException in sp_feImage_set");
+ break;
+ }
+
+
case SP_ATTR_X:
feImage->x.readOrUnset(value);
object->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -215,6 +238,9 @@ static void sp_feImage_build_renderer(SPFilterPrimitive *primitive, NR::Filter *
g_assert(nr_image != NULL);
sp_filter_primitive_renderer_common(primitive, nr_primitive);
+
+ nr_image->from_element = sp_image->from_element;
+ nr_image->SVGElem = sp_image->SVGElem;
nr_image->set_region(sp_image->x, sp_image->y, sp_image->width, sp_image->height);
nr_image->set_href(sp_image->href);
nr_image->set_document(sp_image->document);
diff --git a/src/sp-feimage.h b/src/sp-feimage.h
index cf80a31666fd15ef60fde8f9703004ec60da0b80..d66a4fb770594608fc6241213512df86a077fd42 100644 (file)
--- a/src/sp-feimage.h
+++ b/src/sp-feimage.h
#include "sp-filter.h"
#include "sp-feimage-fns.h"
#include "svg/svg-length.h"
+#include "sp-item.h"
/* FeImage base class */
class SPFeImageClass;
gchar *href;
SVGLength x, y, height, width;
SPDocument *document;
+ bool from_element;
+ SPItem* SVGElem;
};
struct SPFeImageClass {
index 3a5c285208dcf024d0c56d538869c3d4adc38f88..6e9eeedb6a934232fe37d3f5fb4d36cbbda04e7f 100644 (file)
{
pack_start(_entry, false, false);
pack_start(_fromFile, false, false);
- //pack_start(_fromSVGElement, false, false);
+ pack_start(_fromSVGElement, false, false);
_fromFile.set_label(_("Image File"));
_fromFile.signal_clicked().connect(sigc::mem_fun(*this, &FileOrElementChooser::select_file));