mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-05 04:30:18 +01:00
PS: Fix for dash-zero-length
This commit is contained in:
parent
7285499700
commit
8aa306caac
1 changed files with 75 additions and 4 deletions
|
|
@ -1805,15 +1805,82 @@ _cairo_ps_surface_stroke (void *abstract_surface,
|
|||
cairo_ps_surface_t *surface = abstract_surface;
|
||||
cairo_output_stream_t *stream = surface->stream;
|
||||
cairo_int_status_t status;
|
||||
double *dash = style->dash;
|
||||
int num_dashes = style->num_dashes;
|
||||
double dash_offset = style->dash_offset;
|
||||
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return _analyze_operation (surface, op, source);
|
||||
|
||||
assert (operation_supported (surface, op, source));
|
||||
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"%% _cairo_ps_surface_stroke\n");
|
||||
|
||||
/* PostScript has "special needs" when it comes to zero-length
|
||||
* dash segments with butt caps. It apparently (at least
|
||||
* according to ghostscript) draws hairlines for this
|
||||
* case. That's not what the cairo semantics want, so we first
|
||||
* touch up the array to eliminate any 0.0 values that will
|
||||
* result in "on" segments.
|
||||
*/
|
||||
if (num_dashes && style->line_cap == CAIRO_LINE_CAP_BUTT) {
|
||||
int i;
|
||||
|
||||
/* If there's an odd number of dash values they will each get
|
||||
* interpreted as both on and off. So we first explicitly
|
||||
* expand the array to remove the duplicate usage so that we
|
||||
* can modify some of the values.
|
||||
*/
|
||||
if (num_dashes % 2) {
|
||||
dash = malloc (2 * num_dashes * sizeof (double));
|
||||
if (dash == NULL)
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
memcpy (dash, style->dash, num_dashes * sizeof (double));
|
||||
memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double));
|
||||
|
||||
num_dashes *= 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_dashes; i += 2) {
|
||||
if (dash[i] == 0.0) {
|
||||
/* If we're at the front of the list, we first rotate
|
||||
* two elements from the end of the list to the front
|
||||
* of the list before folding away the 0.0. Or, if
|
||||
* there are only two dash elements, then there is
|
||||
* nothing at all to draw.
|
||||
*/
|
||||
if (i == 0) {
|
||||
double last_two[2];
|
||||
|
||||
if (num_dashes == 2) {
|
||||
if (dash != style->dash)
|
||||
free (dash);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
/* The cases of num_dashes == 0, 1, or 3 elements
|
||||
* cannot exist, so the rotation of 2 elements
|
||||
* will always be safe */
|
||||
memcpy (last_two, dash + num_dashes - 2, sizeof (last_two));
|
||||
memmove (dash + 2, dash, (num_dashes - 2) * sizeof (double));
|
||||
memcpy (dash, last_two, sizeof (last_two));
|
||||
dash_offset += dash[0] + dash[1];
|
||||
i = 2;
|
||||
}
|
||||
dash[i-1] += dash[i+1];
|
||||
num_dashes -= 2;
|
||||
memmove (dash + i, dash + i + 2, (num_dashes - i) * sizeof (double));
|
||||
/* If we might have just rotated, it's possible that
|
||||
* we rotated a 0.0 value to the front of the list.
|
||||
* Set i to -2 so it will get incremented to 0. */
|
||||
if (i == 2)
|
||||
i = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit_pattern (surface, source);
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
|
|
@ -1836,14 +1903,18 @@ _cairo_ps_surface_stroke (void *abstract_surface,
|
|||
_cairo_output_stream_printf (stream, "%d setlinejoin\n",
|
||||
_cairo_ps_line_join (style->line_join));
|
||||
/* dashes */
|
||||
if (style->num_dashes) {
|
||||
if (num_dashes) {
|
||||
int d;
|
||||
|
||||
_cairo_output_stream_printf (stream, "[");
|
||||
for (d = 0; d < style->num_dashes; d++)
|
||||
_cairo_output_stream_printf (stream, " %f", style->dash[d]);
|
||||
for (d = 0; d < num_dashes; d++)
|
||||
_cairo_output_stream_printf (stream, " %f", dash[d]);
|
||||
_cairo_output_stream_printf (stream, "] %f setdash\n",
|
||||
style->dash_offset);
|
||||
dash_offset);
|
||||
}
|
||||
if (dash != style->dash)
|
||||
free (dash);
|
||||
|
||||
/* miter limit */
|
||||
_cairo_output_stream_printf (stream, "%f setmiterlimit\n",
|
||||
style->miter_limit);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue