Code

Fixed icon loading, cacheing and fallback to use stock mechanisms.
[inkscape.git] / src / display / nr-filter-slot.cpp
index 62a8717bb2c0e83bb4ad6b4a8ef0534bc0083765..1501afcbecb91699ac83b4c227033a5adebe11ba 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <assert.h>
+#include <string.h>
 
 #include "display/nr-arena-item.h"
 #include "display/nr-filter-types.h"
@@ -162,7 +163,7 @@ void FilterSlot::get_final(int slot_nr, NRPixBlock *result) {
     memset(NR_PIXBLOCK_PX(result), 0, size);
 
     if (fabs(trans[1]) > 1e-6 || fabs(trans[2]) > 1e-6) {
-        transform_nearest(result, final_usr, trans);
+        transform_bicubic(result, final_usr, trans);
     } else if (fabs(trans[0] - 1) > 1e-6 || fabs(trans[3] - 1) > 1e-6) {
         scale_bicubic(result, final_usr);
     } else {
@@ -172,8 +173,18 @@ void FilterSlot::get_final(int slot_nr, NRPixBlock *result) {
 
 void FilterSlot::set(int slot_nr, NRPixBlock *pb)
 {
-    int index = _get_index(slot_nr);
+    /* Unnamed slot is for saving filter primitive results, when parameter
+     * 'result' is not set. Only the filter immediately after this one
+     * can access unnamed results, so we don't have to worry about overwriting
+     * previous results in filter chain. On the other hand, we may not
+     * overwrite any other image with this one, because they might be
+     * accessed later on. */
+    int index = ((slot_nr != NR_FILTER_SLOT_NOT_SET)
+                 ? _get_index(slot_nr)
+                 : _get_index(NR_FILTER_UNNAMED_SLOT));
     assert(index >= 0);
+    // Unnamed slot is only for NR::FilterSlot internal use.
+    assert(slot_nr != NR_FILTER_UNNAMED_SLOT);
     assert(slot_nr == NR_FILTER_SLOT_NOT_SET ||_slot_number[index] == slot_nr);
 
     if (slot_nr == NR_FILTER_SOURCEGRAPHIC || slot_nr == NR_FILTER_BACKGROUNDIMAGE) {
@@ -205,10 +216,14 @@ void FilterSlot::set(int slot_nr, NRPixBlock *pb)
                                    min_x, min_y,
                                    max_x, max_y, true);
             if (trans_pb->size != NR_PIXBLOCK_SIZE_TINY && trans_pb->data.px == NULL) {
-                // memory allocation failed
+                /* TODO: this gets hit occasionally. Worst case scenario:
+                 * images are exported in horizontal stripes. One stripe
+                 * is not too high, but can get thousands of pixels wide.
+                 * Rotate this 45 degrees -> _huge_ image */
+                g_warning("Memory allocation failed in NR::FilterSlot::set (transform)");
                 return;
             }
-            transform_nearest(trans_pb, pb, trans);
+            transform_bicubic(trans_pb, pb, trans);
             nr_pixblock_release(pb);
             delete pb;
             pb = trans_pb;
@@ -231,7 +246,7 @@ void FilterSlot::set(int slot_nr, NRPixBlock *pb)
             nr_pixblock_setup_fast(trans_pb, pb->mode,
                                    min_x, min_y, max_x, max_y, true);
             if (trans_pb->size != NR_PIXBLOCK_SIZE_TINY && trans_pb->data.px == NULL) {
-                //memory allocation failed
+                g_warning("Memory allocation failed in NR::FilterSlot::set (scaling)");
                 return;
             }
             scale_bicubic(trans_pb, pb);
@@ -273,7 +288,8 @@ int FilterSlot::_get_index(int slot_nr)
            slot_nr == NR_FILTER_BACKGROUNDIMAGE ||
            slot_nr == NR_FILTER_BACKGROUNDALPHA ||
            slot_nr == NR_FILTER_FILLPAINT ||
-           slot_nr == NR_FILTER_STROKEPAINT);
+           slot_nr == NR_FILTER_STROKEPAINT ||
+           slot_nr == NR_FILTER_UNNAMED_SLOT);
 
     int index = -1;
     if (slot_nr == NR_FILTER_SLOT_NOT_SET) {
@@ -292,7 +308,7 @@ int FilterSlot::_get_index(int slot_nr)
         int seek = _slot_count;
         do {
             seek--;
-        } while (_slot_number[seek] == NR_FILTER_SLOT_NOT_SET && seek >= 0);
+        } while ((seek >= 0) && (_slot_number[seek] == NR_FILTER_SLOT_NOT_SET));
         /* If there is no space for more slots, create more space */
         if (seek == _slot_count - 1) {
             NRPixBlock **new_slot = new NRPixBlock*[_slot_count * 2];