gtk-css-engine r100 - in trunk: . libccd/ccd libccd/examples themes/gtk-css-test/gtk-2.0



Author: robsta
Date: Thu Sep 11 11:39:08 2008
New Revision: 100
URL: http://svn.gnome.org/viewvc/gtk-css-engine?rev=100&view=rev

Log:
* TODO: mention widget path helper app.
* libccd/ccd/ccd-border.c:
* libccd/ccd/ccd-border.h:
* libccd/ccd/ccd-gtk-style.c:
* libccd/ccd/ccd-selector.c:
* libccd/ccd/ccd-style.c:
* libccd/ccd/ccd-style.h:
  Initial support for rounded borders.
* libccd/examples/internal.c: fix after rounded borders internal API
  change.
* themes/gtk-css-test/gtk-2.0/styles.css: test rounded borders.


Modified:
   trunk/   (props changed)
   trunk/ChangeLog
   trunk/TODO
   trunk/libccd/ccd/ccd-border.c
   trunk/libccd/ccd/ccd-border.h
   trunk/libccd/ccd/ccd-gtk-style.c
   trunk/libccd/ccd/ccd-selector.c
   trunk/libccd/ccd/ccd-style.c
   trunk/libccd/ccd/ccd-style.h
   trunk/libccd/examples/internal.c
   trunk/themes/gtk-css-test/gtk-2.0/styles.css

Modified: trunk/TODO
==============================================================================
--- trunk/TODO	(original)
+++ trunk/TODO	Thu Sep 11 11:39:08 2008
@@ -92,6 +92,8 @@
 * Create a spiffy website, possibly on http://gnome.org/projects. 
   Any volunteers?
 * Evaluate alternative SVG renderers as they become available.
+* Investigate a helper app for widget matching, like
+  http://testbit.eu/~timj/historic/gle/ .
 
 
 RELEASES

Modified: trunk/libccd/ccd/ccd-border.c
==============================================================================
--- trunk/libccd/ccd/ccd-border.c	(original)
+++ trunk/libccd/ccd/ccd-border.c	Thu Sep 11 11:39:08 2008
@@ -17,69 +17,103 @@
  * MA 02110-1301, USA.
  */
 
+#include <math.h>
 #include <stdio.h>
 #include <string.h>
 #include "ccd-border.h"
 
-#define SET_COMMON_WIDTH(spec_, border_, val_)				       \
-if (CCD_PROPERTY_SPEC_SET == spec_ && 					       \
-    !(CCD_BORDER_FLAGS_SPECIFIC_WIDTH & (border_).flags)) {		       \
-	(border_).width = val_;						       \
-	(border_).flags |= CCD_BORDER_FLAGS_COMMON_WIDTH;		       \
-}									       \
-if (spec_ != CCD_PROPERTY_SPEC_UNSET) {					       \
-	(border_).width_spec = spec_;					       \
-}
-
-#define SET_SPECIFIC_WIDTH(spec_, border_, val_)			       \
-if (CCD_PROPERTY_SPEC_SET == spec_) {					       \
-	(border_).width = val_;						       \
-	(border_).flags |= CCD_BORDER_FLAGS_SPECIFIC_WIDTH;		       \
-}									       \
-if (spec_ != CCD_PROPERTY_SPEC_UNSET) {					       \
-	(border_).width_spec = spec_;					       \
-}
-
-#define SET_COMMON_STYLE(spec_, border_, val_)				       \
-if (CCD_PROPERTY_SPEC_SET == spec_ && 					       \
-    !(CCD_BORDER_FLAGS_SPECIFIC_STYLE & (border_).flags)) {		       \
-	(border_).style = val_;						       \
-	(border_).flags |= CCD_BORDER_FLAGS_COMMON_STYLE;		       \
-}									       \
-if (spec_ != CCD_PROPERTY_SPEC_UNSET) {					       \
-	(border_).style_spec = spec_;					       \
-}
-
-#define SET_SPECIFIC_STYLE(spec_, border_, val_)			       \
-if (CCD_PROPERTY_SPEC_SET == spec_) {					       \
-	(border_).style = val_;						       \
-	(border_).flags |= CCD_BORDER_FLAGS_SPECIFIC_STYLE;		       \
-}									       \
-if (spec_ != CCD_PROPERTY_SPEC_UNSET) {					       \
-	(border_).style_spec = spec_;					       \
-}
-
-#define SET_COMMON_COLOR(spec_, border_, val_)				       \
-if (CCD_PROPERTY_SPEC_SET == spec_ && 					       \
-    !(CCD_BORDER_FLAGS_SPECIFIC_COLOR & (border_).flags)) { 		       \
-	(border_).color.red = val_.red;					       \
-	(border_).color.green = val_.green;				       \
-	(border_).color.blue = val_.blue;				       \
-	(border_).flags |= CCD_BORDER_FLAGS_COMMON_COLOR;		       \
-}									       \
-if (spec_ != CCD_PROPERTY_SPEC_UNSET) {					       \
-	(border_).color_spec = spec_;					       \
-}
-
-#define SET_SPECIFIC_COLOR(spec_, border_, val_)			       \
-if (CCD_PROPERTY_SPEC_SET == spec_) { 					       \
-	(border_).color.red = val_.red;					       \
-	(border_).color.green = val_.green;				       \
-	(border_).color.blue = val_.blue;				       \
-	(border_).flags |= CCD_BORDER_FLAGS_SPECIFIC_COLOR;		       \
-}									       \
-if (spec_ != CCD_PROPERTY_SPEC_UNSET) {					       \
-	(border_).color_spec = spec_;					       \
+#define SET_COMMON_WIDTH(spec_, border_, val_)			       \
+if (CCD_PROPERTY_SPEC_SET == spec_ && 				       \
+    !(CCD_BORDER_FLAGS_SPECIFIC_WIDTH & (border_).flags)) {	       \
+	(border_).width = val_;					       \
+	(border_).flags |= CCD_BORDER_FLAGS_COMMON_WIDTH;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(border_).width_spec = spec_;				       \
+}
+
+#define SET_SPECIFIC_WIDTH(spec_, border_, val_)		       \
+if (CCD_PROPERTY_SPEC_SET == spec_) {				       \
+	(border_).width = val_;					       \
+	(border_).flags |= CCD_BORDER_FLAGS_SPECIFIC_WIDTH;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(border_).width_spec = spec_;				       \
+}
+
+#define SET_COMMON_STYLE(spec_, border_, val_)			       \
+if (CCD_PROPERTY_SPEC_SET == spec_ && 				       \
+    !(CCD_BORDER_FLAGS_SPECIFIC_STYLE & (border_).flags)) {	       \
+	(border_).style = val_;					       \
+	(border_).flags |= CCD_BORDER_FLAGS_COMMON_STYLE;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(border_).style_spec = spec_;				       \
+}
+
+#define SET_SPECIFIC_STYLE(spec_, border_, val_)		       \
+if (CCD_PROPERTY_SPEC_SET == spec_) {				       \
+	(border_).style = val_;					       \
+	(border_).flags |= CCD_BORDER_FLAGS_SPECIFIC_STYLE;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(border_).style_spec = spec_;				       \
+}
+
+#define SET_COMMON_COLOR(spec_, border_, val_)			       \
+if (CCD_PROPERTY_SPEC_SET == spec_ && 				       \
+    !(CCD_BORDER_FLAGS_SPECIFIC_COLOR & (border_).flags)) { 	       \
+	(border_).color.red = val_.red;				       \
+	(border_).color.green = val_.green;			       \
+	(border_).color.blue = val_.blue;			       \
+	(border_).flags |= CCD_BORDER_FLAGS_COMMON_COLOR;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(border_).color_spec = spec_;				       \
+}
+
+#define SET_SPECIFIC_COLOR(spec_, border_, val_)		       \
+if (CCD_PROPERTY_SPEC_SET == spec_) { 				       \
+	(border_).color.red = val_.red;				       \
+	(border_).color.green = val_.green;			       \
+	(border_).color.blue = val_.blue;			       \
+	(border_).flags |= CCD_BORDER_FLAGS_SPECIFIC_COLOR;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(border_).color_spec = spec_;				       \
+}
+
+#define SET_COMMON_RADIUS(spec_, join_, val_)			       \
+if (CCD_PROPERTY_SPEC_SET == spec_ && 				       \
+    !(CCD_BORDER_FLAGS_SPECIFIC_RADIUS & (join_).flags)) {	       \
+	(join_).radius = val_;					       \
+	(join_).flags |= CCD_BORDER_FLAGS_COMMON_RADIUS;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(join_).radius_spec = spec_;				       \
+}
+
+#define SET_SPECIFIC_RADIUS(spec_, join_, val_)			       \
+if (CCD_PROPERTY_SPEC_SET == spec_) {				       \
+	(join_).radius = val_;					       \
+	(join_).flags |= CCD_BORDER_FLAGS_SPECIFIC_RADIUS;	       \
+}								       \
+if (spec_ != CCD_PROPERTY_SPEC_UNSET) {				       \
+	(join_).radius_spec = spec_;				       \
+}
+
+#define _PI (_pi ())
+
+static double
+_pi (void)
+{
+	static double pi = 0.;
+
+	if (pi == 0.) {
+		pi = acos (-1.0);
+	}
+
+	return pi;
 }
 
 /*!
@@ -140,63 +174,81 @@
 	g_free (self);
 }
 
-static bool
+static ccd_property_spec_t
 parse_width (CRTerm const		**value,
-	     ccd_property_spec_t	 *spec,
 	     double			 *width)
 {
-	*spec = ccd_property_parse_spec (value);
-	if (CCD_PROPERTY_SPEC_SET == *spec &&
+	ccd_property_spec_t spec;
+
+	spec = ccd_property_parse_spec (value);
+	if (CCD_PROPERTY_SPEC_SET == spec &&
 	    *value && 
 	    TERM_NUMBER == (*value)->type) {
 
 		*width = (*value)->content.num->val;
 		(*value) = (*value)->next;
-		*spec = CCD_PROPERTY_SPEC_SET;
-		return true;
+		spec = CCD_PROPERTY_SPEC_SET;
 	}
 
-	return false;
+	return spec;
 }
 
-static bool
+static ccd_property_spec_t
 parse_style (CRTerm const		**value,
-	     ccd_property_spec_t	 *spec,
 	     ccd_border_style_t		 *style)
 {
+	ccd_property_spec_t spec;
 
-	*spec = ccd_property_parse_spec (value);
+	spec = ccd_property_parse_spec (value);
 	*style = CCD_BORDER_STYLE_SOLID;
-	if (CCD_PROPERTY_SPEC_SET == *spec &&
+	if (CCD_PROPERTY_SPEC_SET == spec &&
 	    *value && 
 	    TERM_IDENT == (*value)->type &&
 	    match_style (cr_string_peek_raw_str ((*value)->content.str), style)) {
 
 		(*value) = (*value)->next;
-		*spec = CCD_PROPERTY_SPEC_SET;
-		return true;
+		spec = CCD_PROPERTY_SPEC_SET;
 	}
 
-	return false;
+	return spec;
 }
 
-static bool
+static ccd_property_spec_t
 parse_color (CRTerm const		**value,
-	     ccd_property_spec_t	 *spec,
 	     ccd_color_t		 *color)
 {
-	*spec = ccd_property_parse_spec (value);
+	ccd_property_spec_t spec;
+
+	spec = ccd_property_parse_spec (value);
 	color->red = color->green = color->blue = 0;
-	if (CCD_PROPERTY_SPEC_SET == *spec &&
+	if (CCD_PROPERTY_SPEC_SET == spec &&
 	    *value &&
 	    ccd_color_parse (color, value)) {
 
 		/* iter is advanced by ccd_color_parse() */
-		*spec = CCD_PROPERTY_SPEC_SET;
-		return true;
+		spec = CCD_PROPERTY_SPEC_SET;
 	}
 
-	return false;
+	return spec;
+}
+
+static ccd_property_spec_t
+parse_radius (CRTerm const		**value,
+	      double			 *radius)
+{
+	ccd_property_spec_t spec;
+
+	spec = ccd_property_parse_spec (value);
+	if (CCD_PROPERTY_SPEC_SET == spec &&
+	    *value && 
+	    TERM_NUMBER == (*value)->type) {
+
+		*radius = (*value)->content.num->val;
+		(*value) = (*value)->next;
+		spec = CCD_PROPERTY_SPEC_SET;
+	}
+
+	return spec;
 }
 
 static bool
@@ -211,17 +263,17 @@
 
 	if (0 == strcmp ("width", property)) {
 
-		parse_width (&value, &spec, &width);
+		spec = parse_width (&value, &width);
 		SET_SPECIFIC_WIDTH (spec, *stroke, width);
 
 	} else if (0 == strcmp ("style", property)) {
 
-		parse_style (&value, &spec, &style);
+		spec = parse_style (&value, &style);
 		SET_SPECIFIC_STYLE (spec, *stroke, style);
 
 	} else if (0 == strcmp ("color", property)) {
 
-		parse_color (&value, &spec, &color);
+		spec = parse_color (&value, &color);
 		SET_SPECIFIC_COLOR (spec, *stroke, color);
 
 	} else {
@@ -248,13 +300,67 @@
 		  CRTerm const	*values)
 {
 	CRTerm const		*iter;
+	double			 radius;
 	double			 width;
 	ccd_border_style_t	 style;
 	ccd_color_t		 color;
+	ccd_property_spec_t	 radius_spec;
 	ccd_property_spec_t	 width_spec;
 	ccd_property_spec_t	 color_spec;
 	ccd_property_spec_t	 style_spec;
 
+	/* Radius */
+	iter = values;
+	if (0 == strcmp ("border-top-right-radius", property)) {
+
+		radius_spec = parse_radius (&iter, &radius);
+		if (CCD_PROPERTY_SPEC_UNSET == radius_spec) {
+			return false;
+
+		}
+		SET_SPECIFIC_RADIUS (radius_spec, self->top_right, radius);
+		return true;
+
+	} else if (0 == strcmp ("border-bottom-right-radius", property)) {
+
+		radius_spec = parse_radius (&iter, &radius);
+		if (CCD_PROPERTY_SPEC_UNSET == radius_spec) {
+			return false;
+		}
+		SET_SPECIFIC_RADIUS (radius_spec, self->right_bottom, radius);
+		return true;
+
+	} else if (0 == strcmp ("border-bottom-left-radius", property)) {
+
+		radius_spec = parse_radius (&iter, &radius);
+		if (CCD_PROPERTY_SPEC_UNSET == radius_spec) {
+			return false;
+		}
+		SET_SPECIFIC_RADIUS (radius_spec, self->bottom_left, radius);
+		return true;
+
+	} else if (0 == strcmp ("border-top-left-radius", property)) {
+
+		radius_spec = parse_radius (&iter, &radius);
+		if (CCD_PROPERTY_SPEC_UNSET == radius_spec) {
+			return false;
+		}
+		SET_SPECIFIC_RADIUS (radius_spec, self->left_top, radius);
+		return true;
+
+	} else if (0 == strcmp ("border-radius", property)) {
+
+		radius_spec = parse_radius (&iter, &radius);
+		if (CCD_PROPERTY_SPEC_UNSET == radius_spec) {
+			return false;
+		}
+		SET_COMMON_RADIUS (radius_spec, self->left_top, radius);
+		SET_COMMON_RADIUS (radius_spec, self->top_right, radius);
+		SET_COMMON_RADIUS (radius_spec, self->right_bottom, radius);
+		SET_COMMON_RADIUS (radius_spec, self->bottom_left, radius);
+		return true;
+	}
+
 	/* Test for specific properties first. */
 	if (0 == strncmp ("border-left-", property, 
 			  sizeof ("border-left-") - 1)) {
@@ -287,9 +393,9 @@
 
 	/* Now try to parse multi-value properties. */
 	iter = values;
-	parse_width (&iter, &width_spec, &width);
-	parse_style (&iter, &style_spec, &style);
-	parse_color (&iter, &color_spec, &color);
+	width_spec = parse_width (&iter, &width);
+	style_spec = parse_style (&iter, &style);
+	color_spec = parse_color (&iter, &color);
 
 	if (0 == strcmp ("border", property)) {
 
@@ -340,21 +446,33 @@
 }
 
 static void
-draw_none (ccd_border_stroke_t const	*stroke,
-	   cairo_t			*cr,
-	   double			 x1,
-	   double			 y1,
-	   double			 x2,
-	   double			 y2)
+line (ccd_border_stroke_t const	*stroke,
+      cairo_t			*cr,
+      double			 x1,
+      double			 y1,
+      double			 x2,
+      double			 y2)
+{
+	/* cairo_move_to (cr, x1, y1); */
+	cairo_line_to (cr, x2, y2);
+}
+
+static void
+draw_none_line (ccd_border_stroke_t const	*stroke,
+		cairo_t				*cr,
+		double				 x1,
+		double				 y1,
+		double				 x2,
+		double				 y2)
 {}
 
 static void
-draw_dotted (ccd_border_stroke_t const	*stroke,
-	     cairo_t			*cr,
-	     double			 x1,
-	     double			 y1,
-	     double			 x2,
-	     double			 y2)
+draw_dotted_line (ccd_border_stroke_t const	*stroke,
+		  cairo_t			*cr,
+		  double			 x1,
+		  double			 y1,
+		  double			 x2,
+		  double			 y2)
 {
 	double dash_len;
 
@@ -362,8 +480,8 @@
 
 	cairo_save (cr);
 
-	cairo_move_to (cr, x1, y1);
-	cairo_line_to (cr, x2, y2);
+	line (stroke, cr, x1, y1, x2, y2);
+
 	cairo_set_dash (cr, &dash_len, 1, 0);
 	cairo_set_line_width (cr, stroke->width);
 	cairo_set_source_rgb (cr, stroke->color.red, stroke->color.green, 
@@ -374,12 +492,12 @@
 }
 
 static void
-draw_dashed (ccd_border_stroke_t const	*stroke,
-	     cairo_t			*cr,
-	     double			 x1,
-	     double			 y1,
-	     double			 x2,
-	     double			 y2)
+draw_dashed_line (ccd_border_stroke_t const	*stroke,
+		  cairo_t			*cr,
+		  double			 x1,
+		  double			 y1,
+		  double			 x2,
+		  double			 y2)
 {
 	double dashes[2];
 
@@ -388,8 +506,8 @@
 
 	cairo_save (cr);
 
-	cairo_move_to (cr, x1, y1);
-	cairo_line_to (cr, x2, y2);
+	line (stroke, cr, x1, y1, x2, y2);
+
 	cairo_set_dash (cr, dashes, G_N_ELEMENTS (dashes), 0);
 	cairo_set_line_width (cr, stroke->width);
 	cairo_set_source_rgb (cr, stroke->color.red, stroke->color.green, 
@@ -400,17 +518,17 @@
 }
 
 static void
-draw_solid (ccd_border_stroke_t const	*stroke,
-	    cairo_t			*cr,
-	    double			 x1,
-	    double			 y1,
-	    double			 x2,
-	    double			 y2)
+draw_solid_line (ccd_border_stroke_t const	*stroke,
+		 cairo_t			*cr,
+		 double				 x1,
+		 double				 y1,
+		 double				 x2,
+		 double				 y2)
 {
 	cairo_save (cr);
 
-	cairo_move_to (cr, x1, y1);
-	cairo_line_to (cr, x2, y2);
+	line (stroke, cr, x1, y1, x2, y2);
+
 	cairo_set_line_width (cr, stroke->width);
 	cairo_set_source_rgb (cr, stroke->color.red, stroke->color.green, 
 				stroke->color.blue);
@@ -419,26 +537,31 @@
 	cairo_restore (cr);
 }
 
-typedef void (*draw_f) (ccd_border_stroke_t const *, cairo_t *, 
-			double, double, double, double);
+typedef void (*line_draw_f) (ccd_border_stroke_t const *, cairo_t *, 
+			     double, double, double, double);
 
-static draw_f
-get_draw_func (ccd_border_stroke_t const *stroke)
+static line_draw_f
+get_line_draw_func (ccd_border_stroke_t const	*stroke,
+		    bool			 path_only)
 {
+	if (path_only) {
+		return line;
+	}
+
 	if (CCD_PROPERTY_SPEC_NONE == stroke->style_spec) {
-		return draw_none;
+		return draw_none_line;
 	}
 
 	switch (stroke->style) {
 	case CCD_BORDER_STYLE_HIDDEN: 
 		g_warning ("CCD_BORDER_STYLE_HIDDEN not implemented");
-		return draw_none;
+		return draw_none_line;
 	case CCD_BORDER_STYLE_DOTTED:
-		return draw_dotted;
+		return draw_dotted_line;
 	case CCD_BORDER_STYLE_DASHED:
-		return draw_dashed;
+		return draw_dashed_line;
 	case CCD_BORDER_STYLE_SOLID:
-		return draw_solid;
+		return draw_solid_line;
 	case CCD_BORDER_STYLE_DOUBLE:
 		g_warning ("CCD_BORDER_STYLE_DOUBLE not implemented");
 	case CCD_BORDER_STYLE_GROOVE:
@@ -451,54 +574,232 @@
 		g_warning ("CCD_BORDER_STYLE_OUTSET not implemented");
 	default:
 		g_assert_not_reached ();
-		return draw_solid;
+		return draw_solid_line;
 	}
 }
 
-void
-ccd_border_draw (ccd_border_stroke_t const	*left,
-		 ccd_border_stroke_t const	*top,
-		 ccd_border_stroke_t const	*right,
-		 ccd_border_stroke_t const	*bottom,
+static void
+join (ccd_border_stroke_t const	*before,
+      ccd_border_stroke_t const	*after,
+      cairo_t			*cr,
+      double			 xc,
+      double			 yc,
+      double			 radius,
+      double			 angle1,
+      double			 angle2)
+{
+	cairo_arc (cr, xc, yc, radius, angle1, angle2);
+}
+
+static void
+draw_solid_join (ccd_border_stroke_t const	*before,
+		 ccd_border_stroke_t const	*after,
 		 cairo_t			*cr,
-		 double				 x,
-		 double				 y,
-		 double				 width,
-		 double				 height)
+		 double				 xc,
+		 double				 yc,
+		 double				 radius,
+		 double				 angle1,
+		 double				 angle2)
 {
-	draw_f	draw_func;
-	double	off;
+	cairo_save (cr);
+
+	join (before, after, cr, xc, yc, radius, angle1, angle2);
+
+	cairo_set_line_width (cr, before->width);
+
+	/* TODO draw with gradient if colors are different. */
+	if (before) {
+		cairo_set_source_rgb (cr,
+				      before->color.red, before->color.green, 
+				      before->color.blue);
+	} else if (after) {
+		cairo_set_source_rgb (cr,
+				      after->color.red, after->color.green, 
+				      after->color.blue);
+	} else {
+		cairo_set_source_rgb (cr, 0., 0., 0.);
+	}
+	
+	cairo_stroke (cr);
+
+	cairo_restore (cr);
+}
+
+typedef void (*join_draw_f) (ccd_border_stroke_t const *, 
+			     ccd_border_stroke_t const *, 
+			     cairo_t *, 
+			     double, double, double, double, double);
+
+static join_draw_f
+get_join_draw_func (ccd_border_stroke_t const	*before,
+		    ccd_border_stroke_t const	*after,
+		    bool			 path_only)
+{
+	if (path_only) {
+		return join;
+	}
+
+	return draw_solid_join;
+}
+
+static void
+border (ccd_border_stroke_t const	*left,
+	ccd_border_join_t const		*left_top,
+	ccd_border_stroke_t const	*top,
+	ccd_border_join_t const		*top_right,
+	ccd_border_stroke_t const	*right,
+	ccd_border_join_t const		*right_bottom,
+	ccd_border_stroke_t const	*bottom,
+	ccd_border_join_t const		*bottom_left,
+	cairo_t				*cr,
+	double				 x,
+	double				 y,
+	double				 width,
+	double				 height,
+	bool				 path_only)
+{
+	line_draw_f	line_func;
+	join_draw_f	join_func;
+	double		xoff, yoff;
+	double		x1, x2, y1, y2;
+	double		xc, yc;
+
+	/* TODO also clip when no border. */
+	/* TODO pass on `path_only' to `line_func' and cairo_move_to() if false. */
 
 	if (left && left->flags) {
-		draw_func = get_draw_func (left);
-		off = left->width / 2.;
-		draw_func (left, cr,
-			   x + off, y, x + off, y + height);
+		line_func = get_line_draw_func (left, path_only);
+		xoff = left->width / 2.;
+		yoff = bottom_left && bottom_left->radius_spec ? bottom_left->radius : 0;
+		x1 = x + xoff;
+		y1 = y + height - yoff;
+		x2 = x1;
+		y2 = y + (left_top && left_top->radius_spec ? left_top->radius : 0);
+
+		cairo_move_to (cr, x1, y1);
+		line_func (left, cr, x1, y1, x2, y2);
+	}
+
+	if (left_top && left_top->flags) {
+		join_func = get_join_draw_func (left, top, path_only);
+		xoff = left->width / 2.;
+		yoff = top->width / 2.;
+		xc = x + left_top->radius + xoff;
+		yc = y + left_top->radius + yoff;
+		join_func (left, top, cr, xc, yc,
+			   left_top->radius, _PI, 3 * _PI / 2);
 	}
 
 	if (top && top->flags) {
-		draw_func = get_draw_func (top);
-		off = top->width / 2.;
-		draw_func (top, cr,
-			   x, y + off, x + width, y + off);
+		line_func = get_line_draw_func (top, path_only);
+		xoff = left_top && left_top->radius_spec ? left_top->radius : 0;
+		yoff = top->width / 2.;
+		x1 = x + xoff;
+		y1 = y + yoff;
+		x2 = x + width - (top_right && top_right->radius_spec ?
+					top_right->radius : 0); 
+		y2 = y1;
+		line_func (top, cr, x1, y1, x2, y2);
+	}
+
+	if (top_right && top_right->flags) {
+		join_func = get_join_draw_func (top, right, path_only);
+		xoff = right->width / 2.;
+		yoff = top->width / 2.;
+		xc = x + width - top_right->radius - xoff;
+		yc = y + top_right->radius + yoff;
+		join_func (top, right, cr, xc, yc,
+			   top_right->radius, 3 * _PI / 2., 0);
 	}
 
 	if (right && right->flags) {
-		draw_func = get_draw_func (right);
-		off = right->width / 2.;
-		draw_func (right, cr,
-			   x + width - off, y, x + width - off, y + height);
+		line_func = get_line_draw_func (right, path_only);
+		xoff = right->width / 2.;
+		yoff = top_right && top_right->radius_spec ? top_right->radius : 0;
+		x1 = x + width - xoff;
+		y1 = y + yoff;
+		x2 = x1;
+		y2 = y + height - (right_bottom && right_bottom->radius_spec ?
+					right_bottom->radius : 0);
+		line_func (right, cr, x1, y1, x2, y2);
+	}
+
+	if (right_bottom && right_bottom->flags) {
+		join_func = get_join_draw_func (right, bottom, path_only);
+		xoff = right->width / 2.;
+		yoff = bottom->width / 2.;
+		xc = x + width - right_bottom->radius - xoff;
+		yc = y + height - right_bottom->radius - yoff;
+		join_func (right, bottom, cr, xc, yc,
+			   right_bottom->radius, 0, _PI / 2.);
 	}
 
 	if (bottom && bottom->flags) {
-		draw_func = get_draw_func (bottom);
-		off = bottom->width / 2.;
-		draw_func (bottom, cr,
-			   x + width, y + height - off, x, y + height - off);
+		line_func = get_line_draw_func (bottom, path_only);
+		xoff = right_bottom && right_bottom->radius_spec ? right_bottom->radius : 0;
+		yoff = bottom->width / 2.;
+		x1 = x + width - xoff;
+		y1 = y + height - yoff;
+		x2 = x + (bottom_left && bottom_left->radius_spec ? bottom_left->radius : 0);
+		y2 = y1;
+		line_func (bottom, cr, x1, y1, x2, y2);
+	}
+
+	if (bottom_left && bottom_left->flags) {
+		join_func = get_join_draw_func (bottom, left, path_only);
+		xoff = left->width / 2.;
+		yoff = bottom->width / 2.;
+		xc = x + bottom_left->radius + xoff;
+		yc = y + height - bottom_left->radius - yoff;
+		join_func (bottom, left, cr, xc, yc,
+			   bottom_left->radius, _PI / 2., _PI);
 	}
 }
 
 void
+ccd_border_clip (ccd_border_stroke_t const	*left,
+		 ccd_border_join_t const	*left_top,
+		 ccd_border_stroke_t const	*top,
+		 ccd_border_join_t const	*top_right,
+		 ccd_border_stroke_t const	*right,
+		 ccd_border_join_t const	*right_bottom,
+		 ccd_border_stroke_t const	*bottom,
+		 ccd_border_join_t const	*bottom_left,
+		 cairo_t			*cr,
+		 double				 x,
+		 double				 y,
+		 double				 width,
+		 double				 height)
+{
+	border (left, left_top, top, top_right, 
+		right, right_bottom, bottom, bottom_left,
+		cr, x, y, width, height, true);
+
+	cairo_close_path (cr);
+	cairo_clip (cr);
+}
+
+void
+ccd_border_draw (ccd_border_stroke_t const	*left,
+		 ccd_border_join_t const	*left_top,
+		 ccd_border_stroke_t const	*top,
+		 ccd_border_join_t const	*top_right,
+		 ccd_border_stroke_t const	*right,
+		 ccd_border_join_t const	*right_bottom,
+		 ccd_border_stroke_t const	*bottom,
+		 ccd_border_join_t const	*bottom_left,
+		 cairo_t			*cr,
+		 double				 x,
+		 double				 y,
+		 double				 width,
+		 double				 height)
+{
+	border (left, left_top, top, top_right, 
+		right, right_bottom, bottom, bottom_left,
+		cr, x, y, width, height, false);
+}
+
+void
 ccd_border_stroke_dump (ccd_border_stroke_t const *self)
 {
 	if (self->flags & CCD_BORDER_FLAGS_WIDTH_MASK) {

Modified: trunk/libccd/ccd/ccd-border.h
==============================================================================
--- trunk/libccd/ccd/ccd-border.h	(original)
+++ trunk/libccd/ccd/ccd-border.h	Thu Sep 11 11:39:08 2008
@@ -48,16 +48,24 @@
  */
 typedef enum {
 	CCD_BORDER_FLAGS_COMMON_WIDTH	= 1 << 0,
-	CCD_BORDER_FLAGS_SPECIFIC_WIDTH = 1 << 1,
-	CCD_BORDER_FLAGS_WIDTH_MASK	= CCD_BORDER_FLAGS_COMMON_WIDTH | CCD_BORDER_FLAGS_SPECIFIC_WIDTH,
+	CCD_BORDER_FLAGS_SPECIFIC_WIDTH	= 1 << 1,
+	CCD_BORDER_FLAGS_WIDTH_MASK	= CCD_BORDER_FLAGS_COMMON_WIDTH |
+					  CCD_BORDER_FLAGS_SPECIFIC_WIDTH,
 
 	CCD_BORDER_FLAGS_COMMON_STYLE	= 1 << 2,
 	CCD_BORDER_FLAGS_SPECIFIC_STYLE = 1 << 3,
-	CCD_BORDER_FLAGS_STYLE_MASK	= CCD_BORDER_FLAGS_COMMON_STYLE | CCD_BORDER_FLAGS_SPECIFIC_STYLE,
+	CCD_BORDER_FLAGS_STYLE_MASK	= CCD_BORDER_FLAGS_COMMON_STYLE |
+					  CCD_BORDER_FLAGS_SPECIFIC_STYLE,
 
 	CCD_BORDER_FLAGS_COMMON_COLOR	= 1 << 4,
 	CCD_BORDER_FLAGS_SPECIFIC_COLOR = 1 << 5,
-	CCD_BORDER_FLAGS_COLOR_MASK	= CCD_BORDER_FLAGS_COMMON_COLOR | CCD_BORDER_FLAGS_SPECIFIC_COLOR
+	CCD_BORDER_FLAGS_COLOR_MASK	= CCD_BORDER_FLAGS_COMMON_COLOR |
+					  CCD_BORDER_FLAGS_SPECIFIC_COLOR,
+
+	CCD_BORDER_FLAGS_COMMON_RADIUS	= 1 << 6,
+	CCD_BORDER_FLAGS_SPECIFIC_RADIUS = 1 << 7,
+	CCD_BORDER_FLAGS_RADIUS_MASK	= CCD_BORDER_FLAGS_COMMON_RADIUS |
+					  CCD_BORDER_FLAGS_SPECIFIC_RADIUS
 } ccd_border_flags_t;
 
 #define CCD_BORDER_STROKE_ASSIGN(lhs_, rhs_) {		\
@@ -77,14 +85,31 @@
 	ccd_property_spec_t	style_spec;
 	ccd_color_t		color;
 	ccd_property_spec_t	color_spec;
-	int			flags;
-} ccd_border_stroke_t;
+	unsigned int		flags;
+} ccd_border_stroke_t; 
+
+#define CCD_BORDER_JOIN_ASSIGN(lhs_, rhs_) {		\
+	lhs_.radius		= rhs_.radius;		\
+	lhs_.radius_spec	= rhs_.radius_spec;	\
+	lhs_.flags		= rhs_.flags;		\
+}
+
+/* TODO just call it "spec"? */
+typedef struct {
+	double			radius;
+	ccd_property_spec_t	radius_spec;	
+	unsigned int		flags;
+} ccd_border_join_t;
 
 typedef struct {
 	ccd_border_stroke_t	left;
+	ccd_border_join_t	left_top;
 	ccd_border_stroke_t	top;
+	ccd_border_join_t	top_right;
 	ccd_border_stroke_t	right;
+	ccd_border_join_t	right_bottom;
 	ccd_border_stroke_t	bottom;
+	ccd_border_join_t	bottom_left;
 } ccd_border_t;
 
 ccd_border_t *	ccd_border_new	(void);
@@ -93,11 +118,27 @@
 bool ccd_border_parse (ccd_border_t *self, char const *property, 
 				CRTerm const *values);
 
+void ccd_border_clip (ccd_border_stroke_t const *left, 
+		      ccd_border_join_t const *left_top,
+		      ccd_border_stroke_t const *top, 
+		      ccd_border_join_t const *top_right,
+		      ccd_border_stroke_t const *right,
+		      ccd_border_join_t const *right_bottom,
+		      ccd_border_stroke_t const *bottom, 
+		      ccd_border_join_t const *bottom_left,
+		      cairo_t *cr, 
+		      double x, double y, double width, double height);
+
 void ccd_border_draw (ccd_border_stroke_t const *left, 
+		      ccd_border_join_t const *left_top,
 		      ccd_border_stroke_t const *top, 
+		      ccd_border_join_t const *top_right,
 		      ccd_border_stroke_t const *right,
+		      ccd_border_join_t const *right_bottom,
 		      ccd_border_stroke_t const *bottom, 
-		      cairo_t *cr, double x, double y, double width, double height);
+		      ccd_border_join_t const *bottom_left,
+		      cairo_t *cr, 
+		      double x, double y, double width, double height);
 
 void ccd_border_dump		(ccd_border_t const *self);
 void ccd_border_stroke_dump	(ccd_border_stroke_t const *self);

Modified: trunk/libccd/ccd/ccd-gtk-style.c
==============================================================================
--- trunk/libccd/ccd/ccd-gtk-style.c	(original)
+++ trunk/libccd/ccd/ccd-gtk-style.c	Thu Sep 11 11:39:08 2008
@@ -47,53 +47,67 @@
 	ccd_background_draw (self->bg_color, self->bg_image,
 			     cr, x, y, width, height);
 
+	/* TODO take care about roundings on the gap side. */
+
 	switch (gap_side) {
 	case GTK_POS_LEFT:
 		if (gap_start > y || gap_width < height) {
 			/* Draw gap only if it's not over the whole border. */
-			ccd_border_draw (&self->left, NULL, NULL, NULL,
+			ccd_border_draw (&self->left, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 					 cr, x, y, 0, gap_start);
-			ccd_border_draw (&self->left, NULL, NULL, NULL,
+			ccd_border_draw (&self->left, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 					 cr, x, y + gap_start + gap_width, 
 					 0, height - gap_start - gap_width);
 		}
-		ccd_border_draw (NULL, &self->top, &self->right, &self->bottom,
+		ccd_border_draw (NULL, NULL, 
+				 &self->top, &self->top_right,
+				 &self->right, &self->right_bottom,
+				 &self->bottom, NULL,
 				 cr, x, y, width, height);
 		break;
 	case GTK_POS_TOP:
 		if (gap_start > x || gap_width < width) {
 			/* Draw gap only if it's not over the whole border. */
-			ccd_border_draw (NULL, &self->top, NULL, NULL,
+			ccd_border_draw (NULL, NULL, &self->top, NULL, NULL, NULL, NULL, NULL,
 					 cr, x, y, gap_start, 0);
-			ccd_border_draw (NULL, &self->top, NULL, NULL,
+			ccd_border_draw (NULL, NULL, &self->top, NULL, NULL, NULL, NULL, NULL,
 					 cr, x + gap_start + gap_width, y, 
 					 width - gap_start - gap_width, 0);
 		}
-		ccd_border_draw (&self->left, NULL, &self->right, &self->bottom,
+		ccd_border_draw (&self->left, NULL, 
+				 NULL, NULL,
+				 &self->right, &self->right_bottom,
+				 &self->bottom, &self->bottom_left,
 				 cr, x, y, width, height);
 		break;
 	case GTK_POS_RIGHT:
 		if (gap_start > y || gap_width < height) {
 			/* Draw gap only if it's not over the whole border. */
-			ccd_border_draw (&self->left, NULL, NULL, NULL, cr, 
-					 x + width, y, 0, gap_start);
-			ccd_border_draw (&self->left, NULL, NULL, NULL, cr, 
-					 x + width, y + gap_start + gap_width, 
+			ccd_border_draw (NULL, NULL, NULL, NULL, &self->right, NULL, NULL, NULL,
+					 cr, x + width, y, 0, gap_start);
+			ccd_border_draw (NULL, NULL, NULL, NULL, &self->right, NULL, NULL, NULL,
+					 cr, x + width, y + gap_start + gap_width, 
 					 0, height - gap_start - gap_width);
 		}
-		ccd_border_draw (&self->left, &self->top, NULL, &self->bottom,
+		ccd_border_draw (&self->left, &self->left_top,
+				 &self->top, NULL, 
+				 NULL, NULL,
+				 &self->bottom, &self->bottom_left,
 				 cr, x, y, width, height);
 		break;
 	case GTK_POS_BOTTOM:
 		if (gap_start > x || gap_width < width) {
 			/* Draw gap only if it's not over the whole border. */
-			ccd_border_draw (NULL, NULL, NULL, &self->bottom,
+			ccd_border_draw (NULL, NULL, NULL, NULL, NULL, NULL, &self->bottom, NULL,
 					 cr, x, y + height, gap_start, 0);
-			ccd_border_draw (NULL, NULL, NULL, &self->bottom,
+			ccd_border_draw (NULL, NULL, NULL, NULL, NULL, NULL, &self->bottom, NULL,
 					 cr, x + gap_start + gap_width, y + height,
 					 width - gap_start - gap_width, 0);
 		}
-		ccd_border_draw (&self->left, &self->top, &self->right, NULL,
+		ccd_border_draw (&self->left, &self->left_top,
+				 &self->top, &self->top_right,
+				 &self->right, NULL,
+				 NULL, NULL,
 				 cr, x, y, width, height);
 		break;
 	default:

Modified: trunk/libccd/ccd/ccd-selector.c
==============================================================================
--- trunk/libccd/ccd/ccd-selector.c	(original)
+++ trunk/libccd/ccd/ccd-selector.c	Thu Sep 11 11:39:08 2008
@@ -899,14 +899,23 @@
 		break;
 	}
 
+	/* TODO use spec instead of flags? */
 	if (self->block->border.left.flags)
 		CCD_BORDER_STROKE_ASSIGN (style->left, self->block->border.left);
+	if (self->block->border.left_top.flags)
+		CCD_BORDER_JOIN_ASSIGN (style->left_top, self->block->border.left_top);
 	if (self->block->border.top.flags)
 		CCD_BORDER_STROKE_ASSIGN (style->top, self->block->border.top);
+	if (self->block->border.top_right.flags)
+		CCD_BORDER_JOIN_ASSIGN (style->top_right, self->block->border.top_right);
 	if (self->block->border.right.flags)
 		CCD_BORDER_STROKE_ASSIGN (style->right, self->block->border.right);
+	if (self->block->border.right_bottom.flags)
+		CCD_BORDER_JOIN_ASSIGN (style->right_bottom, self->block->border.right_bottom);
 	if (self->block->border.bottom.flags)
 		CCD_BORDER_STROKE_ASSIGN (style->bottom, self->block->border.bottom);
+	if (self->block->border.bottom_left.flags)
+		CCD_BORDER_JOIN_ASSIGN (style->bottom_left, self->block->border.bottom_left);
 
 	switch (self->block->color_spec) {
 	case CCD_PROPERTY_SPEC_UNSET:

Modified: trunk/libccd/ccd/ccd-style.c
==============================================================================
--- trunk/libccd/ccd/ccd-style.c	(original)
+++ trunk/libccd/ccd/ccd-style.c	Thu Sep 11 11:39:08 2008
@@ -63,7 +63,7 @@
 			 * account for that. */
 			off = stroke->width / 2.;
 
-			ccd_border_draw (NULL, stroke, NULL, NULL, 
+			ccd_border_draw (NULL, NULL, stroke, NULL, NULL, NULL, NULL, NULL,
 						cr, x1, y1 - off, x2 - x1, 0);
 
 		}
@@ -76,7 +76,7 @@
 			 * account for that. */
 			off = stroke->width / 2.;
 
-			ccd_border_draw (stroke, NULL, NULL, NULL, 
+			ccd_border_draw (stroke, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 						cr, x1 - off, y1, 0, y2 - y1);
 		}
 	}
@@ -103,8 +103,11 @@
 			int32_t			 width,
 			int32_t			 height)
 {
-	ccd_border_draw (&self->left, &self->top, &self->right, &self->bottom, 
-				cr, x, y, width, height);
+	ccd_border_draw (&self->left, &self->left_top, 
+			 &self->top, &self->top_right,
+			 &self->right, &self->right_bottom,
+			 &self->bottom, &self->bottom_left,
+			 cr, x, y, width, height);
 }
 
 /**
@@ -126,10 +129,23 @@
 			  int32_t		 width,
 			  int32_t		 height)
 {
+	cairo_save (cr);
+
+	ccd_border_clip (&self->left, &self->left_top, 
+			 &self->top, &self->top_right,
+			 &self->right, &self->right_bottom,
+			 &self->bottom, &self->bottom_left,
+			 cr, x, y, width, height);
+
 	ccd_background_draw (self->bg_color, self->bg_image,
 			     cr, x, y, width, height);
 
-	ccd_border_draw (&self->left, &self->top, &self->right, &self->bottom, 
+	cairo_restore (cr);
+
+	ccd_border_draw (&self->left, &self->left_top, 
+			 &self->top, &self->top_right,
+			 &self->right, &self->right_bottom,
+			 &self->bottom, &self->bottom_left,
 			 cr, x, y, width, height);
 }
 

Modified: trunk/libccd/ccd/ccd-style.h
==============================================================================
--- trunk/libccd/ccd/ccd-style.h	(original)
+++ trunk/libccd/ccd/ccd-style.h	Thu Sep 11 11:39:08 2008
@@ -44,9 +44,13 @@
 	ccd_background_color_t const	*bg_color;
 	ccd_background_image_t const	*bg_image;
 	ccd_border_stroke_t		 left;
+	ccd_border_join_t		 left_top;
 	ccd_border_stroke_t		 top;
+	ccd_border_join_t		 top_right;
 	ccd_border_stroke_t		 right;
+	ccd_border_join_t		 right_bottom;
 	ccd_border_stroke_t		 bottom;
+	ccd_border_join_t		 bottom_left;
 	ccd_color_t const		*color;
 	ccd_property_spec_t		 color_spec;
 } ccd_style_t;

Modified: trunk/libccd/examples/internal.c
==============================================================================
--- trunk/libccd/examples/internal.c	(original)
+++ trunk/libccd/examples/internal.c	Thu Sep 11 11:39:08 2008
@@ -57,7 +57,11 @@
 		.bottom.width = 3, .bottom.style = CCD_BORDER_STYLE_SOLID, .bottom.color.red = 0, .bottom.color.green = 0, .bottom.color.blue = 0
 	};
 
-	ccd_border_draw (&border.left, &border.top, &border.right, &border.bottom, cr, x, y, width, height);
+	ccd_border_draw (&border.left, NULL,
+			 &border.top, NULL,
+			 &border.right, NULL,
+			 &border.bottom, NULL,
+			 cr, x, y, width, height);
 }
 
 static gboolean

Modified: trunk/themes/gtk-css-test/gtk-2.0/styles.css
==============================================================================
--- trunk/themes/gtk-css-test/gtk-2.0/styles.css	(original)
+++ trunk/themes/gtk-css-test/gtk-2.0/styles.css	Thu Sep 11 11:39:08 2008
@@ -102,28 +102,9 @@
 	background-color: yellow;
 }
 */
-option {
-background-color: blue;
-}
-
-option:insensitive {
-background-color: gray;
-}
-/*
-option[shadow=in] {
-background-color: black);
-}
-*/
-option:insensitive[shadow=in] {
-background-color:white;
-}
-
-GtkHScale box.trough {
-	background: yellow;
-}
 
 box {
-	border-bottom-color: red;
+	background: blue;
 	border: 1px solid black;
-	border-bottom: 1px solid blue;
+	border-radius: 5;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]