[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