[cairo-commit] goocanvas/demo Makefile.am, 1.13, 1.14 demo-large-items.c, NONE, 1.1 demo-large-line.c, NONE, 1.1 demo-large-line.h, NONE, 1.1 demo-large-rect.c, NONE, 1.1 demo-large-rect.h, NONE, 1.1 demo-table.c, 1.2, 1.3 demo.c, 1.26, 1.27 mv-demo-table.c, 1.2, 1.3

Damon Chaplin commit at pdx.freedesktop.org
Fri May 11 09:30:59 PDT 2007


Committed by: damon

Update of /cvs/cairo/goocanvas/demo
In directory kemper:/tmp/cvs-serv11649/demo

Modified Files:
	Makefile.am demo-table.c demo.c mv-demo-table.c 
Added Files:
	demo-large-items.c demo-large-line.c demo-large-line.h 
	demo-large-rect.c demo-large-rect.h 
Log Message:
2007-05-11  Damon Chaplin  <damon at gnome.org>

	* demo/demo-large-rect.c: 
	* demo/demo-large-line.c: 
	* demo/demo-large-items.c: new demo and items to show how to create a
	very large canvas and very large items.

	* src/goocanvasitemsimple.c (goo_canvas_item_simple_get_line_width): 
	added utility function to get an item's line width.
	Also changed default line width property value to 2.0, and returned
	canvas line width setting if item's line width isn't set.

	* src/goocanvasrect.c (goo_canvas_rect_update): 
	* src/goocanvaspolyline.c (goo_canvas_polyline_reconfigure_arrows): use
	the above function to get the line width.



Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/goocanvas/demo/Makefile.am,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- Makefile.am	20 Feb 2007 23:53:17 -0000	1.13
+++ Makefile.am	11 May 2007 16:30:47 -0000	1.14
@@ -13,7 +13,8 @@
 	demo.c demo-fifteen.c demo-scalability.c demo-grabs.c \
 	demo-arrowhead.c demo-features.c demo-events.c \
 	demo-paths.c demo-focus.c demo-item.h demo-item.c demo-animation.c \
-	demo-clipping.c demo-table.c
+	demo-clipping.c demo-table.c demo-large-line.h demo-large-line.c \
+	demo-large-items.c demo-large-rect.h demo-large-rect.c
 
 demo_LDADD = $(top_builddir)/src/libgoocanvas.la @PACKAGE_LIBS@ $(INTLLIBS)
 

--- NEW FILE: demo-large-items.c ---
#include <config.h>
#include <stdlib.h>
#include <goocanvas.h>
#include "demo-large-line.h"
#include "demo-large-rect.h"

/*
 * We need to make sure that that (MAX_ZOOM * canvas width) < 2^31 so we stay
 * within the GDK window size limit (a signed 32-bit int).
 *
 * The canvas width is 107374182 * 2 = 214748364.
 * Multiply by MAX_ZOOM (10) = 2147483640.
 * 2^31 = 2147483648 so we are just inside the GDK limit.
 */
#if 1
#define CANVAS_TOP	-107374182
#define CANVAS_BOTTOM	107374182
#define CANVAS_LEFT	-107374182
#define CANVAS_RIGHT    107374182
#else
#define CANVAS_TOP	0
#define CANVAS_BOTTOM	10000
#define CANVAS_LEFT	0
#define CANVAS_RIGHT	10000
#endif

#define MAX_ZOOM	10

static gboolean
on_motion_notify (GooCanvasItem *item,
		  GooCanvasItem *target,
		  GdkEventMotion *event,
		  gpointer data)
{
  GooCanvasItem *ancestor = target;
  gchar *id;

  while (ancestor)
    {
      id = g_object_get_data (G_OBJECT (ancestor), "id");
      if (id)
	{
	  g_print ("%s item received 'motion-notify' signal\n", id);
	  return TRUE;
	}

      ancestor = goo_canvas_item_get_parent (ancestor);
    }

  return TRUE;
}


static void
zoom_changed (GtkAdjustment *adj, GooCanvas *canvas)
{
  goo_canvas_set_scale (canvas, adj->value);
}


GtkWidget *
create_large_items_page (void)
{
  GtkWidget *vbox, *hbox, *w, *scrolled_win, *canvas;
  GtkAdjustment *adj;
  GooCanvasItem *root, *item;
  gchar *text;

  vbox = gtk_vbox_new (FALSE, 4);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  gtk_widget_show (vbox);

  text = g_strdup_printf ("This is a very large canvas, from (%i, %i) to (%i, %i).\nThe maximum zoom is %i. At this scale the canvas comes very close to the GDK window size limit (32-bit gint).\nThe items have been specially written to work around cairo's limits (transformed coords must be < +/- 32768).",
			  CANVAS_LEFT, CANVAS_TOP,
			  CANVAS_RIGHT, CANVAS_BOTTOM, MAX_ZOOM);
  w = gtk_label_new (text);
  g_free (text);
  gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
  gtk_widget_show (w);

  hbox = gtk_hbox_new (FALSE, 4);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  gtk_widget_show (hbox);

  scrolled_win = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
				       GTK_SHADOW_IN);
  gtk_widget_show (scrolled_win);
  gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);

  /* Create the canvas. */
  canvas = goo_canvas_new ();
  gtk_widget_set_size_request (canvas, 600, 450);
  gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);

  root = goo_canvas_get_root_item (GOO_CANVAS (canvas));

  g_signal_connect (root, "motion_notify_event",
		    (GtkSignalFunc) on_motion_notify, NULL);

#if 1
  item = goo_demo_large_rect_new (root, CANVAS_LEFT + 10, CANVAS_TOP + 10,
				  CANVAS_RIGHT - CANVAS_LEFT - 20,
				  CANVAS_BOTTOM - CANVAS_TOP - 20,
				  "fill-color", "yellow",
				  NULL);
  g_object_set_data (G_OBJECT (item), "id", "Large Yellow Rect");
#endif

#if 1
  item = goo_demo_large_rect_new (root, CANVAS_LEFT + 100, CANVAS_TOP + 100,
				  CANVAS_RIGHT - CANVAS_LEFT - 200, 50,
				  "fill-color", "orange",
				  NULL);
  g_object_set_data (G_OBJECT (item), "id", "Large Orange Rect");
#endif

#if 1
  item = goo_demo_large_line_new (root, CANVAS_LEFT + 100, CANVAS_TOP + 200,
				  CANVAS_RIGHT - 100, CANVAS_TOP + 200,
				  "stroke-color", "purple",
				  "line-width", 10.0,
				  NULL);
  g_object_set_data (G_OBJECT (item), "id", "Large Purple Line");
#endif

#if 1
  item = goo_demo_large_line_new (root, CANVAS_LEFT + 100, CANVAS_TOP + 300,
				  CANVAS_RIGHT - 100, CANVAS_BOTTOM - 100,
				  "stroke-color", "blue",
				  "line-width", 10.0,
				  NULL);
  g_object_set_data (G_OBJECT (item), "id", "Large Blue Line");
  /*goo_canvas_item_rotate (item, 10, CANVAS_LEFT + 100, CANVAS_TOP + 200);*/
#endif

  goo_canvas_set_bounds (GOO_CANVAS (canvas), CANVAS_LEFT, CANVAS_TOP,
			 CANVAS_RIGHT, CANVAS_BOTTOM);
  gtk_widget_show (canvas);

  /* Zoom */
  w = gtk_label_new ("Zoom:");
  gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
  gtk_widget_show (w);

  adj = GTK_ADJUSTMENT (gtk_adjustment_new (1.00, 0.05, 10.00, 0.05, 0.50, 0.50));
  w = gtk_spin_button_new (adj, 0.0, 2);
  g_signal_connect (adj, "value_changed",
		    (GtkSignalFunc) zoom_changed,
		    canvas);
  gtk_widget_set_size_request (w, 50, -1);
  gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
  gtk_widget_show (w);

  return vbox;
}

--- NEW FILE: demo-large-line.c ---
/*
 * GooCanvas Demo. Copyright (C) 2007 Damon Chaplin.
 * Released under the GNU LGPL license. See COPYING for details.
 *
 * demo-large-line.c - a demo item that exceeds the cairo 16-bit size limit.
 *                     Note that it doesn't support miters.
 */
#include <config.h>
#include "goocanvas.h"
#include "demo-large-line.h"


/* Use the GLib convenience macro to define the type. GooDemoLargeLine is the
   class struct, goo_demo_large_line is the function prefix, and our class is a
   subclass of GOO_TYPE_CANVAS_ITEM_SIMPLE. */
G_DEFINE_TYPE (GooDemoLargeLine, goo_demo_large_line,
	       GOO_TYPE_CANVAS_ITEM_SIMPLE)


/* The standard object initialization function. */
static void
goo_demo_large_line_init (GooDemoLargeLine *demo_large_line)
{
  demo_large_line->x1 = 0.0;
  demo_large_line->y1 = 0.0;
  demo_large_line->x2 = 0.0;
  demo_large_line->y2 = 0.0;
}


/* The convenience function to create new items. This should start with a 
   parent argument and end with a variable list of object properties to fit
   in with the standard canvas items. */
GooCanvasItem*
goo_demo_large_line_new (GooCanvasItem      *parent,
			 gdouble             x1,
			 gdouble             y1,
			 gdouble             x2,
			 gdouble             y2,
			 ...)
{
  GooCanvasItem *item;
  GooDemoLargeLine *demo_large_line;
  const char *first_property;
  va_list var_args;

  item = g_object_new (GOO_TYPE_DEMO_LARGE_LINE, NULL);

  demo_large_line = (GooDemoLargeLine*) item;
  demo_large_line->x1 = x1;
  demo_large_line->y1 = y1;
  demo_large_line->x2 = x2;
  demo_large_line->y2 = y2;

  va_start (var_args, y2);
  first_property = va_arg (var_args, char*);
  if (first_property)
    g_object_set_valist ((GObject*) item, first_property, var_args);
  va_end (var_args);

  if (parent)
    {
      goo_canvas_item_add_child (parent, item, -1);
      g_object_unref (item);
    }

  return item;
}


/* The update method. This is called when the canvas is initially shown and
   also whenever the object is updated and needs to change its size and/or
   shape. It should calculate its new bounds in its own coordinate space,
   storing them in simple->bounds. */
static void
goo_demo_large_line_update  (GooCanvasItemSimple *simple,
			     cairo_t             *cr)
{
  GooDemoLargeLine *item = (GooDemoLargeLine*) simple;
  gdouble half_line_width;

  half_line_width = goo_canvas_item_simple_get_line_width (simple) / 2;

  /* Compute the new bounds. */
  simple->bounds.x1 = MIN (item->x1, item->x2) - half_line_width;
  simple->bounds.y1 = MIN (item->y1, item->y2) - half_line_width;
  simple->bounds.x2 = MAX (item->x1, item->x2) + half_line_width;
  simple->bounds.y2 = MAX (item->y1, item->y2) + half_line_width;
}


static void
clamp_x (gdouble point1[2],
	 gdouble point2[2],
	 gdouble clamp)

{
  gdouble fraction = (clamp - point1[0]) / (point2[0] - point1[0]);
  point1[0] = clamp;
  point1[1] += fraction * (point2[1] - point1[1]);
}


static void
clamp_y (gdouble point1[2],
	 gdouble point2[2],
	 gdouble clamp)

{
  gdouble fraction = (clamp - point1[1]) / (point2[1] - point1[1]);
  point1[1] = clamp;
  point1[0] += fraction * (point2[0] - point1[0]);
}


static void
paint_large_line (GooDemoLargeLine      *line,
		  cairo_t               *cr,
		  const GooCanvasBounds *bounds,
		  gdouble                line_width,
		  gdouble                x1,
		  gdouble                y1,
		  gdouble                x2,
		  gdouble                y2)
{
  GooCanvasItem *item = (GooCanvasItem*) line;
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) line;
  GooCanvas *canvas = simple->canvas;
  GooCanvasBounds tmp_bounds = *bounds;
  gdouble point1[2], point2[2], *p1, *p2;

  point1[0] = x1;
  point1[1] = y1;
  point2[0] = x2;
  point2[1] = y2;

  /* Transform the coordinates to the canvas device space, so we can clamp
     the line to the bounds to be painted. */
  goo_canvas_convert_from_item_space (canvas, item, &point1[0], &point1[1]);
  goo_canvas_convert_from_item_space (canvas, item, &point2[0], &point2[1]);

  /* Extend the bounds a bit to account for the line width. */
  tmp_bounds.x1 -= line_width;
  tmp_bounds.y1 -= line_width;
  tmp_bounds.x2 += line_width;
  tmp_bounds.y2 += line_width;

  /* Make p1 the left-most point. */
  if (point1[0] < point2[0])
    {
      p1 = point1;
      p2 = point2;
    }
  else
    {
      p1 = point2;
      p2 = point1;
    }

  /* Just return if the line is completely outside the bounds horizontally. */
  if (p2[0] < tmp_bounds.x1 || p1[0] > tmp_bounds.x2)
    return;

  /* Clamp each x coordinate to the bounds. */
  if (p1[0] < tmp_bounds.x1)
    clamp_x (p1, p2, tmp_bounds.x1);
  if (p2[0] > tmp_bounds.x2)
    clamp_x (p2, p1, tmp_bounds.x2);

  /* Now make p1 the top-most point. */
  if (point1[1] < point2[1])
    {
      p1 = point1;
      p2 = point2;
    }
  else
    {
      p1 = point2;
      p2 = point1;
    }

  /* Just return if the line is completely outside the bounds vertically. */
  if (p2[1] < tmp_bounds.y1 || p1[1] > tmp_bounds.y2)
    return;

  /* Clamp each y coordinate to the bounds. */
  if (p1[1] < tmp_bounds.y1)
    clamp_y (p1, p2, tmp_bounds.y1);
  if (p2[1] > tmp_bounds.y2)
    clamp_y (p2, p1, tmp_bounds.y2);

  /* Convert back to item space. */
  goo_canvas_convert_to_item_space (canvas, item, &point1[0], &point1[1]);
  goo_canvas_convert_to_item_space (canvas, item, &point2[0], &point2[1]);

  /* Draw the line. */
  cairo_move_to (cr, point1[0], point1[1]);
  cairo_line_to (cr, point2[0], point2[1]);
  cairo_stroke (cr);
}


/* The paint method. This should draw the item on the given cairo_t, using
   the item's own coordinate space. */
static void
goo_demo_large_line_paint (GooCanvasItemSimple   *simple,
			   cairo_t               *cr,
			   const GooCanvasBounds *bounds)
{
  GooDemoLargeLine *item = (GooDemoLargeLine*) simple;
  gdouble line_width;

  goo_canvas_style_set_stroke_options (simple->simple_data->style, cr);
  line_width = goo_canvas_item_simple_get_line_width (simple);
  paint_large_line (item, cr, bounds, line_width,
		    item->x1, item->y1, item->x2, item->y2);
}


/* Hit detection. This should check if the given coordinate (in the item's
   coordinate space) is within the item. If it is it should return TRUE,
   otherwise it should return FALSE. */
static gboolean
goo_demo_large_line_is_item_at (GooCanvasItemSimple *simple,
				gdouble              x,
				gdouble              y,
				cairo_t             *cr,
				gboolean             is_pointer_event)
{
  /*GooDemoLargeLine *item = (GooDemoLargeLine*) simple;*/

  /* FIXME: Implement this. */

  return FALSE;
}


/* The class initialization function. Here we set the class' update(), paint()
   and is_item_at() methods. */
static void
goo_demo_large_line_class_init (GooDemoLargeLineClass *klass)
{
  GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;

  simple_class->simple_update        = goo_demo_large_line_update;
  simple_class->simple_paint         = goo_demo_large_line_paint;
  simple_class->simple_is_item_at    = goo_demo_large_line_is_item_at;
}



--- NEW FILE: demo-large-line.h ---
/*
 * GooCanvas Demo. Copyright (C) 2007 Damon Chaplin.
 * Released under the GNU LGPL license. See COPYING for details.
 *
 * demo-large-line.h - a demo item that exceeds the cairo 16-bit size limit.
 *                     Note that it doesn't support miters.
 */
#ifndef __GOO_DEMO_LARGE_LINE_H__
#define __GOO_DEMO_LARGE_LINE_H__

#include <gtk/gtk.h>
#include "goocanvasitemsimple.h"

G_BEGIN_DECLS


#define GOO_TYPE_DEMO_LARGE_LINE            (goo_demo_large_line_get_type ())
#define GOO_DEMO_LARGE_LINE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_DEMO_LARGE_LINE, GooDemoLargeLine))
#define GOO_DEMO_LARGE_LINE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_DEMO_LARGE_LINE, GooDemoLargeLineClass))
#define GOO_IS_DEMO_LARGE_LINE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_DEMO_LARGE_LINE))
#define GOO_IS_DEMO_LARGE_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_DEMO_LARGE_LINE))
#define GOO_DEMO_LARGE_LINE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_DEMO_LARGE_LINE, GooDemoLargeLineClass))


typedef struct _GooDemoLargeLine       GooDemoLargeLine;
typedef struct _GooDemoLargeLineClass  GooDemoLargeLineClass;

struct _GooDemoLargeLine
{
  GooCanvasItemSimple parent_object;

  gdouble x1, y1, x2, y2;
};

struct _GooDemoLargeLineClass
{
  GooCanvasItemSimpleClass parent_class;
};


GType               goo_demo_large_line_get_type  (void) G_GNUC_CONST;

GooCanvasItem*      goo_demo_large_line_new       (GooCanvasItem      *parent,
						   gdouble             x1,
						   gdouble             y1,
						   gdouble             x2,
						   gdouble             y2,
						   ...);


G_END_DECLS

#endif /* __GOO_DEMO_LARGE_LINE_H__ */

--- NEW FILE: demo-large-rect.c ---
/*
 * GooCanvas Demo. Copyright (C) 2007 Damon Chaplin.
 * Released under the GNU LGPL license. See COPYING for details.
 *
 * demo-large-rect.c - a demo item that exceeds the cairo 16-bit size limit.
 *                     Note that it doesn't support rotations or shears.
 */
#include <config.h>
#include "goocanvas.h"
#include "demo-large-rect.h"


/* Use the GLib convenience macro to define the type. GooDemoLargeRect is the
   class struct, goo_demo_large_rect is the function prefix, and our class is a
   subclass of GOO_TYPE_CANVAS_ITEM_SIMPLE. */
G_DEFINE_TYPE (GooDemoLargeRect, goo_demo_large_rect,
	       GOO_TYPE_CANVAS_ITEM_SIMPLE)


/* The standard object initialization function. */
static void
goo_demo_large_rect_init (GooDemoLargeRect *demo_large_rect)
{
  demo_large_rect->x = 0.0;
  demo_large_rect->y = 0.0;
  demo_large_rect->width = 0.0;
  demo_large_rect->height = 0.0;
}


/* The convenience function to create new items. This should start with a 
   parent argument and end with a variable list of object properties to fit
   in with the standard canvas items. */
GooCanvasItem*
goo_demo_large_rect_new (GooCanvasItem      *parent,
			 gdouble             x,
			 gdouble             y,
			 gdouble             width,
			 gdouble             height,
			 ...)
{
  GooCanvasItem *item;
  GooDemoLargeRect *demo_large_rect;
  const char *first_property;
  va_list var_args;

  item = g_object_new (GOO_TYPE_DEMO_LARGE_RECT, NULL);

  demo_large_rect = (GooDemoLargeRect*) item;
  demo_large_rect->x = x;
  demo_large_rect->y = y;
  demo_large_rect->width = width;
  demo_large_rect->height = height;

  va_start (var_args, height);
  first_property = va_arg (var_args, char*);
  if (first_property)
    g_object_set_valist ((GObject*) item, first_property, var_args);
  va_end (var_args);

  if (parent)
    {
      goo_canvas_item_add_child (parent, item, -1);
      g_object_unref (item);
    }

  return item;
}


/* The update method. This is called when the canvas is initially shown and
   also whenever the object is updated and needs to change its size and/or
   shape. It should calculate its new bounds in its own coordinate space,
   storing them in simple->bounds. */
static void
goo_demo_large_rect_update  (GooCanvasItemSimple *simple,
			     cairo_t             *cr)
{
  GooDemoLargeRect *item = (GooDemoLargeRect*) simple;
  gdouble half_line_width;

  /* We can quickly compute the bounds as being just the rectangle's size
     plus half the line width around each edge. */
  half_line_width = goo_canvas_item_simple_get_line_width (simple) / 2;

  simple->bounds.x1 = item->x - half_line_width;
  simple->bounds.y1 = item->y - half_line_width;
  simple->bounds.x2 = item->x + item->width + half_line_width;
  simple->bounds.y2 = item->y + item->height + half_line_width;
}


static void
create_large_rect_path (GooDemoLargeRect      *rect,
			cairo_t               *cr,
			const GooCanvasBounds *bounds,
			gdouble                line_width,
			gdouble                x,
			gdouble                y,
			gdouble                width,
			gdouble                height)
{
  GooCanvasItem *item = (GooCanvasItem*) rect;
  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) rect;
  GooCanvas *canvas = simple->canvas;
  GooCanvasBounds tmp_bounds = *bounds;
  gdouble x1 = x, y1 = y, x2 = x + width, y2 = y + height;

  /* Transform the coordinates to the canvas device space, so we can clamp
     the line to the bounds to be painted. */
  goo_canvas_convert_from_item_space (canvas, item, &x1, &y1);
  goo_canvas_convert_from_item_space (canvas, item, &x2, &y2);

  /* Extend the bounds a bit to account for the line width, so when we clamp
     the rect to the bounds the outside edges aren't visible. */
  tmp_bounds.x1 -= line_width;
  tmp_bounds.y1 -= line_width;
  tmp_bounds.x2 += line_width;
  tmp_bounds.y2 += line_width;

  /* If the rect is completely outside the bounds just return. */
  if (x1 > tmp_bounds.x2 || x2 < tmp_bounds.x1
      || y1 > tmp_bounds.y2 || y2 < tmp_bounds.y1)
    return;

  /* Clamp the rect to the bounds. */
  if (x1 < tmp_bounds.x1)
    x1 = tmp_bounds.x1;
  if (x2 > tmp_bounds.x2)
    x2 = tmp_bounds.x2;

  if (y1 < tmp_bounds.y1)
    y1 = tmp_bounds.y1;
  if (y2 > tmp_bounds.y2)
    y2 = tmp_bounds.y2;

  /* Convert back to item space. */
  goo_canvas_convert_to_item_space (canvas, item, &x1, &y1);
  goo_canvas_convert_to_item_space (canvas, item, &x2, &y2);

  /* Create the path. */
  cairo_move_to (cr, x1, y1);
  cairo_line_to (cr, x2, y1);
  cairo_line_to (cr, x2, y2);
  cairo_line_to (cr, x1, y2);
  cairo_close_path (cr);
}


/* The paint method. This should draw the item on the given cairo_t, using
   the item's own coordinate space. */
static void
goo_demo_large_rect_paint (GooCanvasItemSimple   *simple,
			   cairo_t               *cr,
			   const GooCanvasBounds *bounds)
{
  GooDemoLargeRect *item = (GooDemoLargeRect*) simple;
  gdouble line_width;

  line_width = goo_canvas_item_simple_get_line_width (simple);
  create_large_rect_path (item, cr, bounds, line_width,
			  item->x, item->y, item->width, item->height);
  goo_canvas_item_simple_paint_path (simple, cr);
}


/* Hit detection. This should check if the given coordinate (in the item's
   coordinate space) is within the item. If it is it should return TRUE,
   otherwise it should return FALSE. */
static gboolean
goo_demo_large_rect_is_item_at (GooCanvasItemSimple *simple,
				gdouble              x,
				gdouble              y,
				cairo_t             *cr,
				gboolean             is_pointer_event)
{
  GooDemoLargeRect *item = (GooDemoLargeRect*) simple;
  gdouble half_line_width;

  /* We assume the item covers its rectangle + line widths. */
  half_line_width = goo_canvas_item_simple_get_line_width (simple) / 2;

  if ((x < item->x - half_line_width)
      || (x > item->x + item->width + half_line_width)
      || (y < item->y - half_line_width)
      || (y > item->y + item->height + half_line_width))
    return FALSE;

  return TRUE;
}


/* The class initialization function. Here we set the class' update(), paint()
   and is_item_at() methods. */
static void
goo_demo_large_rect_class_init (GooDemoLargeRectClass *klass)
{
  GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;

  simple_class->simple_update        = goo_demo_large_rect_update;
  simple_class->simple_paint         = goo_demo_large_rect_paint;
  simple_class->simple_is_item_at    = goo_demo_large_rect_is_item_at;
}



--- NEW FILE: demo-large-rect.h ---
/*
 * GooCanvas Demo. Copyright (C) 2007 Damon Chaplin.
 * Released under the GNU LGPL license. See COPYING for details.
 *
 * demo-large-rect.h - a demo item that exceeds the cairo 16-bit size limit.
 */
#ifndef __GOO_DEMO_LARGE_RECT_H__
#define __GOO_DEMO_LARGE_RECT_H__

#include <gtk/gtk.h>
#include "goocanvasitemsimple.h"

G_BEGIN_DECLS


#define GOO_TYPE_DEMO_LARGE_RECT            (goo_demo_large_rect_get_type ())
#define GOO_DEMO_LARGE_RECT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_DEMO_LARGE_RECT, GooDemoLargeRect))
#define GOO_DEMO_LARGE_RECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_DEMO_LARGE_RECT, GooDemoLargeRectClass))
#define GOO_IS_DEMO_LARGE_RECT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_DEMO_LARGE_RECT))
#define GOO_IS_DEMO_LARGE_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_DEMO_LARGE_RECT))
#define GOO_DEMO_LARGE_RECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_DEMO_LARGE_RECT, GooDemoLargeRectClass))


typedef struct _GooDemoLargeRect       GooDemoLargeRect;
typedef struct _GooDemoLargeRectClass  GooDemoLargeRectClass;

struct _GooDemoLargeRect
{
  GooCanvasItemSimple parent_object;

  gdouble x, y, width, height;
};

struct _GooDemoLargeRectClass
{
  GooCanvasItemSimpleClass parent_class;
};


GType               goo_demo_large_rect_get_type  (void) G_GNUC_CONST;

GooCanvasItem*      goo_demo_large_rect_new       (GooCanvasItem      *parent,
						   gdouble             x,
						   gdouble             y,
						   gdouble             width,
						   gdouble             height,
						   ...);


G_END_DECLS

#endif /* __GOO_DEMO_LARGE_RECT_H__ */

Index: demo-table.c
===================================================================
RCS file: /cvs/cairo/goocanvas/demo/demo-table.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- demo-table.c	6 Mar 2007 12:08:15 -0000	1.2
+++ demo-table.c	11 May 2007 16:30:48 -0000	1.3
@@ -33,7 +33,7 @@
 		  gint           columns,
 		  gchar         *text)
 {
-  GooCanvasItem *item;
+  GooCanvasItem *item = NULL;
   GtkWidget *widget;
 
   switch (demo_item_type)

Index: demo.c
===================================================================
RCS file: /cvs/cairo/goocanvas/demo/demo.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- demo.c	3 Apr 2007 09:58:05 -0000	1.26
+++ demo.c	11 May 2007 16:30:48 -0000	1.27
@@ -34,6 +34,7 @@
 GtkWidget *create_animation_page (void);
 GtkWidget *create_clipping_page (void);
 GtkWidget *create_table_page (void);
+GtkWidget *create_large_items_page (void);
 
 #if CAIRO_HAS_PDF_SURFACE
 static void
@@ -1319,6 +1320,11 @@
 			    create_table_page (),
 			    gtk_label_new ("Table"));
 #endif
+#if 1
+  gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
+			    create_large_items_page (),
+			    gtk_label_new ("Large Items"));
+#endif
 
   return window;
 }

Index: mv-demo-table.c
===================================================================
RCS file: /cvs/cairo/goocanvas/demo/mv-demo-table.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mv-demo-table.c	8 Mar 2007 12:31:59 -0000	1.2
+++ mv-demo-table.c	11 May 2007 16:30:48 -0000	1.3
@@ -33,7 +33,7 @@
 		  gint           columns,
 		  gchar         *text)
 {
-  GooCanvasItemModel *model;
+  GooCanvasItemModel *model = NULL;
   GooCanvasItem *item;
 
   switch (demo_item_type)



More information about the cairo-commit mailing list