index 2e973b4ec9d258b0f928ed912c6fb0d7c4ab77ba..f7a04fd50383541d17dbd62f395b26ff993299a5 100644 (file)
#include <glib.h>
#include <cmath>
+#include <cstring>
+#include <string>
#include "display/nr-filter.h"
#include "display/nr-filter-primitive.h"
#include "libnr/nr-scale.h"
#include "svg/svg-length.h"
#include "sp-filter-units.h"
-#if defined (SOLARIS_2_8)
+#if defined (SOLARIS) && (SOLARIS == 8)
#include "round.h"
using Inkscape::round;
#endif
int Filter::render(NRArenaItem const *item, NRPixBlock *pb)
{
- if(!_primitive[0]) {
+ if (!_primitive[0]) {
// TODO: Should clear the input buffer instead of just returning
- return 0;
+ return 1;
}
- Matrix trans = *item->ctm;
+ Matrix trans = item->ctm;
FilterSlot slot(_slot_count, item);
- Rect item_bbox = *item->item_bbox;
+ Rect item_bbox;
+ try {
+ item_bbox = *item->item_bbox;
+ } catch (NR::IsNothing) {
+ // Bounding box might not exist, so create a dummy one.
+ Point zero(0, 0);
+ item_bbox = Rect(zero, zero);
+ }
+ if (item_bbox.min()[X] > item_bbox.max()[X]
+ || item_bbox.min()[Y] > item_bbox.max()[Y])
+ {
+ // Code below assumes non-negative size.
+ return 1;
+ }
+
Rect filter_area = filter_effect_area(item_bbox);
+ if (item_bbox.isEmpty()) {
+ // It's no use to try and filter an empty object.
+ return 1;
+ }
+
FilterUnits units(_filter_units, _primitive_units);
units.set_ctm(trans);
units.set_item_bbox(item_bbox);
NRPixBlock *in = new NRPixBlock;
nr_pixblock_setup_fast(in, pb->mode, pb->area.x0, pb->area.y0,
- pb->area.x1, pb->area.y1, false);
+ pb->area.x1, pb->area.y1, true);
if (in->size != NR_PIXBLOCK_SIZE_TINY && in->data.px == NULL) {
g_warning("NR::Filter::render: failed to reserve temporary buffer");
return 0;
}
in = NULL; // in is now handled by FilterSlot, we should not touch it
- // TODO: filters may need both filterUnits and primitiveUnits,
- // so we should pass FilterUnits to render method, not just one Matrix
- Matrix primitiveunits2pixblock = units.get_matrix_primitiveunits2pb();
for (int i = 0 ; i < _primitive_count ; i++) {
- _primitive[i]->render(slot, primitiveunits2pixblock);
+ _primitive[i]->render(slot, units);
}
slot.get_final(_output_slot, pb);
}
void Filter::bbox_enlarge(NRRectL &bbox) {
+ // Modifying empty bounding boxes confuses rest of the renderer, so
+ // let's not do that.
+ if (bbox.x0 > bbox.x1 || bbox.y0 > bbox.y1) return;
+
/* TODO: this is wrong. Should use bounding box in user coordinates
* and find its extents in display coordinates. */
Point min(bbox.x0, bbox.y0);