[cairo-commit] 2 commits - src/cairo-pdf-operators.c src/cairo-pdf-operators-private.h src/cairo-pdf-surface.c src/cairo-ps-surface.c
Adrian Johnson
ajohnson at kemper.freedesktop.org
Tue Jul 8 06:28:36 PDT 2008
src/cairo-pdf-operators-private.h | 16 +++++++++
src/cairo-pdf-operators.c | 63 +++++++++++++++++++++++++++++---------
src/cairo-pdf-surface.c | 4 ++
src/cairo-ps-surface.c | 5 +++
4 files changed, 74 insertions(+), 14 deletions(-)
New commits:
commit 7127089fe67690db997f86fd89b71820aa4fcdf0
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Jul 8 22:46:04 2008 +0930
PDF/PS: Remember the current line style
So we don't need to emit line style parameters that are already set.
diff --git a/src/cairo-pdf-operators-private.h b/src/cairo-pdf-operators-private.h
index 0894047..1c23da5 100644
--- a/src/cairo-pdf-operators-private.h
+++ b/src/cairo-pdf-operators-private.h
@@ -82,6 +82,14 @@ typedef struct _cairo_pdf_operators {
int hex_width;
int num_glyphs;
cairo_pdf_glyph_t glyphs[PDF_GLYPH_BUFFER_SIZE];
+
+ /* PDF line style */
+ cairo_bool_t has_line_style;
+ double line_width;
+ cairo_line_cap_t line_cap;
+ cairo_line_join_t line_join;
+ double miter_limit;
+ cairo_bool_t has_dashes;
} cairo_pdf_operators_t;
cairo_private void
@@ -119,6 +127,11 @@ _cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
cairo_fill_rule_t fill_rule);
cairo_private cairo_int_status_t
+_cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
+ cairo_stroke_style_t *style,
+ double scale);
+
+cairo_private cairo_int_status_t
_cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index 4fd15a7..e20b38f 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -64,6 +64,7 @@ _cairo_pdf_operators_init (cairo_pdf_operators_t *pdf_operators,
pdf_operators->use_font_subset_closure = NULL;
pdf_operators->in_text_object = FALSE;
pdf_operators->num_glyphs = 0;
+ pdf_operators->has_line_style = FALSE;
}
cairo_status_t
@@ -90,6 +91,7 @@ _cairo_pdf_operators_set_stream (cairo_pdf_operators_t *pdf_operators,
cairo_output_stream_t *stream)
{
pdf_operators->stream = stream;
+ pdf_operators->has_line_style = FALSE;
}
void
@@ -97,6 +99,7 @@ _cairo_pdf_operators_set_cairo_to_pdf_matrix (cairo_pdf_operators_t *pdf_operato
cairo_matrix_t *cairo_to_pdf)
{
pdf_operators->cairo_to_pdf = *cairo_to_pdf;
+ pdf_operators->has_line_style = FALSE;
}
/* Finish writing out any pending commands to the stream. This
@@ -134,6 +137,7 @@ _cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators)
void
_cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators)
{
+ pdf_operators->has_line_style = FALSE;
}
/* A word wrap stream can be used as a filter to do word wrapping on
@@ -526,7 +530,7 @@ _cairo_pdf_line_join (cairo_line_join_t join)
}
}
-static cairo_int_status_t
+cairo_int_status_t
_cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
cairo_stroke_style_t *style,
double scale)
@@ -534,6 +538,7 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
double *dash = style->dash;
int num_dashes = style->num_dashes;
double dash_offset = style->dash_offset;
+ double line_width = style->line_width * scale;
/* PostScript has "special needs" when it comes to zero-length
* dash segments with butt caps. It apparently (at least
@@ -598,17 +603,26 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
}
}
- _cairo_output_stream_printf (pdf_operators->stream,
- "%f w\n",
- style->line_width * scale);
+ if (!pdf_operators->has_line_style || pdf_operators->line_width != line_width) {
+ _cairo_output_stream_printf (pdf_operators->stream,
+ "%f w\n",
+ line_width);
+ pdf_operators->line_width = line_width;
+ }
- _cairo_output_stream_printf (pdf_operators->stream,
- "%d J\n",
- _cairo_pdf_line_cap (style->line_cap));
+ if (!pdf_operators->has_line_style || pdf_operators->line_cap != style->line_cap) {
+ _cairo_output_stream_printf (pdf_operators->stream,
+ "%d J\n",
+ _cairo_pdf_line_cap (style->line_cap));
+ pdf_operators->line_cap = style->line_cap;
+ }
- _cairo_output_stream_printf (pdf_operators->stream,
- "%d j\n",
- _cairo_pdf_line_join (style->line_join));
+ if (!pdf_operators->has_line_style || pdf_operators->line_join != style->line_join) {
+ _cairo_output_stream_printf (pdf_operators->stream,
+ "%d j\n",
+ _cairo_pdf_line_join (style->line_join));
+ pdf_operators->line_join = style->line_join;
+ }
if (num_dashes) {
int d;
@@ -618,15 +632,21 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
_cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d] * scale);
_cairo_output_stream_printf (pdf_operators->stream, "] %f d\n",
dash_offset * scale);
- } else {
+ pdf_operators->has_dashes = TRUE;
+ } else if (!pdf_operators->has_line_style || pdf_operators->has_dashes) {
_cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\n");
+ pdf_operators->has_dashes = FALSE;
}
if (dash != style->dash)
free (dash);
- _cairo_output_stream_printf (pdf_operators->stream,
- "%f M ",
- style->miter_limit < 1.0 ? 1.0 : style->miter_limit);
+ if (!pdf_operators->has_line_style || pdf_operators->miter_limit != style->miter_limit) {
+ _cairo_output_stream_printf (pdf_operators->stream,
+ "%f M ",
+ style->miter_limit < 1.0 ? 1.0 : style->miter_limit);
+ pdf_operators->miter_limit = style->miter_limit;
+ }
+ pdf_operators->has_line_style = TRUE;
return _cairo_output_stream_get_status (pdf_operators->stream);
}
commit 837bf73f082f3bb0158b57cf7c456380531853b3
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Tue Jul 8 22:00:15 2008 +0930
Add PDF operators function to reset any remembered state
diff --git a/src/cairo-pdf-operators-private.h b/src/cairo-pdf-operators-private.h
index b482335..0894047 100644
--- a/src/cairo-pdf-operators-private.h
+++ b/src/cairo-pdf-operators-private.h
@@ -110,6 +110,9 @@ _cairo_pdf_operators_set_cairo_to_pdf_matrix (cairo_pdf_operators_t *pdf_operato
cairo_private cairo_status_t
_cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators);
+cairo_private void
+_cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators);
+
cairo_private cairo_int_status_t
_cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
cairo_path_fixed_t *path,
diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index da01919..4fd15a7 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -121,6 +121,21 @@ _cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators)
return status;
}
+/* Reset the known graphics state of the PDF consumer. ie no
+ * assumptions will be made about the state. The next time a
+ * particular graphics state is required (eg line width) the state
+ * operator is always emitted and then remembered for subsequent
+ * operatations.
+ *
+ * This should be called when starting a new stream or after emitting
+ * the 'Q' operator (where pdf-operators functions were called inside
+ * the q/Q pair).
+ */
+void
+_cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators)
+{
+}
+
/* A word wrap stream can be used as a filter to do word wrapping on
* top of an existing output stream. The word wrapping is quite
* simple, using isspace to determine characters that separate
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index f68b696..1d1407c 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -870,6 +870,7 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
surface->pdf_stream.length = length;
surface->pdf_stream.compressed = compressed;
surface->current_pattern_is_solid_color = FALSE;
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
@@ -1006,6 +1007,7 @@ _cairo_pdf_surface_open_group (cairo_pdf_surface_t *surface,
surface->group_stream.active = TRUE;
surface->current_pattern_is_solid_color = FALSE;
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
surface->group_stream.mem_stream = _cairo_memory_stream_create ();
@@ -2722,6 +2724,7 @@ _cairo_pdf_surface_unselect_pattern (cairo_pdf_surface_t *surface)
return status;
_cairo_output_stream_printf (surface->output, "Q\n");
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
}
surface->select_pattern_gstate_saved = FALSE;
@@ -2783,6 +2786,7 @@ _cairo_pdf_surface_intersect_clip_path (void *abstract_surface,
_cairo_output_stream_printf (surface->output, "Q q\n");
surface->current_pattern_is_solid_color = FALSE;
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index aa93f1e..e6ce3f3 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -2031,6 +2031,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
surface->width = meta_extents.width;
surface->height = meta_extents.height;
surface->current_pattern_is_solid_color = FALSE;
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
&surface->cairo_to_ps);
@@ -2064,6 +2065,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
surface->width = old_width;
surface->height = old_height;
surface->current_pattern_is_solid_color = FALSE;
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
surface->cairo_to_ps = old_cairo_to_ps;
status = _cairo_surface_set_clip (&surface->base, old_clip);
if (status)
@@ -2901,6 +2903,7 @@ _cairo_ps_surface_intersect_clip_path (void *abstract_surface,
_cairo_output_stream_printf (stream, "Q q\n");
surface->current_pattern_is_solid_color = FALSE;
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
return CAIRO_STATUS_SUCCESS;
}
@@ -3079,6 +3082,7 @@ _cairo_ps_surface_fill (void *abstract_surface,
return status;
_cairo_output_stream_printf (surface->stream, "Q\n");
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
} else {
status = _cairo_ps_surface_emit_pattern (surface, source, op);
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
@@ -3207,6 +3211,7 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
surface->bbox_y2 = y2;
}
surface->current_pattern_is_solid_color = FALSE;
+ _cairo_pdf_operators_reset (&surface->pdf_operators);
return _cairo_output_stream_get_status (surface->stream);
}
More information about the cairo-commit
mailing list