summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2006-04-18 16:53:23 -0700
committerCarl Worth <cworth@cworth.org>2006-04-18 16:53:23 -0700
commitb1b699593b820ac4e011f89ad700f052b2f20205 (patch)
tree5a0d3ecbf894620b6d8e662a37d7b2445d39558c /src
parentefbe40bb8f770fbf60de794488803d3edacd7ed6 (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.c144
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