diff options
author | Carl Worth <cworth@cworth.org> | 2005-08-19 12:02:14 +0000 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2005-08-19 12:02:14 +0000 |
commit | 2b72a4eee80e73f0553779a281e6ef5f0587519e (patch) | |
tree | a59ebce04ad87fc7a2e457967dc4df368605d7c6 /src/cairo-gstate.c | |
parent | a2e798b5a126a0aaf7043b817120986889538acf (diff) |
Fix for bug #2729:
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).
Add documentation.
Add new CAIRO_STATUS_INVALID_DASH.
Add dash-offfset-negative test from Owen.
churn
Diffstat (limited to 'src/cairo-gstate.c')
-rw-r--r-- | src/cairo-gstate.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 79962c3a..c7b0c640 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -430,21 +430,48 @@ _cairo_gstate_get_line_join (cairo_gstate_t *gstate) 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; |