static void
so_image_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
{
	GocItem *view = GOC_ITEM (GOC_GROUP (sov)->children->data);
	double scale = goc_canvas_get_pixels_per_unit (view->canvas);

	if (visible) {
		double x, y, width, height;
		double old_x1, old_y1, old_x2, old_y2, old_width, old_height;
		GdkPixbuf *placeholder = g_object_get_data (G_OBJECT (view), "tile");

		x = MIN (coords [0], coords [2]) / scale;
		y = MIN (coords [1], coords [3]) / scale;
		width  = fabs (coords [2] - coords [0]) / scale;
		height = fabs (coords [3] - coords [1]) / scale;

		goc_item_get_bounds (view, &old_x1, &old_y1, &old_x2, &old_y2);
		goc_item_set (view,
			"x", x,			"y", y,
			"width",  width,	"height", height,
			NULL);

		/* regenerate the image if necessary */
		old_width = fabs (old_x1 - old_x2);
		old_height = fabs (old_y1 - old_y2);
		if (placeholder != NULL &&
		    (fabs (width - old_width) > 0.5 || fabs (height - old_height) > 0.5)) {
			GdkPixbuf *newimage = go_pixbuf_tile (placeholder,
				(guint)width, (guint)height);
			goc_item_set (view, "pixbuf", newimage, NULL);
			g_object_unref (newimage);
		}

		goc_item_show (view);
	} else
		goc_item_hide (view);
}
Example #2
0
void
goc_canvas_get_bounds (GocCanvas *canvas, double *x0, double *y0, double *x1, double *y1)
{
	goc_item_get_bounds (GOC_ITEM (canvas->root), x0, y0, x1, y1);
}
Example #3
0
static void
so_path_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
{
	GnmSOPathView *spv = (GnmSOPathView *) sov;

	if (visible) {
		SheetObject		*so   = sheet_object_view_get_so (sov);
		GnmSOPath const	*sop  = GNM_SO_PATH (so);
		GOPath *path;
		double scale, x_scale, y_scale, x, y;
		if ((sop->path == NULL && sop->paths == NULL) || sop->width <=0. || sop->height <=0.)
			return;

		scale = goc_canvas_get_pixels_per_unit (GOC_ITEM (sov)->canvas);
		x_scale = fabs (coords[2] - coords[0]) / sop->width / scale;
		y_scale = fabs (coords[3] - coords[1]) / sop->height / scale;
		x = MIN (coords[0], coords[2]) / scale - sop->x_offset * x_scale;
		y = MIN (coords[1], coords[3]) / scale - sop->y_offset * y_scale;

		if (sop->path != NULL) {
			path = go_path_scale (sop->path, x_scale, y_scale);
			goc_item_set (spv->path, "x", x, "y", y, "path", path, NULL);
			go_path_free (path);
		} else {
			unsigned i;
			for (i = 0; i < sop->paths->len; i++) {
				path = go_path_scale ((GOPath *) g_ptr_array_index (sop->paths, i), x_scale, y_scale);
				goc_item_set (GOC_ITEM (g_ptr_array_index (spv->paths, i)), "x", x, "y", y, "path", path, NULL);
				go_path_free (path);
			}
		}

		if (spv->text != NULL && GOC_ITEM (spv->text)) {
			double x0, y0, x1, y1;
			if (spv->path)
				goc_item_get_bounds (spv->path, &x0, &y0, &x1, &y1);
			else {
				unsigned i;
				double mx, my, Mx, My;
				x0 = y0 = G_MAXDOUBLE;
				x1 = y1 = -G_MAXDOUBLE;
				for (i = 0; i < spv->paths->len; i++) {
					goc_item_get_bounds (GOC_ITEM (g_ptr_array_index (spv->paths, i)), &mx, &my, &Mx, &My);
					if (mx < x0)
						x0 = mx;
					if (my < y0)
						y0 = my;
					if (Mx > x1)
						x1 = Mx;
					if (My > y1)
						y1 = My;
				}
			}
			x1 -= x0 + sop->margin_pts.left + sop->margin_pts.right;
			y1 -= y0 + sop->margin_pts.top + sop->margin_pts.bottom;
			x0 += x1 / 2. + sop->margin_pts.left;
			y0 += y1 / 2. + sop->margin_pts.top;
			x1 = MAX (x1, DBL_MIN);
			y1 = MAX (y1, DBL_MIN);

			goc_item_set (GOC_ITEM (spv->text),
			              "x", x0,
			              "y", y0,
				          "clip-height", y1,
				          "clip-width",  x1,
				          "wrap-width",  x1,
				          NULL);
		}
	} else
		goc_item_hide (GOC_ITEM (sov));
}
Example #4
0
static gboolean
goc_canvas_draw (GtkWidget *widget, cairo_t *cr)
{
	double x0, y0, x1, y1;
	double ax0, ay0, ax1, ay1;
	double clip_x1, clip_y1, clip_x2, clip_y2;
	GocCanvas *canvas = GOC_CANVAS (widget);
	GdkEventExpose *event = (GdkEventExpose *) gtk_get_current_event ();
	GocCanvasPrivate *priv = (GocCanvasPrivate *) canvas->priv;
	cairo_rectangle_list_t *l = cairo_copy_clip_rectangle_list (cr);
	int i, x, y;

	if (GOC_IS_ITEM (priv->invalidated_item) && priv->invalid_region) {
		/* evaluate the cairo clipped region and compare with the saved one */
		cairo_region_t *region;
		cairo_rectangle_int_t rect[l->num_rectangles];
	    for (i= 0; i  < l->num_rectangles; i++) {
			rect[i].x = l->rectangles[i].x;
			rect[i].y = l->rectangles[i].y;
			rect[i].width = l->rectangles[i].width;
			rect[i].height = l->rectangles[i].height;
		}
		region = cairo_region_create_rectangles (rect, l->num_rectangles);
		if (cairo_region_equal (priv->invalid_region, region)) {
			cairo_rectangle_list_destroy (l);
			cairo_region_destroy (region);
			/* looks like each time we call gtk_widget_queue_draw*,
			   the draw event is fired twice */
			if (priv->done) {
				priv->invalidated_item = NULL;
				cairo_region_destroy (priv->invalid_region);
				priv->invalid_region = NULL;
			} else {
				goc_item_draw (priv->invalidated_item, cr);
				priv->done = TRUE;
			}
			return TRUE;
		}

		cairo_region_destroy (region);
	}

	x = gtk_adjustment_get_value (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas)));
	y = gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas)));
	cairo_translate (cr, -x, -y);
	goc_item_get_bounds (GOC_ITEM (canvas->root),&x0, &y0, &x1, &y1);
	for (i= 0; i  < l->num_rectangles; i++) {
		cairo_save (cr);
		cairo_rectangle (cr, l->rectangles[i].x, l->rectangles[i].y,
		                 l->rectangles[i].width, l->rectangles[i].height);
		cairo_clip (cr);
		clip_x1 = l->rectangles[i].x;
		clip_y1 = l->rectangles[i].y;
		clip_x2 = clip_x1 + l->rectangles[i].width;
		clip_y2 = clip_y1 + l->rectangles[i].height;

		if (canvas->direction == GOC_DIRECTION_RTL) {
			ax1 = (double) (canvas->width - clip_x1) / canvas->pixels_per_unit + canvas->scroll_x1;
			ax0 = (double) (canvas->width - clip_x2) / canvas->pixels_per_unit + canvas->scroll_x1;
		} else {
			ax0 = (double) clip_x1 / canvas->pixels_per_unit + canvas->scroll_x1;
			ax1 = ((double) clip_x1 + event->area.width) / canvas->pixels_per_unit + canvas->scroll_x1;
		}
		ay0 = (double) clip_y1 / canvas->pixels_per_unit + canvas->scroll_y1;
		ay1 = (double) clip_y2 / canvas->pixels_per_unit + canvas->scroll_y1;
		if (x0 <= ax1 && x1 >= ax0 && y0 <= ay1 && y1 >= ay0) {
			canvas->cur_event = (GdkEvent *) event;
			goc_item_draw_region (GOC_ITEM (canvas->root), cr, ax0, ay0, ax1, ay1);
		}
		cairo_restore (cr);
	}
	cairo_rectangle_list_destroy (l);
	return TRUE;
}
Example #5
0
static void
cb_gnm_so_path_changed (GnmSOPath const *sop,
			G_GNUC_UNUSED GParamSpec *pspec,
			GnmSOPathView *group)
{
	GList *ptr = GOC_GROUP (group)->children;
	for (; ptr && ptr->data; ptr = ptr->next)
		if (GOC_IS_PATH (ptr->data))
			cb_gnm_so_path_style_changed (GOC_ITEM (ptr->data), sop);

	if (sop->text != NULL && *sop->text != 0) {
		/* set a font, a very bad solution, but will do until we move to GOString */
		PangoFontDescription *desc = pango_font_description_from_string ("Sans 10");
		GOStyle *style;
		if (group->text == NULL) {
			double x0, y0, x1, y1;
			if (group->path)
				goc_item_get_bounds (group->path, &x0, &y0, &x1, &y1);
			else {
				unsigned i;
				double mx, my, Mx, My;
				x0 = y0 = G_MAXDOUBLE;
				x1 = y1 = -G_MAXDOUBLE;
				for (i = 0; i < group->paths->len; i++) {
					goc_item_get_bounds (GOC_ITEM (g_ptr_array_index (group->paths, i)), &mx, &my, &Mx, &My);
					if (mx < x0)
						x0 = mx;
					if (my < y0)
						y0 = my;
					if (Mx > x1)
						x1 = Mx;
					if (My > y1)
						y1 = My;
				}
			}
			x1 -= x0 + sop->margin_pts.left + sop->margin_pts.right;
			y1 -= y0 + sop->margin_pts.top + sop->margin_pts.bottom;
			x0 += x1 / 2. + sop->margin_pts.left;
			y0 += y1 / 2. + sop->margin_pts.top;
			x1 = MAX (x1, DBL_MIN);
			y1 = MAX (y1, DBL_MIN);
			group->text = goc_item_new (GOC_GROUP (group), GOC_TYPE_TEXT,
				"anchor",	GO_ANCHOR_CENTER,
				"clip",		TRUE,
				"x",		x0,
				"y",		y0,
		        "clip-height", y1,
		        "clip-width",  x1,
		        "wrap-width",  x1,
				"attributes",	sop->markup,
				NULL);
		}
		style = go_styled_object_get_style (GO_STYLED_OBJECT (group->text));
		go_style_set_font_desc (style, desc);
		goc_item_set (group->text,
				     "text", sop->text,
				     "attributes",	sop->markup,
				     NULL);
	} else if (group->text != NULL) {
		g_object_unref (group->text);
		group->text = NULL;
	}
}