mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-06 06:10:17 +01:00
Implement PDF fill-stroke
This commit is contained in:
parent
1e7fa4b9f5
commit
2dfe32a0ff
4 changed files with 164 additions and 2 deletions
|
|
@ -744,7 +744,12 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
|||
cairo_command_t *stroke_command;
|
||||
|
||||
stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL;
|
||||
|
||||
if (stroke_command != NULL &&
|
||||
type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL)
|
||||
{
|
||||
if (stroke_command->header.region != region)
|
||||
stroke_command = NULL;
|
||||
}
|
||||
if (stroke_command != NULL &&
|
||||
stroke_command->header.type == CAIRO_COMMAND_STROKE &&
|
||||
_cairo_path_fixed_is_equal (dev_path, _cairo_command_get_path (stroke_command))) {
|
||||
|
|
@ -778,6 +783,14 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
|||
stroke_command->stroke.tolerance * tolerance_multiplier,
|
||||
stroke_command->stroke.antialias);
|
||||
i++;
|
||||
if (type == CAIRO_META_CREATE_REGIONS) {
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
stroke_command->header.region = CAIRO_META_REGION_NATIVE;
|
||||
} else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
|
||||
stroke_command->header.region = CAIRO_META_REGION_IMAGE_FALLBACK;
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
} else
|
||||
status = _cairo_surface_fill (target,
|
||||
command->fill.op,
|
||||
|
|
|
|||
|
|
@ -97,6 +97,14 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
|
|||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule);
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pdf_operators_show_glyphs (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_glyph_t *glyphs,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright © 2004 Red Hat, Inc
|
||||
* Copyright © 2006 Red Hat, Inc
|
||||
* Copyright © 2007 Adrian Johnson
|
||||
* Copyright © 2007, 2008 Adrian Johnson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
|
|
@ -612,6 +612,55 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
|
|||
return _cairo_output_stream_get_status (pdf_operators->stream);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
cairo_stroke_style_t *style,
|
||||
cairo_matrix_t *ctm,
|
||||
cairo_matrix_t *ctm_inverse)
|
||||
{
|
||||
const char *pdf_operator;
|
||||
cairo_status_t status;
|
||||
cairo_matrix_t m;
|
||||
|
||||
status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style);
|
||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
cairo_matrix_multiply (&m, ctm, &pdf_operators->cairo_to_pdf);
|
||||
_cairo_output_stream_printf (pdf_operators->stream,
|
||||
"q %f %f %f %f %f %f cm\r\n",
|
||||
m.xx, m.yx, m.xy, m.yy,
|
||||
m.x0, m.y0);
|
||||
|
||||
status = _cairo_pdf_operators_emit_path (pdf_operators,
|
||||
path,
|
||||
ctm_inverse,
|
||||
style->line_cap);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
switch (fill_rule) {
|
||||
case CAIRO_FILL_RULE_WINDING:
|
||||
pdf_operator = "B";
|
||||
break;
|
||||
case CAIRO_FILL_RULE_EVEN_ODD:
|
||||
pdf_operator = "B*";
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (pdf_operators->stream,
|
||||
"%s Q\r\n",
|
||||
pdf_operator);
|
||||
|
||||
return _cairo_output_stream_get_status (pdf_operators->stream);
|
||||
}
|
||||
|
||||
#define GLYPH_POSITION_TOLERANCE 0.001
|
||||
|
||||
cairo_int_status_t
|
||||
|
|
|
|||
|
|
@ -4455,6 +4455,97 @@ _cairo_pdf_surface_fill (void *abstract_surface,
|
|||
return _cairo_output_stream_get_status (surface->output);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_fill_stroke (void *abstract_surface,
|
||||
cairo_operator_t fill_op,
|
||||
cairo_pattern_t *fill_source,
|
||||
cairo_fill_rule_t fill_rule,
|
||||
double fill_tolerance,
|
||||
cairo_antialias_t fill_antialias,
|
||||
cairo_path_fixed_t *path,
|
||||
cairo_operator_t stroke_op,
|
||||
cairo_pattern_t *stroke_source,
|
||||
cairo_stroke_style_t *stroke_style,
|
||||
cairo_matrix_t *stroke_ctm,
|
||||
cairo_matrix_t *stroke_ctm_inverse,
|
||||
double stroke_tolerance,
|
||||
cairo_antialias_t stroke_antialias)
|
||||
{
|
||||
cairo_pdf_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
cairo_pdf_resource_t fill_pattern_res, stroke_pattern_res, gstate_res;
|
||||
|
||||
/* During analysis we return unsupported and let the _fill and
|
||||
* _stroke functions that are on the fallback path do the analysis
|
||||
* for us. During render we may still encounter unsupported
|
||||
* combinations of fill/stroke patterns. However we can return
|
||||
* unsupported anytime to let the _fill and _stroke functions take
|
||||
* over.
|
||||
*/
|
||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
/* Fill-stroke with patterns requiring an SMask are not currently
|
||||
* implemented. Non opaque stroke patterns are not supported
|
||||
* because the PDF fill-stroke operator does not blend a
|
||||
* transparent stroke with the fill.
|
||||
*/
|
||||
if (fill_source->type == CAIRO_PATTERN_TYPE_LINEAR ||
|
||||
fill_source->type == CAIRO_PATTERN_TYPE_RADIAL)
|
||||
{
|
||||
if (!_cairo_pattern_is_opaque (fill_source))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
if (!_cairo_pattern_is_opaque (stroke_source))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
fill_pattern_res.id = 0;
|
||||
gstate_res.id = 0;
|
||||
status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
|
||||
&fill_pattern_res,
|
||||
&gstate_res);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
assert (gstate_res.id == 0);
|
||||
|
||||
stroke_pattern_res.id = 0;
|
||||
gstate_res.id = 0;
|
||||
status = _cairo_pdf_surface_add_pdf_pattern (surface,
|
||||
stroke_source,
|
||||
&stroke_pattern_res,
|
||||
&gstate_res);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
assert (gstate_res.id == 0);
|
||||
|
||||
/* As PDF has separate graphics state for fill and stroke we can
|
||||
* select both at the same time */
|
||||
status = _cairo_pdf_surface_select_pattern (surface, fill_source,
|
||||
fill_pattern_res, FALSE);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_select_pattern (surface, stroke_source,
|
||||
stroke_pattern_res, TRUE);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_operators_fill_stroke (&surface->pdf_operators,
|
||||
path,
|
||||
fill_rule,
|
||||
stroke_style,
|
||||
stroke_ctm,
|
||||
stroke_ctm_inverse);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
_cairo_pdf_surface_unselect_pattern (surface);
|
||||
|
||||
return _cairo_output_stream_get_status (surface->output);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_show_glyphs (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
|
|
@ -4572,6 +4663,7 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
|||
|
||||
NULL, /* is_compatible */
|
||||
NULL, /* reset */
|
||||
_cairo_pdf_surface_fill_stroke,
|
||||
};
|
||||
|
||||
static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue