mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-21 20:30:48 +02:00
Use PDF 're' operator for rectangle paths
Modify cairo-pdf-operators.c to emit to 're' path operator when the path contains only a rectangle. This can only be done when the path is logically equivilent to the the path drawn by the 're' operator. Otherwise dashed strokes may start on the wrong line. ie the path must be equivalent to: cairo_move_to (cr, x, y); cairo_rel_line_to (cr, width, 0); cairo_rel_line_to (cr, 0, height); cairo_rel_line_to (cr, -width, 0); cairo_close_path (cr); which is also equivilent to cairo_rectangle().
This commit is contained in:
parent
7acfee38b1
commit
40f4750f5e
4 changed files with 59 additions and 7 deletions
|
|
@ -802,3 +802,27 @@ _cairo_path_fixed_is_box (cairo_path_fixed_t *path,
|
|||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given path contains a single rectangle
|
||||
* that is logically equivalent to:
|
||||
* cairo_move_to (cr, x, y);
|
||||
* cairo_rel_line_to (cr, width, 0);
|
||||
* cairo_rel_line_to (cr, 0, height);
|
||||
* cairo_rel_line_to (cr, -width, 0);
|
||||
* cairo_close_path (cr);
|
||||
*/
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
|
||||
cairo_box_t *box)
|
||||
{
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
|
||||
if (!_cairo_path_fixed_is_box (path, box))
|
||||
return FALSE;
|
||||
|
||||
if (buf->points[0].y == buf->points[1].y)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -328,6 +328,23 @@ _cairo_pdf_path_close_path (void *closure)
|
|||
return _cairo_output_stream_get_status (info->output);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
|
||||
{
|
||||
double x1 = _cairo_fixed_to_double (box->p1.x);
|
||||
double y1 = _cairo_fixed_to_double (box->p1.y);
|
||||
double x2 = _cairo_fixed_to_double (box->p2.x);
|
||||
double y2 = _cairo_fixed_to_double (box->p2.y);
|
||||
|
||||
cairo_matrix_transform_point (info->path_transform, &x1, &y1);
|
||||
cairo_matrix_transform_point (info->path_transform, &x2, &y2);
|
||||
_cairo_output_stream_printf (info->output,
|
||||
"%f %f %f %f re ",
|
||||
x1, y1, x2 - x1, y2 - y1);
|
||||
|
||||
return _cairo_output_stream_get_status (info->output);
|
||||
}
|
||||
|
||||
/* The line cap value is needed to workaround the fact that PostScript
|
||||
* and PDF semantics for stroking degenerate sub-paths do not match
|
||||
* cairo semantics. (PostScript draws something for any line cap
|
||||
|
|
@ -346,6 +363,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
|
|||
cairo_output_stream_t *word_wrap;
|
||||
cairo_status_t status, status2;
|
||||
pdf_path_info_t info;
|
||||
cairo_box_t box;
|
||||
|
||||
word_wrap = _word_wrap_stream_create (pdf_operators->stream, 79);
|
||||
status = _cairo_output_stream_get_status (word_wrap);
|
||||
|
|
@ -355,13 +373,17 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
|
|||
info.output = word_wrap;
|
||||
info.path_transform = path_transform;
|
||||
info.line_cap = line_cap;
|
||||
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,
|
||||
&info);
|
||||
if (_cairo_path_fixed_is_rectangle (path, &box)) {
|
||||
status = _cairo_pdf_path_rectangle (&info, &box);
|
||||
} else {
|
||||
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,
|
||||
&info);
|
||||
}
|
||||
|
||||
status2 = _cairo_output_stream_destroy (word_wrap);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
|
|||
"/l { lineto } bind def\n"
|
||||
"/c { curveto } bind def\n"
|
||||
"/h { closepath } bind def\n"
|
||||
"/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto\n"
|
||||
" 0 exch rlineto 0 rlineto closepath } bind def\n"
|
||||
"/S { stroke } bind def\n"
|
||||
"/f { fill } bind def\n"
|
||||
"/f* { eofill } bind def\n"
|
||||
|
|
|
|||
|
|
@ -1399,6 +1399,10 @@ cairo_private cairo_bool_t
|
|||
_cairo_path_fixed_is_box (cairo_path_fixed_t *path,
|
||||
cairo_box_t *box);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
|
||||
cairo_box_t *box);
|
||||
|
||||
/* cairo_path_fill.c */
|
||||
cairo_private cairo_status_t
|
||||
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue