void FilterSlot::get_final(int slot_nr, NRPixBlock *result) {
    NRPixBlock *final_usr = get(slot_nr);
    Geom::Matrix trans = units.get_matrix_pb2display();

    int size = (result->area.x1 - result->area.x0)
        * (result->area.y1 - result->area.y0)
        * NR_PIXBLOCK_BPP(result);
    memset(NR_PIXBLOCK_PX(result), 0, size);

    if (fabs(trans[1]) > 1e-6 || fabs(trans[2]) > 1e-6) {
        if (filterquality == FILTER_QUALITY_BEST) {
            NR::transform_bicubic(result, final_usr, trans);
        } else {
            NR::transform_nearest(result, final_usr, trans);
        }
    } else if (fabs(trans[0] - 1) > 1e-6 || fabs(trans[3] - 1) > 1e-6) {
        NR::scale_bicubic(result, final_usr);
    } else {
        nr_blit_pixblock_pixblock(result, final_usr);
    }
}
예제 #2
0
NRPixBlock *filter_get_alpha(NRPixBlock *src)
{
    NRPixBlock *dst = new NRPixBlock;
    nr_pixblock_setup_fast(dst, NR_PIXBLOCK_MODE_R8G8B8A8P,
                           src->area.x0, src->area.y0,
                           src->area.x1, src->area.y1, false);
    if (!dst || (dst->size != NR_PIXBLOCK_SIZE_TINY && dst->data.px == NULL)) {
        g_warning("Memory allocation failed in filter_get_alpha");
        delete dst;
        return NULL;
    }
    nr_blit_pixblock_pixblock(dst, src);

    unsigned char *data = NR_PIXBLOCK_PX(dst);
    int end = dst->rs * (dst->area.y1 - dst->area.y0);
    for (int i = 0 ; i < end ; i += 4) {
        data[i + 0] = 0;
        data[i + 1] = 0;
        data[i + 2] = 0;
    }
    dst->empty = false;

    return dst;
}
예제 #3
0
static void
sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf)
{
	SPCanvasArena *arena;
	gint bw, bh, sw, sh;
	gint x, y;

	arena = SP_CANVAS_ARENA (item);

	nr_arena_item_invoke_update (arena->root, NULL, &arena->gc,
				     NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER,
				     NR_ARENA_ITEM_STATE_NONE);

	if (buf->is_bg) {
		sp_canvas_clear_buffer (buf);
		buf->is_bg = FALSE;
		buf->is_buf = TRUE;
	}

	bw = buf->rect.x1 - buf->rect.x0;
	bh = buf->rect.y1 - buf->rect.y0;
	if ((bw < 1) || (bh < 1)) return;

	/* 65536 is max cached buffer and we need 4 channels */
	if (bw * bh < 16384) {
		/* We can go with single buffer */
		sw = bw;
		sh = bh;
	} else if (bw <= 2048) {
		/* Go with row buffer */
		sw = bw;
		sh = 16384 / bw;
	} else if (bh <= 2048) {
		/* Go with column buffer */
		sw = 16384 / bh;
		sh = bh;
	} else {
		sw = 128;
		sh = 128;
	}

/* fixme: RGB transformed bitmap blit is not implemented (Lauris) */
/* And even if it would be, unless it uses MMX there is little reason to go RGB */
#define STRICT_RGBA

	for (y = buf->rect.y0; y < buf->rect.y1; y += sh) {
		for (x = buf->rect.x0; x < buf->rect.x1; x += sw) {
			NRRectL area;
#ifdef STRICT_RGBA
			NRPixBlock pb;
#endif
			NRPixBlock cb;

			area.x0 = x;
			area.y0 = y;
			area.x1 = MIN (x + sw, buf->rect.x1);
			area.y1 = MIN (y + sh, buf->rect.y1);

#ifdef STRICT_RGBA
			nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8A8P, area.x0, area.y0, area.x1, area.y1, TRUE);
			/* fixme: */
			pb.empty = FALSE;
#endif

			nr_pixblock_setup_extern (&cb, NR_PIXBLOCK_MODE_R8G8B8, area.x0, area.y0, area.x1, area.y1,
						  buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + 3 * (x - buf->rect.x0),
						  buf->buf_rowstride,
						  FALSE, FALSE);

#ifdef STRICT_RGBA
			nr_arena_item_invoke_render (arena->root, &area, &pb, 0);
			nr_blit_pixblock_pixblock (&cb, &pb);
			nr_pixblock_release (&pb);
#else
			nr_arena_item_invoke_render (arena->root, &area, &cb, 0);
#endif

			nr_pixblock_release (&cb);
		}
	}
}