index ee566d2dceb90a8b0a749c857ddd017a36090d95..e187c331f43c00c386e8246871d51cfcaa335f0d 100644 (file)
*/
#include <libnr/nr-compose-transform.h>
+#include <libnr/nr-blit.h>
#include "../prefs-utils.h"
#include "nr-arena-image.h"
+#include "style.h"
+#include "display/nr-arena.h"
+#include "display/nr-filter.h"
+#include "display/nr-filter-gaussian.h"
+#include <livarot/Path.h>
+#include <livarot/Shape.h>
+#include "sp-filter.h"
+#include "sp-gaussian-blur.h"
int nr_arena_image_x_sample = 1;
int nr_arena_image_y_sample = 1;
*
*/
+// defined in nr-arena-shape.cpp
+void nr_pixblock_render_shape_mask_or(NRPixBlock &m, Shape *theS);
+
static void nr_arena_image_class_init (NRArenaImageClass *klass);
static void nr_arena_image_init (NRArenaImage *image);
static void nr_arena_image_finalize (NRObject *object);
static unsigned int nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset);
-static unsigned int nr_arena_image_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags);
+static unsigned int nr_arena_image_render (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags);
static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky);
static NRArenaItemClass *parent_class;
image->height = 256.0;
nr_matrix_set_identity (&image->grid2px);
+
+ image->style = 0;
}
static void
@@ -130,6 +144,12 @@ nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int
bbox.y0 = image->y;
bbox.x1 = image->x + image->width;
bbox.y1 = image->y + image->height;
+
+ image->c00 = (NR::Point(bbox.x0, bbox.y0) * gc->transform);
+ image->c01 = (NR::Point(bbox.x0, bbox.y1) * gc->transform);
+ image->c10 = (NR::Point(bbox.x1, bbox.y0) * gc->transform);
+ image->c11 = (NR::Point(bbox.x1, bbox.y1) * gc->transform);
+
nr_rect_d_matrix_transform (&bbox, &bbox, &gc->transform);
item->bbox.x0 = (int) floor (bbox.x0);
@@ -152,27 +172,14 @@ nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int
#define b2i (image->grid2px)
static unsigned int
-nr_arena_image_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags)
+nr_arena_image_render (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags)
{
nr_arena_image_x_sample = prefs_get_int_attribute ("options.bitmapoversample", "value", 1);
nr_arena_image_y_sample = nr_arena_image_x_sample;
- NRArenaImage *image = NR_ARENA_IMAGE (item);
-
- if (!image->px) return item->state;
-
- guint32 Falpha = item->opacity;
- if (Falpha < 1) return item->state;
+ bool outline = (item->arena->rendermode == RENDERMODE_OUTLINE);
- unsigned char * dpx = NR_PIXBLOCK_PX (pb);
- const int drs = pb->rs;
- const int dw = pb->area.x1 - pb->area.x0;
- const int dh = pb->area.y1 - pb->area.y0;
-
- unsigned char * spx = image->px;
- const int srs = image->pxrs;
- const int sw = image->pxw;
- const int sh = image->pxh;
+ NRArenaImage *image = NR_ARENA_IMAGE (item);
NR::Matrix d2s;
@@ -183,23 +190,78 @@ nr_arena_image_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigne
d2s[4] = b2i[0] * pb->area.x0 + b2i[2] * pb->area.y0 + b2i[4];
d2s[5] = b2i[1] * pb->area.x0 + b2i[3] * pb->area.y0 + b2i[5];
- if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8) {
- /* fixme: This is not implemented yet (Lauris) */
- /* nr_R8G8B8_R8G8B8_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample); */
- } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
- nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
- } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) {
-
- //FIXME: The _N_N_N_ version gives a gray border around images, see bug 906376
- // This mode is only used when exporting, screen rendering always has _P_P_P_, so I decided to simply replace it for now
- // Feel free to propose a better fix
-
- //nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
- nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
+ if (!outline) {
+
+ if (!image->px) return item->state;
+
+ guint32 Falpha = item->opacity;
+ if (Falpha < 1) return item->state;
+
+ unsigned char * dpx = NR_PIXBLOCK_PX (pb);
+ const int drs = pb->rs;
+ const int dw = pb->area.x1 - pb->area.x0;
+ const int dh = pb->area.y1 - pb->area.y0;
+
+ unsigned char * spx = image->px;
+ const int srs = image->pxrs;
+ const int sw = image->pxw;
+ const int sh = image->pxh;
+
+ if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8) {
+ /* fixme: This is not implemented yet (Lauris) */
+ /* nr_R8G8B8_R8G8B8_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample); */
+ } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
+ } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) {
+
+ //FIXME: The _N_N_N_ version gives a gray border around images, see bug 906376
+ // This mode is only used when exporting, screen rendering always has _P_P_P_, so I decided to simply replace it for now
+ // Feel free to propose a better fix
+
+ //nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
+ nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample);
+ }
+
+ pb->empty = FALSE;
+
+ } else { // outline; draw a rect instead
+
+ Path* thePath = new Path;
+ thePath->SetBackData (false);
+ thePath->Reset ();
+
+ thePath->MoveTo (image->c00);
+ // the box
+ thePath->LineTo (image->c10);
+ thePath->LineTo (image->c11);
+ thePath->LineTo (image->c01);
+ thePath->LineTo (image->c00);
+ // the diagonals
+ thePath->LineTo (image->c11);
+ thePath->MoveTo (image->c10);
+ thePath->LineTo (image->c01);
+
+ // livarot black magic - exactly this sequnce of conversions to get stable rendering of the shape
+ thePath->Convert(1.0);
+ Shape* theShape = new Shape;
+ thePath->Stroke(theShape, true, 0.25, join_pointy, butt_straight, 5);
+ Shape* theShape1 = new Shape;
+ theShape1->ConvertToShape(theShape, fill_nonZero);
+
+ NRPixBlock m;
+ nr_pixblock_setup_fast(&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE);
+ m.visible_area = pb->visible_area;
+ nr_pixblock_render_shape_mask_or(m, theShape1);
+ m.empty = FALSE;
+ guint32 rgba = prefs_get_int_attribute("options.wireframecolors", "images", 0xff0000ff);
+ nr_blit_pixblock_mask_rgba32(pb, &m, rgba);
+ pb->empty = FALSE;
+ nr_pixblock_release(&m);
+ delete theShape;
+ delete theShape1;
+ delete thePath;
}
- pb->empty = FALSE;
-
return item->state;
}
@@ -256,3 +318,53 @@ nr_arena_image_set_geometry (NRArenaImage *image, double x, double y, double wid
nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE);
}
+void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style)
+{
+ g_return_if_fail(image != NULL);
+ g_return_if_fail(NR_IS_ARENA_IMAGE(image));
+
+ if (style) sp_style_ref(style);
+ if (image->style) sp_style_unref(image->style);
+ image->style = style;
+
+ //if there is a filter set for this group
+ if (style && style->filter.set && style->filter.filter) {
+
+ image->filter = new NR::Filter();
+ image->filter->set_x(style->filter.filter->x);
+ image->filter->set_y(style->filter.filter->y);
+ image->filter->set_width(style->filter.filter->width);
+ image->filter->set_height(style->filter.filter->height);
+
+ //go through all SP filter primitives
+ for(int i=0; i<style->filter.filter->_primitive_count; i++)
+ {
+ SPFilterPrimitive *primitive = style->filter.filter->_primitives[i];
+ //if primitive is gaussianblur
+// if(SP_IS_GAUSSIANBLUR(primitive))
+ {
+ NR::FilterGaussian * gaussian = (NR::FilterGaussian *) image->filter->add_primitive(NR::NR_FILTER_GAUSSIANBLUR);
+ SPGaussianBlur * spblur = SP_GAUSSIANBLUR(primitive);
+ float num = spblur->stdDeviation.getNumber();
+ if( num>=0.0 )
+ {
+ float optnum = spblur->stdDeviation.getOptNumber();
+ if( optnum>=0.0 )
+ gaussian->set_deviation((double) num, (double) optnum);
+ else
+ gaussian->set_deviation((double) num);
+ }
+ }
+ }
+ }
+ else
+ {
+ //no filter set for this group
+ image->filter = NULL;
+ }
+
+ if (style && style->enable_background.set
+ && style->enable_background.value == SP_CSS_BACKGROUND_NEW) {
+ image->background_new = true;
+ }
+}