PDF: Remember the current color

Don't emit the set fill or stroke color operator if the required fill
or stroke color is already selected.
This commit is contained in:
Adrian Johnson 2008-06-03 20:55:30 +09:30
parent fd42b74a4f
commit 6258f1a4e2
2 changed files with 59 additions and 19 deletions

View file

@ -153,6 +153,13 @@ struct _cairo_pdf_surface {
cairo_bool_t force_fallbacks;
cairo_bool_t current_pattern_is_solid_color;
cairo_bool_t current_color_is_stroke;
double current_color_red;
double current_color_green;
double current_color_blue;
double current_color_alpha;
cairo_surface_t *paginated_surface;
};

View file

@ -281,6 +281,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
surface->force_fallbacks = FALSE;
surface->select_pattern_gstate_saved = FALSE;
surface->current_pattern_is_solid_color = FALSE;
_cairo_pdf_operators_init (&surface->pdf_operators,
surface->output,
@ -863,6 +864,7 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
surface->pdf_stream.self = self;
surface->pdf_stream.length = length;
surface->pdf_stream.compressed = compressed;
surface->current_pattern_is_solid_color = FALSE;
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
@ -998,6 +1000,7 @@ _cairo_pdf_surface_open_group (cairo_pdf_surface_t *surface,
assert (surface->group_stream.active == FALSE);
surface->group_stream.active = TRUE;
surface->current_pattern_is_solid_color = FALSE;
surface->group_stream.mem_stream = _cairo_memory_stream_create ();
@ -2592,10 +2595,6 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
cairo_bool_t is_solid_color = FALSE;
cairo_color_t *solid_color;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status)
return status;
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
@ -2615,24 +2614,51 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
}
if (is_solid_color) {
status = _cairo_pdf_surface_add_alpha (surface, solid_color->alpha, &alpha);
if (status)
return status;
if (surface->current_pattern_is_solid_color == FALSE ||
surface->current_color_red != solid_color->red ||
surface->current_color_green != solid_color->green ||
surface->current_color_blue != solid_color->blue ||
surface->current_color_is_stroke != is_stroke)
{
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status)
return status;
_cairo_output_stream_printf (surface->output,
"%f %f %f ",
solid_color->red,
solid_color->green,
solid_color->blue);
_cairo_output_stream_printf (surface->output,
"%f %f %f ",
solid_color->red,
solid_color->green,
solid_color->blue);
if (is_stroke)
_cairo_output_stream_printf (surface->output, "RG ");
else
_cairo_output_stream_printf (surface->output, "rg ");
if (is_stroke)
_cairo_output_stream_printf (surface->output, "RG ");
else
_cairo_output_stream_printf (surface->output, "rg ");
_cairo_output_stream_printf (surface->output,
"/a%d gs\n",
alpha);
surface->current_color_red = solid_color->red;
surface->current_color_green = solid_color->green;
surface->current_color_blue = solid_color->blue;
surface->current_color_is_stroke = is_stroke;
}
if (surface->current_pattern_is_solid_color == FALSE ||
surface->current_color_alpha != solid_color->alpha)
{
status = _cairo_pdf_surface_add_alpha (surface, solid_color->alpha, &alpha);
if (status)
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status)
return status;
_cairo_output_stream_printf (surface->output,
"/a%d gs\n",
alpha);
surface->current_color_alpha = solid_color->alpha;
}
surface->current_pattern_is_solid_color = TRUE;
} else {
status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
if (status)
@ -2642,6 +2668,10 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
if (status)
return status;
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
if (status)
return status;
/* fill-stroke calls select_pattern twice. Don't save if the
* gstate is already saved. */
if (!surface->select_pattern_gstate_saved)
@ -2660,6 +2690,7 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
"/a%d gs\n",
alpha);
surface->select_pattern_gstate_saved = TRUE;
surface->current_pattern_is_solid_color = FALSE;
}
return _cairo_output_stream_get_status (surface->output);
@ -2736,6 +2767,8 @@ _cairo_pdf_surface_intersect_clip_path (void *abstract_surface,
return status;
_cairo_output_stream_printf (surface->output, "Q q\n");
surface->current_pattern_is_solid_color = FALSE;
return CAIRO_STATUS_SUCCESS;
}