Exemplo n.º 1
0
static unsigned int
nr_arena_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset)
{
    unsigned int newstate;

    NRArenaGroup *group = NR_ARENA_GROUP (item);

    unsigned int beststate = NR_ARENA_ITEM_STATE_ALL;

    for (NRArenaItem *child = group->children; child != NULL; child = child->next) {
        NRGC cgc(gc);
        cgc.transform = group->child_transform * gc->transform;
        newstate = nr_arena_item_invoke_update (child, area, &cgc, state, reset);
        beststate = beststate & newstate;
    }

    if (beststate & NR_ARENA_ITEM_STATE_BBOX) {
        nr_rect_l_set_empty (&item->bbox);
        for (NRArenaItem *child = group->children; child != NULL; child = child->next) {
            if (child->visible)
                nr_rect_l_union (&item->bbox, &item->bbox, &child->drawbox);
        }
    }

    return beststate;
}
Exemplo n.º 2
0
static unsigned int
nr_arena_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset)
{
	NRArenaGroup *group;
	NRArenaItem *child;
	unsigned int newstate, beststate;

	group = NR_ARENA_GROUP (item);

	beststate = NR_ARENA_ITEM_STATE_ALL;

	for (child = group->children; child != NULL; child = child->next) {
		NRGC cgc;
		nr_matrix_multiply_dfd (&cgc.transform, &group->child_transform, &gc->transform);
		newstate = nr_arena_item_invoke_update (child, area, &cgc, state, reset);
		beststate = beststate & newstate;
	}

	if (beststate & NR_ARENA_ITEM_STATE_BBOX) {
		nr_rect_l_set_empty (&item->bbox);
		for (child = group->children; child != NULL; child = child->next) {
			nr_rect_l_union (&item->bbox, &item->bbox, &child->bbox);
		}
	}

	return beststate;
}
Exemplo n.º 3
0
static void
sp_canvas_arena_update (SPCanvasItem *item, double *affine, unsigned int flags)
{
	SPCanvasArena *arena;
	guint reset;

	arena = SP_CANVAS_ARENA (item);

	if (((SPCanvasItemClass *) parent_class)->update)
		(* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags);

	memcpy (NR_MATRIX_D_TO_DOUBLE (&arena->gc.transform), affine, 6 * sizeof (double));

	if (flags & SP_CANVAS_UPDATE_AFFINE) {
		reset = NR_ARENA_ITEM_STATE_ALL;
	} else {
		reset = NR_ARENA_ITEM_STATE_NONE;
	}

	nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset);

	item->x1 = arena->root->bbox.x0 - 1;
	item->y1 = arena->root->bbox.y0 - 1;
	item->x2 = arena->root->bbox.x1 + 1;
	item->y2 = arena->root->bbox.y1 + 1;

	if (arena->cursor) {
		NRArenaItem *new_arena;
		/* Mess with enter/leave notifiers */
		new_arena = nr_arena_item_invoke_pick (arena->root, arena->cx, arena->cy, nr_arena_global_delta, arena->sticky);
		if (new_arena != arena->active) {
			GdkEventCrossing ec;
			ec.window = GTK_WIDGET (item->canvas)->window;
			ec.send_event = TRUE;
			ec.subwindow = ec.window;
			ec.time = GDK_CURRENT_TIME;
			ec.x = arena->cx;
			ec.y = arena->cy;
			/* fixme: */
			if (arena->active) {
				ec.type = GDK_LEAVE_NOTIFY;
				sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
			}
			/* fixme: This is not optimal - better track ::destroy (Lauris) */
			if (arena->active) nr_object_unref ((NRObject *) arena->active);
			arena->active = new_arena;
			if (arena->active) nr_object_ref ((NRObject *) arena->active);
			if (arena->active) {
				ec.type = GDK_ENTER_NOTIFY;
				sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
			}
		}
	}
}
Exemplo n.º 4
0
static double
sp_canvas_arena_point (SPCanvasItem *item, double x, double y, SPCanvasItem **actual_item)
{
	SPCanvasArena *arena;
	NRArenaItem *picked;

	arena = SP_CANVAS_ARENA (item);

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

	picked = nr_arena_item_invoke_pick (arena->root, x, y, nr_arena_global_delta, arena->sticky);

	arena->picked = picked;

	if (picked) {
		*actual_item = item;
		return 0.0;
	}

	return 1e18;
}
Exemplo n.º 5
0
static gint
sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event)
{
	SPCanvasArena *arena;
	NRArenaItem *new_arena;
	gint ret;
	/* fixme: This sucks, we have to handle enter/leave notifiers */

	arena = SP_CANVAS_ARENA (item);

	ret = FALSE;

	switch (event->type) {
	case GDK_ENTER_NOTIFY:
		if (!arena->cursor) {
			if (arena->active) {
				g_warning ("Cursor entered to arena with already active item");
				nr_object_unref ((NRObject *) arena->active);
			}
			arena->cursor = TRUE;
#if 0
			gnome_canvas_w2c_d (item->canvas, event->crossing.x, event->crossing.y, &arena->cx, &arena->cy);
#else
			arena->cx = event->crossing.x;
			arena->cy = event->crossing.y;
#endif
			/* fixme: Not sure abut this, but seems the right thing (Lauris) */
			nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE);
			arena->active = nr_arena_item_invoke_pick (arena->root, arena->cx, arena->cy, nr_arena_global_delta, arena->sticky);
			if (arena->active) nr_object_ref ((NRObject *) arena->active);
			ret = sp_canvas_arena_send_event (arena, event);
		}
		break;
	case GDK_LEAVE_NOTIFY:
		if (arena->cursor) {
			ret = sp_canvas_arena_send_event (arena, event);
			if (arena->active) nr_object_unref ((NRObject *) arena->active);
			arena->active = NULL;
			arena->cursor = FALSE;
		}
		break;
	case GDK_MOTION_NOTIFY:
#if 0
		gnome_canvas_w2c_d (item->canvas, event->motion.x, event->motion.y, &arena->cx, &arena->cy);
#else
		arena->cx = event->motion.x;
		arena->cy = event->motion.y;
#endif
		/* fixme: Not sure abut this, but seems the right thing (Lauris) */
		nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE);
		new_arena = nr_arena_item_invoke_pick (arena->root, arena->cx, arena->cy, nr_arena_global_delta, arena->sticky);
		if (new_arena != arena->active) {
			GdkEventCrossing ec;
			ec.window = event->motion.window;
			ec.send_event = event->motion.send_event;
			ec.subwindow = event->motion.window;
			ec.time = event->motion.time;
			ec.x = event->motion.x;
			ec.y = event->motion.y;
			/* fixme: */
			if (arena->active) {
				ec.type = GDK_LEAVE_NOTIFY;
				ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
			}
			if (arena->active) nr_object_unref ((NRObject *) arena->active);
			arena->active = new_arena;
			if (arena->active) nr_object_ref ((NRObject *) arena->active);
			if (arena->active) {
				ec.type = GDK_ENTER_NOTIFY;
				ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec);
			}
		}
		ret = sp_canvas_arena_send_event (arena, event);
		break;
	default:
		/* Just send event */
		ret = sp_canvas_arena_send_event (arena, event);
		break;
	}

	return ret;
}
Exemplo n.º 6
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);
		}
	}
}
Exemplo n.º 7
0
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;
}