[cairo-commit] cairo/src cairo-gstate.c, 1.165, 1.166 cairo.c, 1.126, 1.127 cairo.h, 1.147, 1.148

Carl Worth commit at pdx.freedesktop.org
Sat Aug 20 05:02:16 EST 2005


Committed by: cworth

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv15351/src

Modified Files:
	cairo-gstate.c cairo.c cairo.h 
Log Message:

2005-08-19  Carl Worth  <cworth at cworth.org>

        Fix for bug #2729:

        * src/cairo-gstate.c: (_cairo_gstate_set_dash): Adjust negative
        offsets up to their equivalent positive value. Add error checking
        for dash values, (must each be non-negative and must not be all
        zero).

        * src/cairo.c (cairo_set_dash): Add documentation.

        * src/cairo.h:
        * src/cairo.c: (cairo_status_to_string): Add new
        CAIRO_STATUS_INVALID_DASH.

        * test/.cvsignore:
        * test/Makefile.am: Add dash-offfset-negative test from Owen.

        * doc/public/tmpl/cairo.sgml: churn


Index: cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.165
retrieving revision 1.166
diff -u -d -r1.165 -r1.166
--- cairo-gstate.c	18 Aug 2005 22:50:36 -0000	1.165
+++ cairo-gstate.c	19 Aug 2005 19:02:14 -0000	1.166
@@ -430,21 +430,48 @@
 cairo_status_t
 _cairo_gstate_set_dash (cairo_gstate_t *gstate, double *dash, int num_dashes, double offset)
 {
-    if (gstate->dash) {
+    int i;
+    double dash_total;
+
+    if (gstate->dash)
 	free (gstate->dash);
-	gstate->dash = NULL;
-    }
     
     gstate->num_dashes = num_dashes;
-    if (gstate->num_dashes) {
-	gstate->dash = malloc (gstate->num_dashes * sizeof (double));
-	if (gstate->dash == NULL) {
-	    gstate->num_dashes = 0;
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
+
+    if (gstate->num_dashes == 0) {
+	gstate->dash = NULL;
+	gstate->dash_offset = 0.0;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    gstate->dash = malloc (gstate->num_dashes * sizeof (double));
+    if (gstate->dash == NULL) {
+	gstate->num_dashes = 0;
+	return CAIRO_STATUS_NO_MEMORY;
     }
 
     memcpy (gstate->dash, dash, gstate->num_dashes * sizeof (double));
+    
+    dash_total = 0.0;
+    for (i = 0; i < gstate->num_dashes; i++) {
+	if (gstate->dash[i] < 0)
+	    return CAIRO_STATUS_INVALID_DASH;
+	dash_total += gstate->dash[i];
+    }
+
+    if (dash_total == 0.0)
+	return CAIRO_STATUS_INVALID_DASH;
+
+    /* A single dash value indicate symmetric repeating, so the total
+     * is twice as long. */
+    if (gstate->num_dashes == 1)
+	dash_total *= 2;
+
+    /* The dashing code doesn't like a negative offset, so we compute
+     * the equivalent positive offset. */
+    if (offset < 0)
+	offset += ceil (-offset / dash_total + 0.5) * dash_total;
+
     gstate->dash_offset = offset;
 
     return CAIRO_STATUS_SUCCESS;

Index: cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -d -r1.126 -r1.127
--- cairo.c	19 Aug 2005 06:10:41 -0000	1.126
+++ cairo.c	19 Aug 2005 19:02:14 -0000	1.127
@@ -62,7 +62,7 @@
  * a bit of a pain, but it should be easy to always catch as long as
  * one adds a new test case to test a trigger of the new status value.
  */
-#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_FILE_NOT_FOUND
+#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_DASH
 
 /**
  * _cairo_error:
@@ -715,15 +715,42 @@
 	_cairo_set_error (cr, cr->status);
 }
 
+/**
+ * cairo_set_dash:
+ * @cr: a cairo context
+ * @dashes: an array specifying alternate lengths of on and off po
+ * @num_dashes: the length of the dashes array
+ * @offset: an offset into the dash pattern at which the stroke should start
+ * 
+ * Sets the dash pattern to be used by cairo_stroke(). A dash pattern
+ * is specified by @dashes, an array of positive values. Each value
+ * provides the user-space length of altenate "on" and "off" portions
+ * of the stroke. The @offset specifies an offset into the pattern at
+ * which the stroke begins.
+ *
+ * If @num_dashes is 0 dashing is disabled.
+ *
+ * If @num_dashes is 1 a symmetric pattern is assumed with alternating
+ * on and off portions of the size specified by the single value in
+ * @dashes.
+ *
+ * If any value in @dashes is negative, or if all values are 0, then
+ * @cairo_t will be put into an error state with a status of
+ * #CAIRO_STATUS_INVALID_DASH.
+ **/
 void
-cairo_set_dash (cairo_t *cr, double *dashes, int ndash, double offset)
+cairo_set_dash (cairo_t	*cr,
+		double	*dashes,
+		int	 num_dashes,
+		double	 offset)
 {
     if (cr->status) {
 	_cairo_set_error (cr, cr->status);
 	return;
     }
 
-    cr->status = _cairo_gstate_set_dash (cr->gstate, dashes, ndash, offset);
+    cr->status = _cairo_gstate_set_dash (cr->gstate,
+					 dashes, num_dashes, offset);
     if (cr->status)
 	_cairo_set_error (cr, cr->status);
 }
@@ -2483,6 +2510,8 @@
 	return "invalid value for an input Visual*";
     case CAIRO_STATUS_FILE_NOT_FOUND:
 	return "file not found";
+    case CAIRO_STATUS_INVALID_DASH:
+	return "invalid value for a dash setting";
     }
 
     return "<unknown error status>";

Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -d -r1.147 -r1.148
--- cairo.h	10 Aug 2005 22:58:25 -0000	1.147
+++ cairo.h	19 Aug 2005 19:02:14 -0000	1.148
@@ -166,6 +166,7 @@
  * @CAIRO_STATUS_INVALID_FORMAT: invalid value for an input cairo_format_t
  * @CAIRO_STATUS_INVALID_VISUAL: invalid value for an input Visual*
  * @CAIRO_STATUS_FILE_NOT_FOUND: file not found
+ * @CAIRO_STATUS_INVALID_DASH: invalid value for a dash setting
  *
  * #cairo_status_t is used to indicate errors that can occur when
  * using Cairo. In some cases it is returned directly by functions.
@@ -191,7 +192,8 @@
     CAIRO_STATUS_INVALID_CONTENT,
     CAIRO_STATUS_INVALID_FORMAT,
     CAIRO_STATUS_INVALID_VISUAL,
-    CAIRO_STATUS_FILE_NOT_FOUND
+    CAIRO_STATUS_FILE_NOT_FOUND,
+    CAIRO_STATUS_INVALID_DASH
 } cairo_status_t;
 
 /**
@@ -386,7 +388,10 @@
 cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join);
 
 void
-cairo_set_dash (cairo_t *cr, double *dashes, int ndash, double offset);
+cairo_set_dash (cairo_t	*cr,
+		double	*dashes,
+		int	 num_dashes,
+		double	 offset);
 
 void
 cairo_set_miter_limit (cairo_t *cr, double limit);



More information about the cairo-commit mailing list