Beispiel #1
0
static unsigned int
nr_arena_group_render (cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags)
{
    NRArenaGroup *group = NR_ARENA_GROUP (item);

    unsigned int ret = item->state;

    /* Just compose children into parent buffer */
    for (NRArenaItem *child = group->children; child != NULL; child = child->next) {
        ret = nr_arena_item_invoke_render (ct, child, area, pb, flags);
        if (ret & NR_ARENA_ITEM_STATE_INVALID) break;
    }

    return ret;
}
Beispiel #2
0
void
sp_canvas_arena_render_pixblock (SPCanvasArena *ca, NRPixBlock *pb)
{
	NRRectL area;

	g_return_if_fail (ca != NULL);
	g_return_if_fail (SP_IS_CANVAS_ARENA (ca));

	/* fixme: */
	pb->empty = FALSE;

	area.x0 = pb->area.x0;
	area.y0 = pb->area.y0;
	area.x1 = pb->area.x1;
	area.y1 = pb->area.y1;

	nr_arena_item_invoke_render (ca->root, &area, pb, 0);
}
Beispiel #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);
		}
	}
}
GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rect& dbox, unsigned psize) {
    NRGC gc(NULL);

    Geom::Matrix t(Geom::Scale(scale_factor, scale_factor));
    nr_arena_item_set_transform(root, t);

    gc.transform.setIdentity();
    nr_arena_item_invoke_update( root, NULL, &gc,
                                 NR_ARENA_ITEM_STATE_ALL,
                                 NR_ARENA_ITEM_STATE_NONE );

    /* Item integer bbox in points */
    NRRectL ibox;
    ibox.x0 = (int) floor(scale_factor * dbox.min()[Geom::X] + 0.5);
    ibox.y0 = (int) floor(scale_factor * dbox.min()[Geom::Y] + 0.5);
    ibox.x1 = (int) floor(scale_factor * dbox.max()[Geom::X] + 0.5);
    ibox.y1 = (int) floor(scale_factor * dbox.max()[Geom::Y] + 0.5);

    /* Find visible area */
    int width = ibox.x1 - ibox.x0;
    int height = ibox.y1 - ibox.y0;
    int dx = psize;
    int dy = psize;
    dx = (dx - width)/2; // watch out for size, since 'unsigned'-'signed' can cause problems if the result is negative
    dy = (dy - height)/2;

    NRRectL area;
    area.x0 = ibox.x0 - dx;
    area.y0 = ibox.y0 - dy;
    area.x1 = area.x0 + psize;
    area.y1 = area.y0 + psize;

    /* Actual renderable area */
    NRRectL ua;
    ua.x0 = std::max(ibox.x0, area.x0);
    ua.y0 = std::max(ibox.y0, area.y0);
    ua.x1 = std::min(ibox.x1, area.x1);
    ua.y1 = std::min(ibox.y1, area.y1);

    /* Set up pixblock */
    guchar *px = g_new(guchar, 4 * psize * psize);
    memset(px, 0x00, 4 * psize * psize);

    /* Render */
    NRPixBlock B;
    nr_pixblock_setup_extern( &B, NR_PIXBLOCK_MODE_R8G8B8A8N,
                              ua.x0, ua.y0, ua.x1, ua.y1,
                              px + 4 * psize * (ua.y0 - area.y0) +
                              4 * (ua.x0 - area.x0),
                              4 * psize, FALSE, FALSE );
    nr_arena_item_invoke_render(NULL, root, &ua, &B,
                                 NR_ARENA_ITEM_RENDER_NO_CACHE );
    nr_pixblock_release(&B);

    GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data(px,
                                      GDK_COLORSPACE_RGB,
                                      TRUE,
                                      8, psize, psize, psize * 4,
                                      (GdkPixbufDestroyNotify)g_free,
                                      NULL);

    return pixbuf;
}