Code

Patch from codedread. Prevents rendering of title/desc/metadata elements in text...
[inkscape.git] / src / display / nr-filter-convolve-matrix.cpp
index 562f3ffc470e1c83bc4fca2c01640de26a9854c6..e23a8b32f8a34621328e88ae14f2a7206aa5e5ff 100644 (file)
  */
 
 #include "display/nr-filter-convolve-matrix.h"
+#include "display/nr-filter-units.h"
 #include "display/nr-filter-utils.h"
 #include <vector>
+
 namespace NR {
 
 FilterConvolveMatrix::FilterConvolveMatrix()
@@ -32,8 +34,13 @@ static bool inside_area(int px, int py, int w, int h){
         return true;
 }
 
-int FilterConvolveMatrix::render(FilterSlot &slot, Matrix const &trans) {
+int FilterConvolveMatrix::render(FilterSlot &slot, FilterUnits const &/*units*/) {
     NRPixBlock *in = slot.get(_input);
+    if (!in) {
+        g_warning("Missing source image for feConvolveMatrix (in=%d)", _input);
+        return 1;
+    }
+
     NRPixBlock *out = new NRPixBlock;
 
     nr_pixblock_setup_fast(out, in->mode,
@@ -48,6 +55,9 @@ int FilterConvolveMatrix::render(FilterSlot &slot, Matrix const &trans) {
     int width = in->area.x1 - in->area.x0;
     int height = in->area.y1 - in->area.y0;
 
+    unsigned int index;
+    unsigned int kernel_index;
+    
     for (x=targetX; x < width - (orderX - targetX); x++){
         for (y=targetY; y < height - (orderY - targetY); y++){
             result_R = 0;
@@ -57,18 +67,25 @@ int FilterConvolveMatrix::render(FilterSlot &slot, Matrix const &trans) {
             for (i=0; i < orderY; i++){
                 for (j=0; j < orderX; j++){
                     if (inside_area(x - targetX + j, y - targetY + i, width, height)){
-                        result_R += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] );
-                        result_G += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )+1] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] );
-                        result_B += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )+2] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] );
-                        result_A += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )+3] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] );
+                        index = 4*( x - targetX + j + width*(y - targetY + i) );
+                        kernel_index = orderX-j-1 + orderX*(orderY-i-1);
+                        result_R += ( (double) in_data[index++] * kernelMatrix[kernel_index] );
+                        result_G += ( (double) in_data[index++] * kernelMatrix[kernel_index] );
+                        result_B += ( (double) in_data[index++] * kernelMatrix[kernel_index] );
+                        result_A += ( (double) in_data[index] * kernelMatrix[kernel_index] );
                     }
                 }
             }
-
-            out_data[4*( x + width*y )] = CLAMP_D_TO_U8(result_R / divisor + bias);
-            out_data[4*( x + width*y )+1] = CLAMP_D_TO_U8(result_G / divisor + bias);
-            out_data[4*( x + width*y )+2] = CLAMP_D_TO_U8(result_B / divisor + bias);
-            out_data[4*( x + width*y )+3] = CLAMP_D_TO_U8(result_A / divisor + bias);
+            unsigned int out_index = 4*( x + width*y );
+            out_data[out_index++] = CLAMP_D_TO_U8(result_R / divisor + bias);
+            out_data[out_index++] = CLAMP_D_TO_U8(result_G / divisor + bias);
+            out_data[out_index++] = CLAMP_D_TO_U8(result_B / divisor + bias);
+
+            if( preserveAlpha ) {
+                out_data[out_index] = in_data[out_index];
+            } else {
+                out_data[out_index] = CLAMP_D_TO_U8(result_A / divisor + bias);
+            }
         }
     }
 
@@ -107,13 +124,13 @@ void FilterConvolveMatrix::set_kernelMatrix(std::vector<gdouble> &km) {
 
 void FilterConvolveMatrix::set_edgeMode(FilterConvolveMatrixEdgeMode mode){
     edgeMode = mode;
-}    
+}
 
 void FilterConvolveMatrix::set_preserveAlpha(bool pa){
     preserveAlpha = pa;
 }
 
-void FilterConvolveMatrix::area_enlarge(NRRectL &area, Matrix const &trans)
+void FilterConvolveMatrix::area_enlarge(NRRectL &area, Matrix const &/*trans*/)
 {
     //Seems to me that since this filter's operation is resolution dependent,
     // some spurious pixels may still appear at the borders when low zooming or rotating. Needs a better fix.
@@ -123,6 +140,10 @@ void FilterConvolveMatrix::area_enlarge(NRRectL &area, Matrix const &trans)
     area.y1 += orderY - targetY;
 }
 
+FilterTraits FilterConvolveMatrix::get_input_traits() {
+    return TRAIT_PARALLER;
+}
+
 } /* namespace NR */
 
 /*