[goocanvas/new-api: 3/7] removed cascading style sheets, and used simple style objects instead
- From: Damon Chaplin <damon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goocanvas/new-api: 3/7] removed cascading style sheets, and used simple style objects instead
- Date: Thu, 24 Jun 2010 14:54:32 +0000 (UTC)
commit 99351afa9216330e175658f35c27b21ab9ba6836
Author: Damon Chaplin <damon gnome org>
Date: Thu Jun 24 14:53:14 2010 +0100
removed cascading style sheets, and used simple style objects instead
demo/demo-item.c | 2 +-
demo/demo-large-line.c | 2 +-
demo/demo.c | 14 +-
demo/scalability-demo.c | 155 +++++----
src/goocanvasgrid.c | 8 +-
src/goocanvasgroup.c | 2 -
src/goocanvasimage.c | 2 +-
src/goocanvasitem.c | 40 --
src/goocanvasitem.h | 11 +-
src/goocanvasitemsimple.c | 322 ++++++++---------
src/goocanvasitemsimple.h | 12 +-
src/goocanvaspath.c | 2 +-
src/goocanvaspolyline.c | 6 +-
src/goocanvasstyle.c | 861 +++++++++++++++++++++------------------------
src/goocanvasstyle.h | 88 ++----
src/goocanvastable.c | 9 +-
src/goocanvastext.c | 90 ++++--
src/goocanvasutils.c | 17 +-
18 files changed, 763 insertions(+), 880 deletions(-)
---
diff --git a/demo/demo-item.c b/demo/demo-item.c
index a057a14..027911d 100644
--- a/demo/demo-item.c
+++ b/demo/demo-item.c
@@ -99,7 +99,7 @@ goo_demo_item_paint (GooCanvasItemSimple *simple,
demo_item->y + demo_item->height);
cairo_line_to (cr, demo_item->x + demo_item->width, demo_item->y);
cairo_close_path (cr);
- goo_canvas_style_set_fill_options (simple->style, cr);
+ goo_canvas_item_simple_set_fill_options (simple, cr);
cairo_fill (cr);
}
diff --git a/demo/demo-large-line.c b/demo/demo-large-line.c
index 8f109f5..8b1e9b3 100644
--- a/demo/demo-large-line.c
+++ b/demo/demo-large-line.c
@@ -210,7 +210,7 @@ goo_demo_large_line_paint (GooCanvasItemSimple *simple,
GooDemoLargeLine *item = (GooDemoLargeLine*) simple;
gdouble line_width;
- goo_canvas_style_set_stroke_options (simple->style, cr);
+ goo_canvas_item_simple_set_stroke_options (simple, 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);
diff --git a/demo/demo.c b/demo/demo.c
index 2c44e18..8977309 100644
--- a/demo/demo.c
+++ b/demo/demo.c
@@ -948,16 +948,19 @@ static void
polish_diamond (GooCanvasItem *root)
{
GooCanvasItem *group, *item;
+ GooCanvasStyle *style;
int i, j;
double a, x1, y1, x2, y2;
- group = goo_canvas_group_new (root,
- "line-width", 1.0,
- "line-cap", CAIRO_LINE_CAP_ROUND,
- NULL);
+ group = goo_canvas_group_new (root, NULL);
goo_canvas_item_translate (group, 270, 230);
setup_item_signals (group);
+ style = g_object_new (GOO_TYPE_CANVAS_STYLE,
+ "line-width", 1.0,
+ "line-cap", CAIRO_LINE_CAP_ROUND,
+ NULL);
+
for (i = 0; i < VERTICES; i++) {
a = 2.0 * M_PI * i / VERTICES;
x1 = RADIUS * cos (a);
@@ -968,8 +971,11 @@ polish_diamond (GooCanvasItem *root)
x2 = RADIUS * cos (a);
y2 = RADIUS * sin (a);
item = goo_canvas_polyline_new_line (group, x1, y1, x2, y2, NULL);
+ goo_canvas_item_simple_set_style ((GooCanvasItemSimple*) item, style);
}
}
+
+ g_object_unref (style);
}
diff --git a/demo/scalability-demo.c b/demo/scalability-demo.c
index bbf4a1f..913a996 100644
--- a/demo/scalability-demo.c
+++ b/demo/scalability-demo.c
@@ -1,3 +1,4 @@
+#include <math.h>
#include <stdlib.h>
#include <goocanvas.h>
@@ -47,6 +48,12 @@ double total_width, total_height;
double left_offset, top_offset;
char ids[N_TOTAL_ID_ITEMS][MAX_ID_LEN];
+GdkPixbuf *pixbuf = NULL;
+cairo_pattern_t *pattern = NULL;
+double item_width, item_height;
+double cell_width, cell_height;
+double group_width, group_height;
+
static clock_t start;
static gboolean
@@ -75,72 +82,59 @@ on_motion_notify (GooCanvasItem *item,
static void
+init_ids (void)
+{
+ int group_i, group_j, i, j;
+ int id_item_num = 0;;
+
+ for (group_i = 0; group_i < N_GROUP_COLS; group_i++)
+ {
+ for (group_j = 0; group_j < N_GROUP_ROWS; group_j++)
+ {
+ double group_x = left_offset + (group_i * group_width);
+ double group_y = top_offset + (group_j * group_height);
+
+ for (i = 0; i < N_COLS; i++)
+ {
+ for (j = 0; j < N_ROWS; j++)
+ {
+ double item_x = (i * cell_width) + PADDING;
+ double item_y = (j * cell_height) + PADDING;
+
+ sprintf (ids[id_item_num++], "%.10g, %.10g",
+ group_x + item_x, group_y + item_y);
+ }
+ }
+ }
+ }
+}
+
+
+static void
setup_canvas (GtkWidget *canvas)
{
GooCanvasItem *root, *group, *item;
- GdkPixbuf *pixbuf = NULL;
- cairo_pattern_t *pattern = NULL;
int group_i, group_j, i, j;
- double item_width, item_height;
- double cell_width, cell_height;
- double group_width, group_height;
int total_items = 0, id_item_num = 0;;
- GdkColor color = { 0, 0, 0, 0, };
GooCanvasStyle *style, *style2;
- GValue tmpval = { 0 };
+ PangoFontDescription *font_desc;
+ cairo_matrix_t item_matrix;
+ GQuark id_quark = g_quark_from_static_string ("id");
root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
g_signal_connect (root, "motion_notify_event",
G_CALLBACK (on_motion_notify), NULL);
- g_object_set (G_OBJECT (root),
- "font", "Sans 8",
- NULL);
-
-#ifdef USE_PIXMAP
- pixbuf = gdk_pixbuf_new_from_file("toroid.png", NULL);
- item_width = gdk_pixbuf_get_width (pixbuf);
- item_height = gdk_pixbuf_get_height (pixbuf);
- pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
-#else
- pixbuf = NULL;
- item_width = ITEM_WIDTH;
- item_height = 19;
-#endif
-
- cell_width = item_width + PADDING * 2;
- cell_height = item_height + PADDING * 2;
-
- group_width = N_COLS * cell_width;
- group_height = N_ROWS * cell_height;
-
- total_width = N_GROUP_COLS * group_width;
- total_height = N_GROUP_ROWS * group_height;
+ font_desc = pango_font_description_from_string ("Sans 8");
- /* We use -ve offsets to test if -ve coords are handled correctly. */
- left_offset = -total_width / 2;
- top_offset = -total_height / 2;
+ style = g_object_new (GOO_TYPE_CANVAS_STYLE,
+ "fill-color", "mediumseagreen",
+ NULL);
- style = goo_canvas_style_new ();
- gdk_color_parse ("mediumseagreen", &color);
- pattern = cairo_pattern_create_rgb (color.red / 65535.0,
- color.green / 65535.0,
- color.blue / 65535.0);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, &tmpval);
- g_value_unset (&tmpval);
-
- style2 = goo_canvas_style_new ();
- gdk_color_parse ("steelblue", &color);
- pattern = cairo_pattern_create_rgb (color.red / 65535.0,
- color.green / 65535.0,
- color.blue / 65535.0);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style2, goo_canvas_style_fill_pattern_id, &tmpval);
- g_value_unset (&tmpval);
+ style2 = g_object_new (GOO_TYPE_CANVAS_STYLE,
+ "fill-color", "steelblue",
+ NULL);
for (group_i = 0; group_i < N_GROUP_COLS; group_i++)
{
@@ -160,14 +154,11 @@ setup_canvas (GtkWidget *canvas)
double item_x = (i * cell_width) + PADDING;
double item_y = (j * cell_height) + PADDING;
#ifdef ROTATE
- double rotation = i % 10 * 2;
+ double rotation = (i % 10 * 2) * M_PI / 180;
double rotation_x = item_x + item_width / 2;
double rotation_y = item_y + item_height / 2;
#endif
- sprintf (ids[id_item_num], "%.10g, %.10g",
- group_x + item_x, group_y + item_y);
-
#ifdef USE_PIXMAP
item = goo_canvas_image_new (group, NULL, item_x, item_y,
"pattern", pattern,
@@ -179,15 +170,20 @@ setup_canvas (GtkWidget *canvas)
item_width, item_height,
NULL);
#ifdef SET_STYLE
- goo_canvas_item_set_style (item, (j % 2) ? style : style2);
+ goo_canvas_item_simple_set_style ((GooCanvasItemSimple*) item, (j % 2) ? style : style2);
#endif
#ifdef ROTATE
- goo_canvas_item_rotate (item, rotation, rotation_x, rotation_y);
+ cairo_matrix_init_identity (&item_matrix);
+ cairo_matrix_translate (&item_matrix, rotation_x, rotation_y);
+ cairo_matrix_rotate (&item_matrix, rotation);
+ cairo_matrix_translate (&item_matrix, -rotation_x, -rotation_y);
+ goo_canvas_item_set_transform (item, &item_matrix);
#endif
#endif
- g_object_set_data (G_OBJECT (item), "id",
- ids[id_item_num]);
-
+#if 1
+ g_object_set_qdata (G_OBJECT (item), id_quark,
+ ids[id_item_num]);
+#endif
#if 0
g_signal_connect (item, "motion_notify_event",
G_CALLBACK (on_motion_notify), NULL);
@@ -197,8 +193,14 @@ setup_canvas (GtkWidget *canvas)
item = goo_canvas_text_new (group, ids[id_item_num],
item_x + item_width / 2,
item_y + item_height / 2,
- -1, GTK_ANCHOR_CENTER,
+ item_width, GTK_ANCHOR_CENTER,
+ /*"font-desc", font_desc,*/
+ /*"height", item_height,*/
+ /*"alignment", PANGO_ALIGN_CENTER,*/
NULL);
+ /* FIXME: This is slightly naughty, but much faster. */
+ GOO_CANVAS_TEXT (item)->height = item_height;
+ GOO_CANVAS_TEXT (item)->alignment = PANGO_ALIGN_CENTER;
#else
item = goo_canvas_rect_new (group, item_x + 20, item_y + 4,
item_width - 40, item_height - 8,
@@ -206,8 +208,7 @@ setup_canvas (GtkWidget *canvas)
#endif
#ifdef ROTATE
- goo_canvas_item_rotate (item, rotation, rotation_x,
- rotation_y);
+ goo_canvas_item_set_transform (item, &item_matrix);
#endif
id_item_num++;
total_items += 2;
@@ -259,6 +260,32 @@ create_canvas (void)
{
GtkWidget *canvas;
+#ifdef USE_PIXMAP
+ pixbuf = gdk_pixbuf_new_from_file("toroid.png", NULL);
+ item_width = gdk_pixbuf_get_width (pixbuf);
+ item_height = gdk_pixbuf_get_height (pixbuf);
+ pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
+#else
+ pixbuf = NULL;
+ item_width = ITEM_WIDTH;
+ item_height = 19;
+#endif
+
+ cell_width = item_width + PADDING * 2;
+ cell_height = item_height + PADDING * 2;
+
+ group_width = N_COLS * cell_width;
+ group_height = N_ROWS * cell_height;
+
+ total_width = N_GROUP_COLS * group_width;
+ total_height = N_GROUP_ROWS * group_height;
+
+ /* We use -ve offsets to test if -ve coords are handled correctly. */
+ left_offset = -total_width / 2;
+ top_offset = -total_height / 2;
+
+ init_ids ();
+
/* Create the canvas. */
canvas = goo_canvas_new ();
gtk_widget_set_size_request (canvas, 600, 450);
diff --git a/src/goocanvasgrid.c b/src/goocanvasgrid.c
index 9ecc7f4..54b9542 100644
--- a/src/goocanvasgrid.c
+++ b/src/goocanvasgrid.c
@@ -452,7 +452,7 @@ paint_vertical_lines (GooCanvasItemSimple *simple,
max_x = grid->x + grid->width;
max_y = grid->y + grid->height;
- has_stroke = goo_canvas_style_set_stroke_options (simple->style, cr);
+ has_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
line_width = goo_canvas_item_simple_get_line_width (simple);
/* If the grid's vertical grid line pattern/color has been set, use that.
@@ -512,7 +512,7 @@ paint_horizontal_lines (GooCanvasItemSimple *simple,
max_x = grid->x + grid->width;
max_y = grid->y + grid->height;
- has_stroke = goo_canvas_style_set_stroke_options (simple->style, cr);
+ has_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
line_width = goo_canvas_item_simple_get_line_width (simple);
/* If the grid's horizontal grid line pattern/color has been set, use that.
@@ -567,7 +567,7 @@ goo_canvas_grid_paint (GooCanvasItemSimple *simple,
gdouble half_border_width;
/* Paint the background in the fill pattern/color, if one is set. */
- if (goo_canvas_style_set_fill_options (simple->style, cr))
+ if (goo_canvas_item_simple_set_fill_options (simple, cr))
{
cairo_rectangle (cr, grid->x, grid->y,
grid->width, grid->height);
@@ -605,7 +605,7 @@ goo_canvas_grid_paint (GooCanvasItemSimple *simple,
if (grid->border_pattern)
cairo_set_source (cr, grid->border_pattern);
else
- goo_canvas_style_set_stroke_options (simple->style, cr);
+ goo_canvas_item_simple_set_stroke_options (simple, cr);
cairo_set_line_width (cr, grid->border_width);
half_border_width = grid->border_width / 2.0;
diff --git a/src/goocanvasgroup.c b/src/goocanvasgroup.c
index 66a47fe..87f19de 100644
--- a/src/goocanvasgroup.c
+++ b/src/goocanvasgroup.c
@@ -404,8 +404,6 @@ goo_canvas_group_update (GooCanvasItem *item,
simple->need_update = FALSE;
simple->need_entire_subtree_update = FALSE;
- goo_canvas_item_simple_check_style (simple);
-
simple->bounds.x1 = simple->bounds.y1 = 0.0;
simple->bounds.x2 = simple->bounds.y2 = 0.0;
diff --git a/src/goocanvasimage.c b/src/goocanvasimage.c
index 4164c20..8ef7a33 100644
--- a/src/goocanvasimage.c
+++ b/src/goocanvasimage.c
@@ -279,7 +279,7 @@ goo_canvas_image_paint (GooCanvasItemSimple *simple,
cairo_matrix_translate (&matrix, -image->x, -image->y);
cairo_pattern_set_matrix (image->pattern, &matrix);
- goo_canvas_style_set_fill_options (simple->style, cr);
+ goo_canvas_item_simple_set_fill_options (simple, cr);
cairo_set_source (cr, image->pattern);
cairo_rectangle (cr, image->x, image->y,
image->width, image->height);
diff --git a/src/goocanvasitem.c b/src/goocanvasitem.c
index 805f11d..2599965 100644
--- a/src/goocanvasitem.c
+++ b/src/goocanvasitem.c
@@ -56,8 +56,6 @@ enum {
static guint canvas_item_signals[LAST_SIGNAL] = { 0 };
-extern void _goo_canvas_style_init (void);
-
G_DEFINE_TYPE (GooCanvasItem, goo_canvas_item, G_TYPE_OBJECT)
@@ -429,8 +427,6 @@ goo_canvas_item_class_init (GooCanvasItemClass *klass)
G_TYPE_BOOLEAN, 2,
GOO_TYPE_CANVAS_ITEM,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- _goo_canvas_style_init ();
}
@@ -1108,42 +1104,6 @@ goo_canvas_item_skew_y (GooCanvasItem *item,
}
-/**
- * goo_canvas_item_get_style:
- * @item: an item.
- *
- * Gets the item's style. If the item doesn't have its own style it will return
- * its parent's style.
- *
- * Returns: the item's style.
- **/
-GooCanvasStyle*
-goo_canvas_item_get_style (GooCanvasItem *item)
-{
- GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
-
- return item_class->get_style ? item_class->get_style (item) : NULL;
-}
-
-
-/**
- * goo_canvas_item_set_style:
- * @item: an item.
- * @style: a style.
- *
- * Sets the item's style, by copying the properties from the given style.
- **/
-void
-goo_canvas_item_set_style (GooCanvasItem *item,
- GooCanvasStyle *style)
-{
- GooCanvasItemClass *item_class = GOO_CANVAS_ITEM_GET_CLASS (item);
-
- if (item_class->set_style)
- item_class->set_style (item, style);
-}
-
-
typedef struct _GooCanvasItemAnimation GooCanvasItemAnimation;
struct _GooCanvasItemAnimation
{
diff --git a/src/goocanvasitem.h b/src/goocanvasitem.h
index 25cabdd..de8ee8f 100644
--- a/src/goocanvasitem.h
+++ b/src/goocanvasitem.h
@@ -8,7 +8,6 @@
#define __GOO_CANVAS_ITEM_H__
#include <gtk/gtk.h>
-#include "goocanvasstyle.h"
G_BEGIN_DECLS
@@ -141,8 +140,7 @@ struct _GooCanvasItem
* inside a layout container like #GooCanvasTable).
*
* Items that support transforms should also implement get_transform() and
- * set_transform(). Items that support styles should implement get_style()
- * and set_style().
+ * set_transform().
*
* Container items must implement get_canvas(), set_canvas(),
* get_n_children(), get_child() and request_update(). Containers that support
@@ -226,9 +224,6 @@ struct _GooCanvasItemClass
cairo_matrix_t *transform);
void (* set_transform) (GooCanvasItem *item,
const cairo_matrix_t *transform);
- GooCanvasStyle* (* get_style) (GooCanvasItem *item);
- void (* set_style) (GooCanvasItem *item,
- GooCanvasStyle *style);
gboolean (* is_visible) (GooCanvasItem *item);
gboolean (* get_can_focus) (GooCanvasItem *item);
gdouble (* get_requested_height) (GooCanvasItem *item,
@@ -393,10 +388,6 @@ void goo_canvas_item_skew_y (GooCanvasItem *item,
gdouble cx,
gdouble cy);
-GooCanvasStyle* goo_canvas_item_get_style (GooCanvasItem *item);
-void goo_canvas_item_set_style (GooCanvasItem *item,
- GooCanvasStyle *style);
-
void goo_canvas_item_animate (GooCanvasItem *item,
gdouble x,
gdouble y,
diff --git a/src/goocanvasitemsimple.c b/src/goocanvasitemsimple.c
index 8e48ead..0be1c6f 100644
--- a/src/goocanvasitemsimple.c
+++ b/src/goocanvasitemsimple.c
@@ -135,9 +135,8 @@ goo_canvas_item_simple_get_property (GObject *object,
GParamSpec *pspec)
{
GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
- AtkObject *accessible;
GooCanvasStyle *style = simple->style;
- GValue *svalue;
+ AtkObject *accessible;
gdouble line_width = 2.0;
gchar *font = NULL;
@@ -157,81 +156,62 @@ goo_canvas_item_simple_get_property (GObject *object,
/* Basic drawing properties. */
case PROP_STROKE_PATTERN:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_stroke_pattern_id);
- g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
+ g_value_set_boxed (value, style ? style->stroke_pattern : NULL);
break;
case PROP_FILL_PATTERN:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_pattern_id);
- g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
+ g_value_set_boxed (value, style ? style->fill_pattern : NULL);
break;
case PROP_FILL_RULE:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_rule_id);
- g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_FILL_RULE_WINDING);
+ g_value_set_enum (value, style ? style->fill_rule : CAIRO_FILL_RULE_WINDING);
break;
case PROP_OPERATOR:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_operator_id);
- g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_OPERATOR_OVER);
+ g_value_set_enum (value, style ? style->op : CAIRO_OPERATOR_OVER);
break;
case PROP_ANTIALIAS:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_antialias_id);
- g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_ANTIALIAS_GRAY);
+ g_value_set_enum (value, style ? style->antialias : CAIRO_ANTIALIAS_GRAY);
break;
/* Line style & width properties. */
case PROP_LINE_WIDTH:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_width_id);
- if (svalue)
- line_width = svalue->data[0].v_double;
+ if (style)
+ line_width = style->line_width;
else if (simple->canvas)
line_width = goo_canvas_get_default_line_width (simple->canvas);
g_value_set_double (value, line_width);
break;
case PROP_LINE_CAP:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_cap_id);
- g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_LINE_CAP_BUTT);
+ g_value_set_enum (value, style ? style->line_cap : CAIRO_LINE_CAP_BUTT);
break;
case PROP_LINE_JOIN:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_join_id);
- g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_LINE_JOIN_MITER);
+ g_value_set_enum (value, style ? style->line_join : CAIRO_LINE_JOIN_MITER);
break;
case PROP_LINE_JOIN_MITER_LIMIT:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_join_miter_limit_id);
- g_value_set_double (value, svalue ? svalue->data[0].v_double : 10.0);
+ g_value_set_double (value, style ? style->line_join_miter_limit : 10.0);
break;
case PROP_LINE_DASH:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_line_dash_id);
- g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
+ g_value_set_boxed (value, style ? style->dash : NULL);
break;
/* Font properties. */
case PROP_FONT:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_font_desc_id);
- if (svalue)
- font = pango_font_description_to_string (svalue->data[0].v_pointer);
+ if (style->font_desc)
+ font = pango_font_description_to_string (style->font_desc);
g_value_set_string (value, font);
g_free (font);
break;
case PROP_FONT_DESC:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_font_desc_id);
- g_value_set_boxed (value, svalue ? svalue->data[0].v_pointer : NULL);
+ g_value_set_boxed (value, style ? style->font_desc : NULL);
break;
case PROP_HINT_METRICS:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_hint_metrics_id);
- g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_HINT_METRICS_OFF);
+ g_value_set_enum (value, style->hint_metrics);
break;
/* Convenience properties. */
case PROP_STROKE_COLOR_RGBA:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_stroke_pattern_id);
- if (svalue)
- goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer,
- value);
+ goo_canvas_get_rgba_value_from_pattern (style ? style->stroke_pattern : NULL, value);
break;
case PROP_FILL_COLOR_RGBA:
- svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_pattern_id);
- if (svalue)
- goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer,
- value);
+ goo_canvas_get_rgba_value_from_pattern (style ? style->fill_pattern : NULL, value);
break;
/* Other properties. */
@@ -271,29 +251,20 @@ goo_canvas_item_simple_set_property (GObject *object,
{
GooCanvasItem *item = (GooCanvasItem*) object;
GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasStyle *style;
GooCanvasItem *parent;
AtkObject *accessible;
- GooCanvasStyle *style;
cairo_pattern_t *pattern;
gboolean need_update = TRUE, recompute_bounds = FALSE;
cairo_matrix_t *transform;
- GValue tmpval = { 0 };
const char *font_name;
PangoFontDescription *font_desc = NULL;
- /* See if we need to create our own style. */
+ /* See if we need to create a style. */
if (prop_id < PROP_TRANSFORM)
{
if (!simple->style)
- {
- simple->style = goo_canvas_style_new ();
- }
- else if (!simple->own_style)
- {
- g_object_unref (simple->style);
- simple->style = goo_canvas_style_new ();
- }
- simple->own_style = TRUE;
+ simple->style = goo_canvas_style_new ();
}
style = simple->style;
@@ -319,89 +290,102 @@ goo_canvas_item_simple_set_property (GObject *object,
/* Basic drawing properties. */
case PROP_STROKE_PATTERN:
- goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, value);
+ goo_canvas_style_set_stroke_pattern (style, g_value_get_boxed (value));
break;
case PROP_FILL_PATTERN:
- goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, value);
+ goo_canvas_style_set_fill_pattern (style, g_value_get_boxed (value));
break;
case PROP_FILL_RULE:
- goo_canvas_style_set_property (style, goo_canvas_style_fill_rule_id, value);
+ style->fill_rule = g_value_get_enum (value);
break;
case PROP_OPERATOR:
- goo_canvas_style_set_property (style, goo_canvas_style_operator_id, value);
+ style->op = g_value_get_enum (value);
break;
case PROP_ANTIALIAS:
- goo_canvas_style_set_property (style, goo_canvas_style_antialias_id, value);
+ style->antialias = g_value_get_enum (value);
break;
/* Line style & width properties. */
case PROP_LINE_WIDTH:
- goo_canvas_style_set_property (style, goo_canvas_style_line_width_id, value);
+ style->line_width = g_value_get_double (value);
recompute_bounds = TRUE;
break;
case PROP_LINE_CAP:
- goo_canvas_style_set_property (style, goo_canvas_style_line_cap_id, value);
+ style->line_cap = g_value_get_enum (value);
recompute_bounds = TRUE;
break;
case PROP_LINE_JOIN:
- goo_canvas_style_set_property (style, goo_canvas_style_line_join_id, value);
+ style->line_join = g_value_get_enum (value);
recompute_bounds = TRUE;
break;
case PROP_LINE_JOIN_MITER_LIMIT:
- goo_canvas_style_set_property (style, goo_canvas_style_line_join_miter_limit_id,
- value);
+ style->line_join_miter_limit = g_value_get_double (value);
recompute_bounds = TRUE;
break;
case PROP_LINE_DASH:
- goo_canvas_style_set_property (style, goo_canvas_style_line_dash_id, value);
+ goo_canvas_line_dash_unref (style->dash);
+ style->dash = g_value_get_boxed (value);
+ goo_canvas_line_dash_ref (style->dash);
recompute_bounds = TRUE;
break;
/* Font properties. */
case PROP_FONT:
+ if (style->font_desc)
+ pango_font_description_free (style->font_desc);
font_name = g_value_get_string (value);
if (font_name)
- font_desc = pango_font_description_from_string (font_name);
- g_value_init (&tmpval, PANGO_TYPE_FONT_DESCRIPTION);
- g_value_take_boxed (&tmpval, font_desc);
- goo_canvas_style_set_property (style, goo_canvas_style_font_desc_id, &tmpval);
- g_value_unset (&tmpval);
+ style->font_desc = pango_font_description_from_string (font_name);
+ else
+ style->font_desc = NULL;
recompute_bounds = TRUE;
break;
case PROP_FONT_DESC:
- goo_canvas_style_set_property (style, goo_canvas_style_font_desc_id, value);
+ if (style->font_desc)
+ pango_font_description_free (style->font_desc);
+ font_desc = g_value_get_boxed (value);
+ if (font_desc)
+ style->font_desc = pango_font_description_copy (font_desc);
+ else
+ style->font_desc = NULL;
recompute_bounds = TRUE;
break;
case PROP_HINT_METRICS:
- goo_canvas_style_set_property (style, goo_canvas_style_hint_metrics_id, value);
+ style->hint_metrics = g_value_get_enum (value);
recompute_bounds = TRUE;
break;
/* Convenience properties. */
case PROP_STROKE_COLOR:
pattern = goo_canvas_create_pattern_from_color_value (value);
- goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
+ goo_canvas_style_set_stroke_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
break;
case PROP_STROKE_COLOR_RGBA:
pattern = goo_canvas_create_pattern_from_rgba_value (value);
- goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
+ goo_canvas_style_set_stroke_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
break;
case PROP_STROKE_PIXBUF:
pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
- goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
+ goo_canvas_style_set_stroke_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
break;
case PROP_FILL_COLOR:
pattern = goo_canvas_create_pattern_from_color_value (value);
- goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
+ goo_canvas_style_set_fill_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
break;
case PROP_FILL_COLOR_RGBA:
pattern = goo_canvas_create_pattern_from_rgba_value (value);
- goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
+ goo_canvas_style_set_fill_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
break;
case PROP_FILL_PIXBUF:
pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
- goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
+ goo_canvas_style_set_fill_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
break;
/* Other properties. */
@@ -558,39 +542,6 @@ goo_canvas_item_simple_set_transform (GooCanvasItem *item,
}
-static GooCanvasStyle*
-goo_canvas_item_simple_get_style (GooCanvasItem *item)
-{
- GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-
- return simple->style;
-}
-
-
-static void
-goo_canvas_item_simple_set_style (GooCanvasItem *item,
- GooCanvasStyle *style)
-{
- GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
-
- if (simple->style)
- g_object_unref (simple->style);
-
- if (style)
- {
- simple->style = goo_canvas_style_copy (style);
- simple->own_style = TRUE;
- }
- else
- {
- simple->style = NULL;
- simple->own_style = FALSE;
- }
-
- goo_canvas_item_simple_changed (simple, TRUE);
-}
-
-
static void
goo_canvas_item_simple_get_bounds (GooCanvasItem *item,
GooCanvasBounds *bounds)
@@ -743,44 +694,6 @@ goo_canvas_item_simple_set_is_static (GooCanvasItem *item,
}
-/**
- * goo_canvas_item_simple_check_style:
- * @item: a #GooCanvasItemSimple.
- *
- * This function is intended to be used by subclasses of #GooCanvasItemSimple,
- * typically in their update() or get_requested_area() methods.
- *
- * It ensures that the item's style is setup correctly. If the item has its
- * own #GooCanvasStyle it makes sure the parent is set correctly. If it
- * doesn't have its own style it uses the parent item's style.
- **/
-void
-goo_canvas_item_simple_check_style (GooCanvasItemSimple *simple)
-{
- GooCanvasStyle *parent_style = NULL;
-
- if (simple->parent)
- parent_style = goo_canvas_item_get_style (simple->parent);
-
- if (simple->own_style)
- {
- goo_canvas_style_set_parent (simple->style, parent_style);
- }
- else if (simple->style != parent_style)
- {
- /* The item doesn't have its own style so we use the parent's (though
- that may also be NULL). */
- if (simple->style)
- g_object_unref (simple->style);
-
- simple->style = parent_style;
-
- if (parent_style)
- g_object_ref (parent_style);
- }
-}
-
-
static void
goo_canvas_item_simple_update_internal (GooCanvasItemSimple *simple,
cairo_t *cr)
@@ -791,8 +704,6 @@ goo_canvas_item_simple_update_internal (GooCanvasItemSimple *simple,
simple->need_update = FALSE;
- goo_canvas_item_simple_check_style (simple);
-
cairo_get_matrix (cr, &transform);
class->simple_update (simple, cr);
@@ -1064,12 +975,10 @@ void
goo_canvas_item_simple_paint_path (GooCanvasItemSimple *simple,
cairo_t *cr)
{
- GooCanvasStyle *style = simple->style;
-
- if (goo_canvas_style_set_fill_options (style, cr))
+ if (goo_canvas_item_simple_set_fill_options (simple, cr))
cairo_fill_preserve (cr);
- if (goo_canvas_style_set_stroke_options (style, cr))
+ if (goo_canvas_item_simple_set_stroke_options (simple, cr))
cairo_stroke (cr);
cairo_new_path (cr);
@@ -1102,16 +1011,15 @@ goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *simple,
cairo_t *cr,
GooCanvasBounds *bounds)
{
- GooCanvasStyle *style = simple->style;
GooCanvasBounds fill_bounds, stroke_bounds;
/* Calculate the filled extents. */
- goo_canvas_style_set_fill_options (style, cr);
+ goo_canvas_item_simple_set_fill_options (simple, cr);
cairo_fill_extents (cr, &fill_bounds.x1, &fill_bounds.y1,
&fill_bounds.x2, &fill_bounds.y2);
/* Check the stroke. */
- goo_canvas_style_set_stroke_options (style, cr);
+ goo_canvas_item_simple_set_stroke_options (simple, cr);
cairo_stroke_extents (cr, &stroke_bounds.x1, &stroke_bounds.y1,
&stroke_bounds.x2, &stroke_bounds.y2);
@@ -1293,13 +1201,12 @@ goo_canvas_item_simple_check_in_path (GooCanvasItemSimple *simple,
cairo_t *cr,
GooCanvasPointerEvents pointer_events)
{
- GooCanvasStyle *style = simple->style;
gboolean do_fill, do_stroke;
/* Check the filled path, if required. */
if (pointer_events & GOO_CANVAS_EVENTS_FILL_MASK)
{
- do_fill = goo_canvas_style_set_fill_options (style, cr);
+ do_fill = goo_canvas_item_simple_set_fill_options (simple, cr);
if (!(pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK) || do_fill)
{
if (cairo_in_fill (cr, x, y))
@@ -1310,7 +1217,7 @@ goo_canvas_item_simple_check_in_path (GooCanvasItemSimple *simple,
/* Check the stroke, if required. */
if (pointer_events & GOO_CANVAS_EVENTS_STROKE_MASK)
{
- do_stroke = goo_canvas_style_set_stroke_options (style, cr);
+ do_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
if (!(pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK) || do_stroke)
{
if (cairo_in_stroke (cr, x, y))
@@ -1333,12 +1240,8 @@ goo_canvas_item_simple_check_in_path (GooCanvasItemSimple *simple,
gdouble
goo_canvas_item_simple_get_line_width (GooCanvasItemSimple *simple)
{
- GValue *value;
-
- value = goo_canvas_style_get_property (simple->style,
- goo_canvas_style_line_width_id);
- if (value)
- return value->data[0].v_double;
+ if (simple->style && simple->style->line_width >= 0)
+ return simple->style->line_width;
else if (simple->canvas)
return goo_canvas_get_default_line_width (simple->canvas);
else
@@ -1346,6 +1249,97 @@ goo_canvas_item_simple_get_line_width (GooCanvasItemSimple *simple)
}
+void
+goo_canvas_item_simple_set_style (GooCanvasItemSimple *simple,
+ GooCanvasStyle *style)
+{
+ if (simple->style)
+ g_object_unref (simple->style);
+
+ simple->style = style;
+ if (style)
+ g_object_ref (style);
+
+ goo_canvas_item_simple_changed (simple, TRUE);
+}
+
+
+gboolean
+goo_canvas_item_simple_set_stroke_options (GooCanvasItemSimple *simple,
+ cairo_t *cr)
+{
+ GooCanvasStyle *style = simple->style;
+
+ /* If no style is set, just reset the source to black and return TRUE so the
+ default style will be used. */
+ if (!style)
+ {
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ return TRUE;
+ }
+
+ if (style->stroke_pattern)
+ cairo_set_source (cr, style->stroke_pattern);
+ else
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ if (style->op != CAIRO_OPERATOR_OVER)
+ cairo_set_operator (cr, style->op);
+
+ if (style->antialias != CAIRO_ANTIALIAS_GRAY)
+ cairo_set_antialias (cr, style->antialias);
+
+ if (style->line_width >= 0.0)
+ cairo_set_line_width (cr, style->line_width);
+
+ if (style->line_cap != CAIRO_LINE_CAP_BUTT)
+ cairo_set_line_cap (cr, style->line_cap);
+
+ if (style->line_join != CAIRO_LINE_JOIN_MITER)
+ cairo_set_line_join (cr, style->line_join);
+
+ if (style->line_join_miter_limit != 10.0)
+ cairo_set_miter_limit (cr, style->line_join_miter_limit);
+
+ if (style->dash)
+ cairo_set_dash (cr, style->dash->dashes, style->dash->num_dashes,
+ style->dash->dash_offset);
+
+ /* If the style pattern has been explicitly set to NULL return FALSE, as no
+ stroke is wanted. */
+ if (style->stroke_pattern_set && !style->stroke_pattern)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+gboolean
+goo_canvas_item_simple_set_fill_options (GooCanvasItemSimple *simple,
+ cairo_t *cr)
+{
+ GooCanvasStyle *style = simple->style;
+
+ /* If no style is set, just return FALSE as no fill is needed. */
+ if (!style)
+ return FALSE;
+
+ if (style->fill_pattern)
+ cairo_set_source (cr, style->fill_pattern);
+
+ if (style->op != CAIRO_OPERATOR_OVER)
+ cairo_set_operator (cr, style->op);
+
+ if (style->antialias != CAIRO_ANTIALIAS_GRAY)
+ cairo_set_antialias (cr, style->antialias);
+
+ if (style->fill_rule != CAIRO_FILL_RULE_WINDING)
+ cairo_set_fill_rule (cr, style->fill_rule);
+
+ return style->fill_pattern ? TRUE : FALSE;
+}
+
+
static void
goo_canvas_item_simple_class_init (GooCanvasItemSimpleClass *klass)
{
@@ -1371,8 +1365,6 @@ goo_canvas_item_simple_class_init (GooCanvasItemSimpleClass *klass)
item_class->get_transform = goo_canvas_item_simple_get_transform;
item_class->set_transform = goo_canvas_item_simple_set_transform;
- item_class->get_style = goo_canvas_item_simple_get_style;
- item_class->set_style = goo_canvas_item_simple_set_style;
item_class->is_visible = goo_canvas_item_simple_is_visible;
item_class->get_can_focus = goo_canvas_item_simple_get_can_focus;
item_class->get_is_static = goo_canvas_item_simple_get_is_static;
diff --git a/src/goocanvasitemsimple.h b/src/goocanvasitemsimple.h
index 21f351f..52fc324 100644
--- a/src/goocanvasitemsimple.h
+++ b/src/goocanvasitemsimple.h
@@ -34,7 +34,8 @@ typedef struct _GooCanvasItemSimpleClass GooCanvasItemSimpleClass;
* @bounds: the bounds of the item, in device space.
* @need_update: if the item needs to recompute its bounds and redraw.
* @need_entire_subtree_update: if all descendants need to be updated.
- * @style: the style to draw with.
+ * @pen: the pen to draw the strokes with.
+ * @brush: the brush to fill the items with.
* @transform: the transformation matrix of the item, or %NULL.
* @clip_path_commands: an array of #GooCanvasPathCommand specifying the clip
* path of the item, or %NULL.
@@ -46,7 +47,6 @@ typedef struct _GooCanvasItemSimpleClass GooCanvasItemSimpleClass;
* @pointer_events: the #GooCanvasPointerEvents setting specifying the events
* the item should receive.
* @can_focus: if the item can take the keyboard focus.
- * @own_style: if the item has its own style, rather than using its parent's.
* @clip_fill_rule: the #cairo_fill_rule_t setting specifying the fill rule
* used for the clip path.
* @is_static: if the item is static.
@@ -76,7 +76,6 @@ struct _GooCanvasItemSimple
guint visibility : 2;
guint pointer_events : 4;
guint can_focus : 1;
- guint own_style : 1;
guint clip_fill_rule : 4;
guint is_static : 1;
};
@@ -133,6 +132,8 @@ struct _GooCanvasItemSimpleClass
GType goo_canvas_item_simple_get_type (void) G_GNUC_CONST;
+void goo_canvas_item_simple_set_style (GooCanvasItemSimple *simple,
+ GooCanvasStyle *style);
void goo_canvas_item_simple_get_path_bounds (GooCanvasItemSimple *item,
cairo_t *cr,
@@ -153,9 +154,12 @@ void goo_canvas_item_simple_paint_path (GooCanvasItemSimple *item,
void goo_canvas_item_simple_changed (GooCanvasItemSimple *item,
gboolean recompute_bounds);
-void goo_canvas_item_simple_check_style (GooCanvasItemSimple *item);
gdouble goo_canvas_item_simple_get_line_width (GooCanvasItemSimple *item);
+gboolean goo_canvas_item_simple_set_stroke_options (GooCanvasItemSimple *simple,
+ cairo_t *cr);
+gboolean goo_canvas_item_simple_set_fill_options (GooCanvasItemSimple *simple,
+ cairo_t *cr);
G_END_DECLS
diff --git a/src/goocanvaspath.c b/src/goocanvaspath.c
index 801360c..ff1a5d5 100644
--- a/src/goocanvaspath.c
+++ b/src/goocanvaspath.c
@@ -447,7 +447,7 @@ goo_canvas_path_is_item_at (GooCanvasItemSimple *simple,
gboolean do_fill;
/* By default only check the fill if a fill color/pattern is specified. */
- do_fill = goo_canvas_style_set_fill_options (simple->style, cr);
+ do_fill = goo_canvas_item_simple_set_fill_options (simple, cr);
if (!do_fill)
pointer_events &= ~GOO_CANVAS_EVENTS_FILL_MASK;
diff --git a/src/goocanvaspolyline.c b/src/goocanvaspolyline.c
index bd0dd11..08ba072 100644
--- a/src/goocanvaspolyline.c
+++ b/src/goocanvaspolyline.c
@@ -777,7 +777,7 @@ goo_canvas_polyline_is_item_at (GooCanvasItemSimple *simple,
&& (pointer_events & GOO_CANVAS_EVENTS_STROKE_MASK))
{
/* We use the stroke pattern to match the style of the line. */
- do_stroke = goo_canvas_style_set_stroke_options (simple->style, cr);
+ do_stroke = goo_canvas_item_simple_set_stroke_options (simple, cr);
if (!(pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK) || do_stroke)
{
if (polyline->start_arrow)
@@ -827,7 +827,7 @@ goo_canvas_polyline_compute_bounds (GooCanvasPolyline *polyline,
&& polyline->num_points >= 2)
{
/* We use the stroke pattern to match the style of the line. */
- goo_canvas_style_set_stroke_options (simple->style, cr);
+ goo_canvas_item_simple_set_stroke_options (simple, cr);
if (polyline->start_arrow)
{
@@ -887,7 +887,7 @@ goo_canvas_polyline_paint (GooCanvasItemSimple *simple,
&& polyline->num_points >= 2)
{
/* We use the stroke pattern to match the style of the line. */
- goo_canvas_style_set_stroke_options (simple->style, cr);
+ goo_canvas_item_simple_set_stroke_options (simple, cr);
if (polyline->start_arrow)
{
diff --git a/src/goocanvasstyle.c b/src/goocanvasstyle.c
index 6ca878d..4d6f01e 100644
--- a/src/goocanvasstyle.c
+++ b/src/goocanvasstyle.c
@@ -1,542 +1,465 @@
/*
- * GooCanvas. Copyright (C) 2005-6 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005-2010 Damon Chaplin.
* Released under the GNU LGPL license. See COPYING for details.
*
- * goocanvasstyle.c - cascading styles.
- */
-
-/**
- * SECTION:goocanvasstyle
- * @Title: GooCanvasStyle
- * @Short_Description: support for cascading style properties for canvas items.
- *
- * #GooCanvasStyle provides support for cascading style properties for canvas
- * items. It is intended to be used when implementing new canvas items.
- *
- * Style properties are identified by a unique #GQuark, and contain
- * arbitrary data stored in a #GValue.
- *
- * #GooCanvasStyle also provides a few convenience functions such as
- * goo_canvas_style_set_stroke_options() and
- * goo_canvas_style_set_fill_options() which efficiently apply an item's
- * standard style properties to the given cairo_t.
+ * goocanvasstyle.c -
*/
#include <config.h>
+#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include "goocanvasstyle.h"
-#include "goocanvasutils.h"
-
-/* GQuarks for the basic properties. */
-
-/**
- * goo_canvas_style_stroke_pattern_id:
- *
- * Unique #GQuark identifier used for the standard stroke pattern property.
- **/
-GQuark goo_canvas_style_stroke_pattern_id;
-
-/**
- * goo_canvas_style_fill_pattern_id:
- *
- * Unique #GQuark identifier used for the standard fill pattern property.
- **/
-GQuark goo_canvas_style_fill_pattern_id;
-
-/**
- * goo_canvas_style_fill_rule_id:
- *
- * Unique #GQuark identifier used for the standard fill rule property.
- **/
-GQuark goo_canvas_style_fill_rule_id;
-
-/**
- * goo_canvas_style_operator_id:
- *
- * Unique #GQuark identifier used for the standard operator property.
- **/
-GQuark goo_canvas_style_operator_id;
-
-/**
- * goo_canvas_style_antialias_id:
- *
- * Unique #GQuark identifier used for the standard antialias property.
- **/
-GQuark goo_canvas_style_antialias_id;
-
-/**
- * goo_canvas_style_line_width_id:
- *
- * Unique #GQuark identifier used for the standard line width property.
- **/
-GQuark goo_canvas_style_line_width_id;
-
-/**
- * goo_canvas_style_line_cap_id:
- *
- * Unique #GQuark identifier used for the standard line cap property.
- **/
-GQuark goo_canvas_style_line_cap_id;
-
-/**
- * goo_canvas_style_line_join_id:
- *
- * Unique #GQuark identifier used for the standard line join property.
- **/
-GQuark goo_canvas_style_line_join_id;
-
-/**
- * goo_canvas_style_line_join_miter_limit_id:
- *
- * Unique #GQuark identifier used for the standard miter limit property.
- **/
-GQuark goo_canvas_style_line_join_miter_limit_id;
-
-/**
- * goo_canvas_style_line_dash_id:
- *
- * Unique #GQuark identifier used for the standard line dash property.
- **/
-GQuark goo_canvas_style_line_dash_id;
-
-/**
- * goo_canvas_style_font_desc_id:
- *
- * Unique #GQuark identifier used for the standard font description property.
- **/
-GQuark goo_canvas_style_font_desc_id;
-
-/**
- * goo_canvas_style_hint_metrics_id:
- *
- * Unique #GQuark identifier used for the standard hint metrics property.
- **/
-GQuark goo_canvas_style_hint_metrics_id;
-
-static void goo_canvas_style_dispose (GObject *object);
-static void goo_canvas_style_finalize (GObject *object);
+#include "goocanvasprivate.h"
+
G_DEFINE_TYPE (GooCanvasStyle, goo_canvas_style, G_TYPE_OBJECT)
-/* Create GQuarks for the basic properties. This is called by
- goo_canvas_style_class_init(), goo_canvas_item_base_init() and
- goo_canvas_item_model_base_init() to try to ensure the GQuarks are
- initialized before they are needed. */
-void
-_goo_canvas_style_init (void)
-{
- static gboolean initialized = FALSE;
-
- if (!initialized)
- {
- goo_canvas_style_stroke_pattern_id = g_quark_from_static_string ("GooCanvasStyle:stroke_pattern");
- goo_canvas_style_fill_pattern_id = g_quark_from_static_string ("GooCanvasStyle:fill_pattern");
- goo_canvas_style_fill_rule_id = g_quark_from_static_string ("GooCanvasStyle:fill_rule");
- goo_canvas_style_operator_id = g_quark_from_static_string ("GooCanvasStyle:operator");
- goo_canvas_style_antialias_id = g_quark_from_static_string ("GooCanvasStyle:antialias");
- goo_canvas_style_line_width_id = g_quark_from_static_string ("GooCanvasStyle:line_width");
- goo_canvas_style_line_cap_id = g_quark_from_static_string ("GooCanvasStyle:line_cap");
- goo_canvas_style_line_join_id = g_quark_from_static_string ("GooCanvasStyle:line_join");
- goo_canvas_style_line_join_miter_limit_id = g_quark_from_static_string ("GooCanvasStyle:line_join_miter_limit");
- goo_canvas_style_line_dash_id = g_quark_from_static_string ("GooCanvasStyle:line_dash");
- goo_canvas_style_font_desc_id = g_quark_from_static_string ("GooCanvasStyle:font_desc");
- goo_canvas_style_hint_metrics_id = g_quark_from_static_string ("GooCanvasStyle:hint_metrics");
-
- initialized = TRUE;
- }
-}
+enum {
+ PROP_0,
+ /* Basic drawing properties. */
+ PROP_STROKE_PATTERN,
+ PROP_FILL_PATTERN,
+ PROP_FILL_RULE,
+ PROP_OPERATOR,
+ PROP_ANTIALIAS,
-static void
-goo_canvas_style_class_init (GooCanvasStyleClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*) klass;
+ /* Line style & width properties. */
+ PROP_LINE_WIDTH,
+ PROP_LINE_CAP,
+ PROP_LINE_JOIN,
+ PROP_LINE_JOIN_MITER_LIMIT,
+ PROP_LINE_DASH,
- gobject_class->dispose = goo_canvas_style_dispose;
- gobject_class->finalize = goo_canvas_style_finalize;
+ /* Font properties. */
+ PROP_FONT,
+ PROP_FONT_DESC,
+ PROP_HINT_METRICS,
- _goo_canvas_style_init ();
-}
+ /* Convenience properties. */
+ PROP_STROKE_COLOR,
+ PROP_STROKE_COLOR_RGBA,
+ PROP_STROKE_PIXBUF,
+ PROP_FILL_COLOR,
+ PROP_FILL_COLOR_RGBA,
+ PROP_FILL_PIXBUF
+};
static void
goo_canvas_style_init (GooCanvasStyle *style)
{
- style->properties = g_array_new (0, 0, sizeof (GooCanvasStyleProperty));
+ style->stroke_pattern = NULL;
+ style->fill_pattern = NULL;
+
+ style->dash = NULL;
+ style->font_desc = NULL;
+
+ style->line_width = -1.0;
+ style->line_join_miter_limit = 10.0;
+
+ style->stroke_pattern_set = FALSE;
+ style->fill_pattern_set = FALSE;
+ style->op = CAIRO_OPERATOR_OVER;
+ style->antialias = CAIRO_ANTIALIAS_GRAY;
+ style->fill_rule = CAIRO_FILL_RULE_WINDING;
+ style->line_cap = CAIRO_LINE_CAP_BUTT;
+ style->line_join = CAIRO_LINE_JOIN_MITER;
+ style->hint_metrics = CAIRO_HINT_METRICS_OFF;
}
-/**
- * goo_canvas_style_new:
- *
- * Creates a new #GooCanvasStyle.
- *
- * Returns: a new #GooCanvasStyle.
- **/
GooCanvasStyle*
goo_canvas_style_new (void)
{
- return GOO_CANVAS_STYLE (g_object_new (GOO_TYPE_CANVAS_STYLE, NULL));
+ return g_object_new (GOO_TYPE_CANVAS_STYLE, NULL);
}
static void
-goo_canvas_style_dispose (GObject *object)
+goo_canvas_style_finalize (GObject *object)
{
GooCanvasStyle *style = (GooCanvasStyle*) object;
- GooCanvasStyleProperty *property;
- gint i;
- if (style->parent)
+ cairo_pattern_destroy (style->stroke_pattern);
+ cairo_pattern_destroy (style->fill_pattern);
+
+ if (style->dash)
{
- g_object_unref (style->parent);
- style->parent = NULL;
+ goo_canvas_line_dash_unref (style->dash);
+ style->dash = NULL;
}
- /* Free the property GValues. */
- for (i = 0; i < style->properties->len; i++)
+ if (style->font_desc)
{
- property = &g_array_index (style->properties, GooCanvasStyleProperty, i);
- g_value_unset (&property->value);
+ pango_font_description_free (style->font_desc);
+ style->font_desc = NULL;
}
- g_array_set_size (style->properties, 0);
- G_OBJECT_CLASS (goo_canvas_style_parent_class)->dispose (object);
+ G_OBJECT_CLASS (goo_canvas_style_parent_class)->finalize (object);
}
static void
-goo_canvas_style_finalize (GObject *object)
+goo_canvas_style_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GooCanvasStyle *style = (GooCanvasStyle*) object;
+ gchar *font = NULL;
- g_array_free (style->properties, TRUE);
-
- G_OBJECT_CLASS (goo_canvas_style_parent_class)->finalize (object);
-}
-
-
-/**
- * goo_canvas_style_copy:
- * @style: a #GooCanvasStyle.
- *
- * Copies the given #GooCanvasStyle, by copying all of its properties.
- * Though the parent of the new style is left unset.
- *
- * Returns: a copy of the given #GooCanvasStyle.
- **/
-GooCanvasStyle*
-goo_canvas_style_copy (GooCanvasStyle *style)
-{
- GooCanvasStyle *copy;
- GooCanvasStyleProperty *property;
- gint i;
-
- copy = goo_canvas_style_new ();
-
- for (i = 0; i < style->properties->len; i++)
+ switch (prop_id)
{
- property = &g_array_index (style->properties, GooCanvasStyleProperty, i);
- goo_canvas_style_set_property (copy, property->id, &property->value);
+ /* Basic drawing properties. */
+ case PROP_STROKE_PATTERN:
+ g_value_set_boxed (value, style->stroke_pattern);
+ break;
+ case PROP_FILL_PATTERN:
+ g_value_set_boxed (value, style->fill_pattern);
+ break;
+ case PROP_FILL_RULE:
+ g_value_set_enum (value, style->fill_rule);
+ break;
+ case PROP_OPERATOR:
+ g_value_set_enum (value, style->op);
+ break;
+ case PROP_ANTIALIAS:
+ g_value_set_enum (value, style->antialias);
+ break;
+
+ /* Line style & width properties. */
+ case PROP_LINE_WIDTH:
+ g_value_set_double (value, style->line_width);
+ break;
+ case PROP_LINE_CAP:
+ g_value_set_enum (value, style->line_cap);
+ break;
+ case PROP_LINE_JOIN:
+ g_value_set_enum (value, style->line_join);
+ break;
+ case PROP_LINE_JOIN_MITER_LIMIT:
+ g_value_set_double (value, style->line_join_miter_limit);
+ break;
+ case PROP_LINE_DASH:
+ g_value_set_boxed (value, style->dash);
+ break;
+
+ /* Font properties. */
+ case PROP_FONT:
+ if (style->font_desc)
+ font = pango_font_description_to_string (style->font_desc);
+ g_value_set_string (value, font);
+ g_free (font);
+ break;
+ case PROP_FONT_DESC:
+ g_value_set_boxed (value, style->font_desc);
+ break;
+ case PROP_HINT_METRICS:
+ g_value_set_enum (value, style->hint_metrics);
+ break;
+
+ /* Convenience properties. */
+ case PROP_STROKE_COLOR_RGBA:
+ goo_canvas_get_rgba_value_from_pattern (style->stroke_pattern, value);
+ break;
+ case PROP_FILL_COLOR_RGBA:
+ goo_canvas_get_rgba_value_from_pattern (style->fill_pattern, value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
-
- return copy;
-}
-
-
-/**
- * goo_canvas_style_get_parent:
- * @style: a style.
- *
- * Gets the parent of the style.
- *
- * Returns: the parent of the given style, or %NULL.
- **/
-GooCanvasStyle*
-goo_canvas_style_get_parent (GooCanvasStyle *style)
-{
- return style->parent;
}
-/**
- * goo_canvas_style_set_parent:
- * @style: a style.
- * @parent: the new parent.
- *
- * Sets the parent of the style.
- **/
void
-goo_canvas_style_set_parent (GooCanvasStyle *style,
- GooCanvasStyle *parent)
+goo_canvas_style_set_stroke_pattern (GooCanvasStyle *style,
+ cairo_pattern_t *pattern)
{
- if (style->parent == parent)
- return;
-
- if (style->parent)
- g_object_unref (style->parent);
-
- style->parent = parent;
-
- if (style->parent)
- g_object_ref (style->parent);
+ cairo_pattern_destroy (style->stroke_pattern);
+ style->stroke_pattern = pattern;
+ cairo_pattern_reference (style->stroke_pattern);
+ style->stroke_pattern_set = TRUE;
}
-/**
- * goo_canvas_style_get_property:
- * @style: a style.
- * @property_id: the property identifier.
- *
- * Gets the value of a property.
- *
- * This searches though all the #GooCanvasStyle's own list of property settings
- * and also all ancestor #GooCanvasStyle objects.
- *
- * Note that it returns a pointer to the internal #GValue setting, which should
- * not be changed.
- *
- * Returns: the property value, or %NULL if it isn't set.
- **/
-GValue*
-goo_canvas_style_get_property (GooCanvasStyle *style,
- GQuark property_id)
+void
+goo_canvas_style_set_fill_pattern (GooCanvasStyle *style,
+ cairo_pattern_t *pattern)
{
- GooCanvasStyleProperty *property;
- gint i;
-
- /* Step up the hierarchy of styles until we find the property. Note that
- if style is passed in as NULL we simply return NULL. */
- while (style)
- {
- for (i = 0; i < style->properties->len; i++)
- {
- property = &g_array_index (style->properties, GooCanvasStyleProperty,
- i);
- if (property->id == property_id)
- return &property->value;
- }
-
- style = style->parent;
- }
-
- return NULL;
+ cairo_pattern_destroy (style->fill_pattern);
+ style->fill_pattern = pattern;
+ cairo_pattern_reference (style->fill_pattern);
+ style->fill_pattern_set = TRUE;
}
-/**
- * goo_canvas_style_set_property:
- * @style: a style.
- * @property_id: the property identifier.
- * @value: the value of the property.
- *
- * Sets a property in the style, replacing any current setting.
- *
- * Note that this will override the property setting in ancestor
- * #GooCanvasStyle objects.
- **/
-void
-goo_canvas_style_set_property (GooCanvasStyle *style,
- GQuark property_id,
- const GValue *value)
+static void
+goo_canvas_style_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GooCanvasStyleProperty *property, new_property = { 0 };
- gint i;
-
- /* See if the property is already set. */
- for (i = 0; i < style->properties->len; i++)
- {
- property = &g_array_index (style->properties, GooCanvasStyleProperty, i);
- if (property->id == property_id)
- {
- /* If the new value is NULL, remove the property setting, otherwise
- update the property value. */
- if (value)
- {
- g_value_copy (value, &property->value);
- }
- else
- {
- g_value_unset (&property->value);
- g_array_remove_index_fast (style->properties, i);
- }
-
- return;
- }
- }
+ GooCanvasStyle *style = (GooCanvasStyle*) object;
+ cairo_pattern_t *pattern;
+ const char *font_name;
+ PangoFontDescription *font_desc = NULL;
- /* The property isn't set, so append a new property. */
- if (value)
+ switch (prop_id)
{
- new_property.id = property_id;
- g_value_init (&new_property.value, G_VALUE_TYPE (value));
- g_value_copy (value, &new_property.value);
- g_array_append_val (style->properties, new_property);
+ /* Basic drawing properties. */
+ case PROP_STROKE_PATTERN:
+ goo_canvas_style_set_stroke_pattern (style, g_value_get_boxed (value));
+ break;
+ case PROP_FILL_PATTERN:
+ goo_canvas_style_set_fill_pattern (style, g_value_get_boxed (value));
+ break;
+ case PROP_FILL_RULE:
+ style->fill_rule = g_value_get_enum (value);
+ break;
+ case PROP_OPERATOR:
+ style->op = g_value_get_enum (value);
+ break;
+ case PROP_ANTIALIAS:
+ style->antialias = g_value_get_enum (value);
+ break;
+
+ /* Line style & width properties. */
+ case PROP_LINE_WIDTH:
+ style->line_width = g_value_get_double (value);
+ break;
+ case PROP_LINE_CAP:
+ style->line_cap = g_value_get_enum (value);
+ break;
+ case PROP_LINE_JOIN:
+ style->line_join = g_value_get_enum (value);
+ break;
+ case PROP_LINE_JOIN_MITER_LIMIT:
+ style->line_join_miter_limit = g_value_get_double (value);
+ break;
+ case PROP_LINE_DASH:
+ goo_canvas_line_dash_unref (style->dash);
+ style->dash = g_value_get_boxed (value);
+ goo_canvas_line_dash_ref (style->dash);
+ break;
+
+ /* Font properties. */
+ case PROP_FONT:
+ if (style->font_desc)
+ pango_font_description_free (style->font_desc);
+ font_name = g_value_get_string (value);
+ if (font_name)
+ style->font_desc = pango_font_description_from_string (font_name);
+ else
+ style->font_desc = NULL;
+ break;
+ case PROP_FONT_DESC:
+ if (style->font_desc)
+ pango_font_description_free (style->font_desc);
+ font_desc = g_value_get_boxed (value);
+ if (font_desc)
+ style->font_desc = pango_font_description_copy (font_desc);
+ else
+ style->font_desc = NULL;
+ break;
+ case PROP_HINT_METRICS:
+ style->hint_metrics = g_value_get_enum (value);
+ break;
+
+ /* Convenience properties. */
+ case PROP_STROKE_COLOR:
+ pattern = goo_canvas_create_pattern_from_color_value (value);
+ goo_canvas_style_set_stroke_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
+ break;
+ case PROP_STROKE_COLOR_RGBA:
+ pattern = goo_canvas_create_pattern_from_rgba_value (value);
+ goo_canvas_style_set_stroke_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
+ break;
+ case PROP_STROKE_PIXBUF:
+ pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
+ goo_canvas_style_set_stroke_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
+ break;
+
+ case PROP_FILL_COLOR:
+ pattern = goo_canvas_create_pattern_from_color_value (value);
+ goo_canvas_style_set_fill_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
+ break;
+ case PROP_FILL_COLOR_RGBA:
+ pattern = goo_canvas_create_pattern_from_rgba_value (value);
+ goo_canvas_style_set_fill_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
+ break;
+ case PROP_FILL_PIXBUF:
+ pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
+ goo_canvas_style_set_fill_pattern (style, pattern);
+ cairo_pattern_destroy (pattern);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
}
-/**
- * goo_canvas_style_set_stroke_options:
- * @style: a style.
- * @cr: a cairo context.
- *
- * Sets the standard cairo stroke options using the given style.
- *
- * Returns: %TRUE if a paint source is set, or %FALSE if the stroke should
- * be skipped.
- **/
-gboolean
-goo_canvas_style_set_stroke_options (GooCanvasStyle *style,
- cairo_t *cr)
+static void
+goo_canvas_style_class_init (GooCanvasStyleClass *klass)
{
- GooCanvasStyleProperty *property;
- gboolean operator_set = FALSE, antialias_set = FALSE;
- gboolean stroke_pattern_set = FALSE, line_width_set = FALSE;
- gboolean line_cap_set = FALSE, line_join_set = FALSE;
- gboolean miter_limit_set = FALSE, line_dash_set = FALSE;
- gboolean source_set = FALSE, need_stroke = TRUE;
- gint i;
-
- if (!style)
- return TRUE;
-
- /* Step up the hierarchy of styles looking for the properties. */
- while (style)
- {
- for (i = 0; i < style->properties->len; i++)
- {
- property = &g_array_index (style->properties, GooCanvasStyleProperty,
- i);
-
- if (property->id == goo_canvas_style_operator_id && !operator_set)
- {
- cairo_set_operator (cr, property->value.data[0].v_long);
- operator_set = TRUE;
- }
- else if (property->id == goo_canvas_style_antialias_id && !antialias_set)
- {
- cairo_set_antialias (cr, property->value.data[0].v_long);
- antialias_set = TRUE;
- }
- else if (property->id == goo_canvas_style_stroke_pattern_id && !stroke_pattern_set)
- {
- if (property->value.data[0].v_pointer)
- {
- cairo_set_source (cr, property->value.data[0].v_pointer);
- source_set = TRUE;
- }
- else
- {
- /* If the stroke pattern has been explicitly set to NULL,
- then we don't need to do the stroke. */
- need_stroke = FALSE;
- }
- stroke_pattern_set = TRUE;
- }
- else if (property->id == goo_canvas_style_line_width_id && !line_width_set)
- {
- cairo_set_line_width (cr, property->value.data[0].v_double);
- line_width_set = TRUE;
- }
- else if (property->id == goo_canvas_style_line_cap_id && !line_cap_set)
- {
- cairo_set_line_cap (cr, property->value.data[0].v_long);
- line_cap_set = TRUE;
- }
- else if (property->id == goo_canvas_style_line_join_id && !line_join_set)
- {
- cairo_set_line_join (cr, property->value.data[0].v_long);
- line_join_set = TRUE;
- }
- else if (property->id == goo_canvas_style_line_join_miter_limit_id && !miter_limit_set)
- {
- cairo_set_miter_limit (cr, property->value.data[0].v_double);
- miter_limit_set = TRUE;
- }
- else if (property->id == goo_canvas_style_line_dash_id && !line_dash_set)
- {
- GooCanvasLineDash *dash = property->value.data[0].v_pointer;
- if (dash)
- cairo_set_dash (cr, dash->dashes, dash->num_dashes,
- dash->dash_offset);
- else
- cairo_set_dash (cr, NULL, 0, 0);
- line_dash_set = TRUE;
- }
- }
-
- style = style->parent;
- }
+ GObjectClass *gobject_class = (GObjectClass*) klass;
- /* If a stroke pattern hasn't been set in the style we reset the source to
- black, just in case a fill pattern was used for the item. */
- if (!source_set)
- cairo_set_source_rgb (cr, 0, 0, 0);
+ gobject_class->finalize = goo_canvas_style_finalize;
- return need_stroke;
+ gobject_class->get_property = goo_canvas_style_get_property;
+ gobject_class->set_property = goo_canvas_style_set_property;
+
+ /* Basic drawing properties. */
+ g_object_class_install_property (gobject_class, PROP_STROKE_PATTERN,
+ g_param_spec_boxed ("stroke-pattern",
+ _("Stroke Pattern"),
+ _("The pattern to use to paint the perimeter of the item, or NULL disable painting"),
+ GOO_TYPE_CAIRO_PATTERN,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_FILL_PATTERN,
+ g_param_spec_boxed ("fill-pattern",
+ _("Fill Pattern"),
+ _("The pattern to use to paint the interior of the item, or NULL to disable painting"),
+ GOO_TYPE_CAIRO_PATTERN,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_FILL_RULE,
+ g_param_spec_enum ("fill-rule",
+ _("Fill Rule"),
+ _("The fill rule used to determine which parts of the item are filled"),
+ GOO_TYPE_CAIRO_FILL_RULE,
+ CAIRO_FILL_RULE_WINDING,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_OPERATOR,
+ g_param_spec_enum ("operator",
+ _("Operator"),
+ _("The compositing operator to use"),
+ GOO_TYPE_CAIRO_OPERATOR,
+ CAIRO_OPERATOR_OVER,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_ANTIALIAS,
+ g_param_spec_enum ("antialias",
+ _("Antialias"),
+ _("The antialiasing mode to use"),
+ GOO_TYPE_CAIRO_ANTIALIAS,
+ CAIRO_ANTIALIAS_GRAY,
+ G_PARAM_READWRITE));
+
+ /* Line style & width properties. */
+ g_object_class_install_property (gobject_class, PROP_LINE_WIDTH,
+ g_param_spec_double ("line-width",
+ _("Line Width"),
+ _("The line width to use for the item's perimeter"),
+ 0.0, G_MAXDOUBLE, 2.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_LINE_CAP,
+ g_param_spec_enum ("line-cap",
+ _("Line Cap"),
+ _("The line cap style to use"),
+ GOO_TYPE_CAIRO_LINE_CAP,
+ CAIRO_LINE_CAP_BUTT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_LINE_JOIN,
+ g_param_spec_enum ("line-join",
+ _("Line Join"),
+ _("The line join style to use"),
+ GOO_TYPE_CAIRO_LINE_JOIN,
+ CAIRO_LINE_JOIN_MITER,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_LINE_JOIN_MITER_LIMIT,
+ g_param_spec_double ("line-join-miter-limit",
+ _("Miter Limit"),
+ _("The smallest angle to use with miter joins, in degrees. Bevel joins will be used below this limit"),
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_LINE_DASH,
+ g_param_spec_boxed ("line-dash",
+ _("Line Dash"),
+ _("The dash pattern to use"),
+ GOO_TYPE_CANVAS_LINE_DASH,
+ G_PARAM_READWRITE));
+
+ /* Font properties. */
+ g_object_class_install_property (gobject_class, PROP_FONT,
+ g_param_spec_string ("font",
+ _("Font"),
+ _("The base font to use for the text"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_FONT_DESC,
+ g_param_spec_boxed ("font-desc",
+ _("Font Description"),
+ _("The attributes specifying which font to use"),
+ PANGO_TYPE_FONT_DESCRIPTION,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_HINT_METRICS,
+ g_param_spec_enum ("hint-metrics",
+ _("Hint Metrics"),
+ _("The hinting to be used for font metrics"),
+ GOO_TYPE_CAIRO_HINT_METRICS,
+ CAIRO_HINT_METRICS_OFF,
+ G_PARAM_READWRITE));
+
+ /* Convenience properties - writable only. */
+ g_object_class_install_property (gobject_class, PROP_STROKE_COLOR,
+ g_param_spec_string ("stroke-color",
+ _("Stroke Color"),
+ _("The color to use for the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
+ NULL,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_STROKE_COLOR_RGBA,
+ g_param_spec_uint ("stroke-color-rgba",
+ _("Stroke Color RGBA"),
+ _("The color to use for the item's perimeter, specified as a 32-bit integer value. To disable painting set the 'stroke-pattern' property to NULL"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_STROKE_PIXBUF,
+ g_param_spec_object ("stroke-pixbuf",
+ _("Stroke Pixbuf"),
+ _("The pixbuf to use to draw the item's perimeter. To disable painting set the 'stroke-pattern' property to NULL"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_FILL_COLOR,
+ g_param_spec_string ("fill-color",
+ _("Fill Color"),
+ _("The color to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
+ NULL,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_FILL_COLOR_RGBA,
+ g_param_spec_uint ("fill-color-rgba",
+ _("Fill Color RGBA"),
+ _("The color to use to paint the interior of the item, specified as a 32-bit integer value. To disable painting set the 'fill-pattern' property to NULL"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_FILL_PIXBUF,
+ g_param_spec_object ("fill-pixbuf",
+ _("Fill Pixbuf"),
+ _("The pixbuf to use to paint the interior of the item. To disable painting set the 'fill-pattern' property to NULL"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_WRITABLE));
}
-/**
- * goo_canvas_style_set_fill_options:
- * @style: a style.
- * @cr: a cairo context.
- *
- * Sets the standard cairo fill options using the given style.
- *
- * Returns: %TRUE if a paint source is set, or %FALSE if the fill should
- * be skipped.
- **/
-gboolean
-goo_canvas_style_set_fill_options (GooCanvasStyle *style,
- cairo_t *cr)
-{
- GooCanvasStyleProperty *property;
- gboolean operator_set = FALSE, antialias_set = FALSE;
- gboolean fill_rule_set = FALSE, fill_pattern_set = FALSE;
- gboolean need_fill = FALSE;
- gint i;
-
- if (!style)
- return FALSE;
-
- /* Step up the hierarchy of styles looking for the properties. */
- while (style)
- {
- for (i = 0; i < style->properties->len; i++)
- {
- property = &g_array_index (style->properties, GooCanvasStyleProperty,
- i);
-
- if (property->id == goo_canvas_style_operator_id && !operator_set)
- {
- cairo_set_operator (cr, property->value.data[0].v_long);
- operator_set = TRUE;
- }
- else if (property->id == goo_canvas_style_antialias_id && !antialias_set)
- {
- cairo_set_antialias (cr, property->value.data[0].v_long);
- antialias_set = TRUE;
- }
- else if (property->id == goo_canvas_style_fill_rule_id && !fill_rule_set)
- {
- cairo_set_fill_rule (cr, property->value.data[0].v_long);
- fill_rule_set = TRUE;
- }
- else if (property->id == goo_canvas_style_fill_pattern_id && !fill_pattern_set)
- {
- if (property->value.data[0].v_pointer)
- {
- cairo_set_source (cr, property->value.data[0].v_pointer);
- need_fill = TRUE;
- }
- fill_pattern_set = TRUE;
- }
- }
-
- style = style->parent;
- }
-
- return need_fill;
-}
diff --git a/src/goocanvasstyle.h b/src/goocanvasstyle.h
index ec76640..6b3c07d 100644
--- a/src/goocanvasstyle.h
+++ b/src/goocanvasstyle.h
@@ -1,47 +1,18 @@
/*
- * GooCanvas. Copyright (C) 2005-6 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005-2010 Damon Chaplin.
* Released under the GNU LGPL license. See COPYING for details.
*
- * goocanvasstyle.h - cascading styles.
+ * goocanvasstyle.h -
*/
#ifndef __GOO_CANVAS_STYLE_H__
#define __GOO_CANVAS_STYLE_H__
#include <gtk/gtk.h>
+#include <goocanvasutils.h>
G_BEGIN_DECLS
-/* GQuarks for the basic properties. */
-extern GQuark goo_canvas_style_stroke_pattern_id;
-extern GQuark goo_canvas_style_fill_pattern_id;
-extern GQuark goo_canvas_style_fill_rule_id;
-extern GQuark goo_canvas_style_operator_id;
-extern GQuark goo_canvas_style_antialias_id;
-extern GQuark goo_canvas_style_line_width_id;
-extern GQuark goo_canvas_style_line_cap_id;
-extern GQuark goo_canvas_style_line_join_id;
-extern GQuark goo_canvas_style_line_join_miter_limit_id;
-extern GQuark goo_canvas_style_line_dash_id;
-extern GQuark goo_canvas_style_font_desc_id;
-extern GQuark goo_canvas_style_hint_metrics_id;
-
-
-/**
- * GooCanvasStyleProperty
- * @id: the unique property identifier.
- * @value: the value of the property.
- *
- * #GooCanvasStyleProperty represents a property setting.
- */
-typedef struct _GooCanvasStyleProperty GooCanvasStyleProperty;
-struct _GooCanvasStyleProperty
-{
- GQuark id;
- GValue value;
-};
-
-
#define GOO_TYPE_CANVAS_STYLE (goo_canvas_style_get_type ())
#define GOO_CANVAS_STYLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_STYLE, GooCanvasStyle))
#define GOO_CANVAS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_STYLE, GooCanvasStyleClass))
@@ -53,22 +24,28 @@ struct _GooCanvasStyleProperty
typedef struct _GooCanvasStyle GooCanvasStyle;
typedef struct _GooCanvasStyleClass GooCanvasStyleClass;
-/**
- * GooCanvasStyle
- * @parent: the parent style.
- * @properties: an array of #GooCanvasStyleProperty property settings.
- *
- * #GooCanvasStyle holds the style properties of a canvas item, as well as a
- * pointer to the parent style.
- */
struct _GooCanvasStyle
{
- /* <private> */
GObject parent_object;
- /* <public> */
- GooCanvasStyle *parent;
- GArray *properties;
+ /*< private >*/
+ cairo_pattern_t *stroke_pattern;
+ cairo_pattern_t *fill_pattern;
+
+ GooCanvasLineDash *dash;
+ PangoFontDescription *font_desc;
+
+ gdouble line_width;
+ gdouble line_join_miter_limit;
+
+ guint stroke_pattern_set : 1;
+ guint fill_pattern_set : 1;
+ cairo_operator_t op : 6;
+ cairo_antialias_t antialias : 4;
+ cairo_fill_rule_t fill_rule : 3;
+ cairo_line_cap_t line_cap : 4;
+ cairo_line_join_t line_join : 4;
+ guint hint_metrics : 2;
};
struct _GooCanvasStyleClass
@@ -85,25 +62,14 @@ struct _GooCanvasStyleClass
};
-GType goo_canvas_style_get_type (void) G_GNUC_CONST;
-GooCanvasStyle* goo_canvas_style_new (void);
-GooCanvasStyle* goo_canvas_style_copy (GooCanvasStyle *style);
-
-GooCanvasStyle* goo_canvas_style_get_parent (GooCanvasStyle *style);
-void goo_canvas_style_set_parent (GooCanvasStyle *style,
- GooCanvasStyle *parent);
+GType goo_canvas_style_get_type (void) G_GNUC_CONST;
+GooCanvasStyle* goo_canvas_style_new (void);
-GValue* goo_canvas_style_get_property (GooCanvasStyle *style,
- GQuark property_id);
-void goo_canvas_style_set_property (GooCanvasStyle *style,
- GQuark property_id,
- const GValue *value);
+void goo_canvas_style_set_stroke_pattern (GooCanvasStyle *style,
+ cairo_pattern_t *pattern);
+void goo_canvas_style_set_fill_pattern (GooCanvasStyle *style,
+ cairo_pattern_t *pattern);
-/* Convenience functions to set the standard cairo stroke and fill options. */
-gboolean goo_canvas_style_set_stroke_options (GooCanvasStyle *style,
- cairo_t *cr);
-gboolean goo_canvas_style_set_fill_options (GooCanvasStyle *style,
- cairo_t *cr);
G_END_DECLS
diff --git a/src/goocanvastable.c b/src/goocanvastable.c
index a2b2ccb..421d23e 100644
--- a/src/goocanvastable.c
+++ b/src/goocanvastable.c
@@ -1826,8 +1826,6 @@ goo_canvas_table_get_requested_area (GooCanvasItem *item,
simple->need_update = FALSE;
- goo_canvas_item_simple_check_style (simple);
-
if (simple->visibility == GOO_CANVAS_ITEM_HIDDEN)
return FALSE;
@@ -2059,8 +2057,6 @@ goo_canvas_table_update (GooCanvasItem *item,
simple->need_update = FALSE;
simple->need_entire_subtree_update = FALSE;
- goo_canvas_item_simple_check_style (simple);
-
/* We just allocate exactly what is requested. */
if (goo_canvas_table_get_requested_area (item, cr, &tmp_bounds))
{
@@ -2080,7 +2076,6 @@ goo_canvas_table_paint (GooCanvasItem *item,
gdouble scale)
{
GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
- GooCanvasStyle *style = simple->style;
GooCanvasGroup *group = (GooCanvasGroup*) item;
GooCanvasTable *table = (GooCanvasTable*) item;
GooCanvasTableLayoutData *layout_data = table->layout_data;
@@ -2153,7 +2148,7 @@ goo_canvas_table_paint (GooCanvasItem *item,
cairo_save (cr);
/* Fill the table, if desired. */
- if (goo_canvas_style_set_fill_options (style, cr))
+ if (goo_canvas_item_simple_set_fill_options (simple, cr))
{
cairo_rectangle (cr,
layout_data->border_width + vert_grid_line_width,
@@ -2165,7 +2160,7 @@ goo_canvas_table_paint (GooCanvasItem *item,
/* We use the style for the stroke color, but the line cap style and line
width are overridden here. */
- goo_canvas_style_set_stroke_options (style, cr);
+ goo_canvas_item_simple_set_stroke_options (simple, cr);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
diff --git a/src/goocanvastext.c b/src/goocanvastext.c
index a8c69a9..e12398c 100644
--- a/src/goocanvastext.c
+++ b/src/goocanvastext.c
@@ -264,8 +264,6 @@ goo_canvas_text_create_layout (GooCanvasText *text,
gdouble *origin_y_return)
{
GooCanvasItemSimple *simple = (GooCanvasItemSimple*) text;
- GooCanvasStyle *style = simple->style;
- GValue *svalue;
PangoLayout *layout;
PangoContext *context;
PangoRectangle ink_rect, logical_rect;
@@ -288,17 +286,12 @@ goo_canvas_text_create_layout (GooCanvasText *text,
else
pango_layout_set_text (layout, string, -1);
- svalue = goo_canvas_style_get_property (style,
- goo_canvas_style_font_desc_id);
- if (svalue)
- pango_layout_set_font_description (layout, svalue->data[0].v_pointer);
-
- svalue = goo_canvas_style_get_property (style,
- goo_canvas_style_hint_metrics_id);
- if (svalue)
- hint_metrics = svalue->data[0].v_long;
+ if (simple->style && simple->style->font_desc)
+ pango_layout_set_font_description (layout, simple->style->font_desc);
font_options = cairo_font_options_create ();
+ if (simple->style)
+ hint_metrics = simple->style->hint_metrics;
cairo_font_options_set_hint_metrics (font_options, hint_metrics);
pango_cairo_context_set_font_options (context, font_options);
cairo_font_options_destroy (font_options);
@@ -432,27 +425,70 @@ goo_canvas_text_update (GooCanvasItemSimple *simple,
layout container and settings. */
text->layout_width = text->width;
- /* Compute the new bounds. */
- layout = goo_canvas_text_create_layout (text, text->layout_width, cr,
- &simple->bounds, NULL, NULL);
- g_object_unref (layout);
+ /* If the text is going to be clipped we can use the text's width and height
+ to calculate the bounds, which is much faster. */
+ if (text->width > 0.0 && text->height > 0.0)
+ {
+ simple->bounds.x1 = text->x;
+ simple->bounds.y1 = text->y;
- /* If the height is set, use that. */
- if (text->height > 0.0)
- simple->bounds.y2 = simple->bounds.y1 + text->height;
+ switch (text->anchor)
+ {
+ case GTK_ANCHOR_N:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_S:
+ simple->bounds.x1 -= text->width / 2.0;
+ break;
+ case GTK_ANCHOR_NE:
+ case GTK_ANCHOR_E:
+ case GTK_ANCHOR_SE:
+ simple->bounds.x1 -= text->width;
+ break;
+ default:
+ break;
+ }
+
+ switch (text->anchor)
+ {
+ case GTK_ANCHOR_W:
+ case GTK_ANCHOR_CENTER:
+ case GTK_ANCHOR_E:
+ simple->bounds.y1 -= text->height / 2.0;
+ break;
+ case GTK_ANCHOR_SW:
+ case GTK_ANCHOR_S:
+ case GTK_ANCHOR_SE:
+ simple->bounds.y1 -= text->height;
+ break;
+ default:
+ break;
+ }
+
+ simple->bounds.x2 = simple->bounds.x1 + text->width;
+ simple->bounds.y2 = simple->bounds.y1 + text->height;
+ }
+ else
+ {
+ /* Compute the new bounds. */
+ layout = goo_canvas_text_create_layout (text, text->layout_width, cr,
+ &simple->bounds, NULL, NULL);
+ g_object_unref (layout);
+
+ /* If the height is set, use that. */
+ if (text->height > 0.0)
+ simple->bounds.y2 = simple->bounds.y1 + text->height;
+ }
}
static gboolean
-goo_canvas_text_is_unpainted (GooCanvasStyle *style)
+goo_canvas_text_is_unpainted (GooCanvasText *text)
{
- GValue *value;
-
- value = goo_canvas_style_get_property (style,
- goo_canvas_style_fill_pattern_id);
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) text;
+ GooCanvasStyle *style = simple->style;
- /* We only return TRUE if the value is explicitly set to NULL. */
- if (value && !value->data[0].v_pointer)
+ /* We only return TRUE if the fill pattern is explicitly set to NULL. */
+ if (style && style->fill_pattern_set && !style->fill_pattern)
return TRUE;
return FALSE;
}
@@ -481,7 +517,7 @@ goo_canvas_text_is_item_at (GooCanvasItemSimple *simple,
if (is_pointer_event
&& simple->pointer_events & GOO_CANVAS_EVENTS_PAINTED_MASK
- && goo_canvas_text_is_unpainted (simple->style))
+ && goo_canvas_text_is_unpainted (text))
return FALSE;
/* Check if the point is outside the clipped height. */
@@ -547,7 +583,7 @@ goo_canvas_text_paint (GooCanvasItemSimple *simple,
if (!text->text || !text->text[0])
return;
- goo_canvas_style_set_fill_options (simple->style, cr);
+ goo_canvas_item_simple_set_fill_options (simple, cr);
cairo_new_path (cr);
layout = goo_canvas_text_create_layout (text, text->layout_width, cr,
diff --git a/src/goocanvasutils.c b/src/goocanvasutils.c
index a2a64a2..e938255 100644
--- a/src/goocanvasutils.c
+++ b/src/goocanvasutils.c
@@ -1229,25 +1229,10 @@ goo_canvas_get_rgba_value_from_pattern (cairo_pattern_t *pattern,
}
-/* Sets a style property to the given pattern, taking ownership of it. */
-void
-goo_canvas_set_style_property_from_pattern (GooCanvasStyle *style,
- GQuark property_id,
- cairo_pattern_t *pattern)
-{
- GValue tmpval = { 0 };
-
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, property_id, &tmpval);
- g_value_unset (&tmpval);
-}
-
-
cairo_pattern_t*
goo_canvas_create_pattern_from_color_value (const GValue *value)
{
- GdkColor color = { 0, 0, 0, 0, };
+ GdkColor color = { 0, 0, 0, 0 };
if (g_value_get_string (value))
gdk_color_parse (g_value_get_string (value), &color);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]