From e4a45ca88c45f44f2c83fde3722b2088b06918ef Mon Sep 17 00:00:00 2001 From: jucablues Date: Thu, 26 Jul 2007 02:00:51 +0000 Subject: [PATCH] improving displacement map renderer. --- src/display/nr-filter-displacement-map.cpp | 50 ++++++++++++++++------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/display/nr-filter-displacement-map.cpp b/src/display/nr-filter-displacement-map.cpp index ec8681ad1..7d32ce2e0 100644 --- a/src/display/nr-filter-displacement-map.cpp +++ b/src/display/nr-filter-displacement-map.cpp @@ -11,14 +11,15 @@ #include "display/nr-filter-displacement-map.h" #include "display/nr-filter-types.h" +#include "libnr/nr-pixops.h" namespace NR { FilterDisplacementMap::FilterDisplacementMap() -: Xchannel(3), - Ychannel(3), - scale(0), - _input2(NR_FILTER_SLOT_NOT_SET) +: scale(0), + _input2(NR_FILTER_SLOT_NOT_SET), + Xchannel(3), + Ychannel(3) {} FilterPrimitive * FilterDisplacementMap::create() { @@ -50,22 +51,45 @@ int FilterDisplacementMap::render(FilterSlot &slot, Matrix const &trans) { unsigned char *out_data = NR_PIXBLOCK_PX(out); int x, y, x0, y0, x1, y1, width; double coordx, coordy; - +// unsigned int alpha; //used for demultiplication + x0 = out->area.x0; y0 = out->area.y0; x1 = out->area.x1; y1 = out->area.y1; width = x1 - x0; - + for (x=x0 + scale/2; x < x1 - scale/2; x++){ for (y=y0 + scale/2; y < y1 - scale/2; y++){ - coordx = x-x0 + scale * ( ((double)map_data[4*((x-x0) + width*(y-y0)) + Xchannel])/255 - 0.5); - coordy = y-y0 + scale * ( ((double)map_data[4*((x-x0) + width*(y-y0)) + Ychannel])/255 - 0.5); - - out_data[4*((x-x0) + width*(y-y0))] = texture_data[4*(int)(coordx + coordy*width)]; - out_data[4*((x-x0) + width*(y-y0)) + 1] = texture_data[4*(int)(coordx + coordy*width) + 1]; - out_data[4*((x-x0) + width*(y-y0)) + 2] = texture_data[4*(int)(coordx + coordy*width) + 2]; - out_data[4*((x-x0) + width*(y-y0)) + 3] = texture_data[4*(int)(coordx + coordy*width) + 3]; +/* SVG spec states that pixel values must be alpha-demultiplied before processing this filter operation. +The following code does it, but when we DON'T do it, output is more similar to output from Batik. + +Batik output: + http://bighead.poli.usp.br/~juca/code/inkscape/batik-fed02.png +Inkscape output without demultiplication: + http://bighead.poli.usp.br/~juca/code/inkscape/displacement-map-test.png + + There is also this other bug that can be seen in the above screenshot: the lower and the right portions are not rendered, I dont know why. + + --JucaBlues + + if (map->mode == NR_PIXBLOCK_MODE_R8G8B8A8P){ + alpha = (unsigned int) map_data[4*((x-x0) + width*(y-y0)) + 3]; + if (alpha==0){ + coordx = x-x0; + coordy = y-y0; + } else { + coordx = x-x0 + scale * ( ((double)NR_DEMUL_111( (unsigned int)map_data[4*((x-x0) + width*(y-y0)) + Xchannel], alpha))/255 - 0.5 ); + coordy = y-y0 + scale * ( ((double)NR_DEMUL_111( (unsigned int)map_data[4*((x-x0) + width*(y-y0)) + Ychannel], alpha))/255 - 0.5 ); + } + } else {*/ + coordx = x-x0 + scale * ( ((double) map_data[4*((x-x0) + width*(y-y0)) + Xchannel])/255 - 0.5 ); + coordy = y-y0 + scale * ( ((double) map_data[4*((x-x0) + width*(y-y0)) + Ychannel])/255 - 0.5 ); + + out_data[4*((x-x0) + width*(y-y0))] = texture_data[4*((int)coordx + ((int)coordy)*width)]; + out_data[4*((x-x0) + width*(y-y0)) + 1] = texture_data[4*((int)coordx + ((int)coordy)*width) + 1]; + out_data[4*((x-x0) + width*(y-y0)) + 2] = texture_data[4*((int)coordx + ((int)coordy)*width) + 2]; + out_data[4*((x-x0) + width*(y-y0)) + 3] = texture_data[4*((int)coordx + ((int)coordy)*width) + 3]; } } -- 2.30.2