diff options
author | Carl Worth <cworth@cworth.org> | 2006-04-18 16:53:23 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2006-04-18 16:53:23 -0700 |
commit | b1b699593b820ac4e011f89ad700f052b2f20205 (patch) | |
tree | 5a0d3ecbf894620b6d8e662a37d7b2445d39558c /src | |
parent | efbe40bb8f770fbf60de794488803d3edacd7ed6 (diff) |
Add support for _cairo_pdf_surface_stroke.
Generalize all functions that emit a source pattern to emit both
for the stroking and non-stroking PDF properties. Also add an
implementation of _cairo_pdf_surface_stroke.
With this commit in place, the following tests change from
all-fallback to all-native output while no tests report any new
failures:
dash-zero-legnth
fill-and-stroke
multi-page
new-sub-path
rel-path
self-intersecting
Diffstat (limited to 'src')
-rw-r--r-- | src/cairo-pdf-surface.c | 144 |
1 files changed, 130 insertions, 14 deletions
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 68c027151..ef08ffce7 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1,6 +1,7 @@ /* cairo - a vector graphics library with display and print output * * Copyright © 2004 Red Hat, Inc + * Copyright © 2006 Red Hat, Inc * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public @@ -32,6 +33,7 @@ * * Contributor(s): * Kristian Høgsberg <krh@redhat.com> + * Carl Worth <cworth@cworth.org> */ #include "cairoint.h" @@ -897,11 +899,18 @@ emit_solid_pattern (cairo_pdf_surface_t *surface, cairo_pdf_document_t *document = surface->document; cairo_output_stream_t *output = document->output_stream; unsigned int alpha; - + alpha = _cairo_pdf_surface_add_alpha (surface, pattern->color.alpha); _cairo_pdf_surface_ensure_stream (surface); + /* With some work, we could separate the stroking + * or non-stroking color here as actually needed. */ _cairo_output_stream_printf (output, - "%f %f %f rg /a%d gs\r\n", + "%f %f %f RG " + "%f %f %f rg " + "/a%d gs\r\n", + pattern->color.red, + pattern->color.green, + pattern->color.blue, pattern->color.red, pattern->color.green, pattern->color.blue, @@ -963,9 +972,13 @@ emit_surface_pattern (cairo_pdf_surface_t *dst, _cairo_pdf_surface_ensure_stream (dst); alpha = _cairo_pdf_surface_add_alpha (dst, 1.0); + /* With some work, we could separate the stroking + * or non-stroking pattern here as actually needed. */ _cairo_output_stream_printf (output, - "/Pattern cs /res%d scn /a%d gs\r\n", - stream->id, alpha); + "/Pattern CS /res%d SCN " + "/Pattern cs /res%d scn " + "/a%d gs\r\n", + stream->id, stream->id, alpha); _cairo_surface_release_source_image (pattern->surface, image, image_extra); @@ -1167,9 +1180,13 @@ emit_linear_pattern (cairo_pdf_surface_t *surface, cairo_linear_pattern_t *patte alpha = _cairo_pdf_surface_add_alpha (surface, 1.0); /* Use pattern */ + /* With some work, we could separate the stroking + * or non-stroking pattern here as actually needed. */ _cairo_output_stream_printf (output, - "/Pattern cs /res%d scn /a%d gs\r\n", - pattern_id, alpha); + "/Pattern CS /res%d SCN " + "/Pattern cs /res%d scn " + "/a%d gs\r\n", + pattern_id, pattern_id, alpha); return CAIRO_STATUS_SUCCESS; } @@ -1238,13 +1255,17 @@ emit_radial_pattern (cairo_pdf_surface_t *surface, cairo_radial_pattern_t *patte alpha = _cairo_pdf_surface_add_alpha (surface, 1.0); /* Use pattern */ + /* With some work, we could separate the stroking + * or non-stroking pattern here as actually needed. */ _cairo_output_stream_printf (output, - "/Pattern cs /res%d scn /a%d gs\r\n", - pattern_id, alpha); + "/Pattern CS /res%d SCN " + "/Pattern cs /res%d scn " + "/a%d gs\r\n", + pattern_id, pattern_id, alpha); return CAIRO_STATUS_SUCCESS; } - + static cairo_status_t emit_pattern (cairo_pdf_surface_t *surface, cairo_pattern_t *pattern) { @@ -1965,10 +1986,12 @@ _cairo_pdf_document_add_page (cairo_pdf_document_t *document, " /ExtGState <<\r\n"); for (i = 0; i < num_alphas; i++) { + /* With some work, we could separate the stroking + * or non-stroking alpha here as actually needed. */ _cairo_array_copy_element (&surface->alphas, i, &alpha); _cairo_output_stream_printf (output, - " /a%d << /ca %f >>\r\n", - i, alpha); + " /a%d << /CA %f /ca %f >>\r\n", + i, alpha, alpha); } _cairo_output_stream_printf (output, @@ -2102,6 +2125,71 @@ _cairo_pdf_surface_mask (void *abstract_surface, return CAIRO_INT_STATUS_UNSUPPORTED; } +static int +_cairo_pdf_line_cap (cairo_line_cap_t cap) +{ + switch (cap) { + case CAIRO_LINE_CAP_BUTT: + return 0; + case CAIRO_LINE_CAP_ROUND: + return 1; + case CAIRO_LINE_CAP_SQUARE: + return 2; + default: + ASSERT_NOT_REACHED; + return 0; + } +} + +static int +_cairo_pdf_line_join (cairo_line_join_t join) +{ + switch (join) { + case CAIRO_LINE_JOIN_MITER: + return 0; + case CAIRO_LINE_JOIN_ROUND: + return 1; + case CAIRO_LINE_JOIN_BEVEL: + return 2; + default: + ASSERT_NOT_REACHED; + return 0; + } +} + +static cairo_status_t +_cairo_pdf_surface_emit_stroke_style (cairo_pdf_surface_t *surface, + cairo_output_stream_t *stream, + cairo_stroke_style_t *style) +{ + _cairo_output_stream_printf (stream, + "%f w\r\n", + style->line_width); + + _cairo_output_stream_printf (stream, + "%d J\r\n", + _cairo_pdf_line_cap (style->line_cap)); + + _cairo_output_stream_printf (stream, + "%d j\r\n", + _cairo_pdf_line_join (style->line_join)); + + if (style->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]); + _cairo_output_stream_printf (stream, "] %f d\r\n", + style->dash_offset); + } + + _cairo_output_stream_printf (stream, + "%f M ", + style->miter_limit); + + return _cairo_output_stream_get_status (stream); +} + static cairo_int_status_t _cairo_pdf_surface_stroke (void *abstract_surface, cairo_operator_t op, @@ -2114,13 +2202,41 @@ _cairo_pdf_surface_stroke (void *abstract_surface, cairo_antialias_t antialias) { cairo_pdf_surface_t *surface = abstract_surface; + cairo_pdf_document_t *document = surface->document; + cairo_status_t status; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_INT_STATUS_UNSUPPORTED; + return _analyze_operation (surface, op, source); - ASSERT_NOT_REACHED; + assert (_operation_supported (surface, op, source)); - return CAIRO_INT_STATUS_UNSUPPORTED; + status = emit_pattern (surface, source); + if (status) + return status; + + /* After emitting the pattern the current stream should belong to + * this surface, so no need to _cairo_pdf_surface_ensure_stream() + */ + assert (document->current_stream != NULL && + document->current_stream == surface->current_stream); + + status = _cairo_pdf_surface_emit_stroke_style (surface, + document->output_stream, + style); + if (status) + return status; + + status = _cairo_path_fixed_interpret (path, + CAIRO_DIRECTION_FORWARD, + _cairo_pdf_path_move_to, + _cairo_pdf_path_line_to, + _cairo_pdf_path_curve_to, + _cairo_pdf_path_close_path, + document->output_stream); + + _cairo_output_stream_printf (document->output_stream, "S\r\n"); + + return status; } static cairo_int_status_t |