mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-08 03:18:05 +02:00
Make PS backend use cairo-pdf-operators.c
Changes include: - Replace PS prolog with new prolog that emulates PDF operators - Remove the [1 0 0 -1 0 height] ctm on each page. PS and PDF surfaces now both transform all output to PS/PDF coordinates. - Invert images to match PDF images where (0,0) is top left - emit_surface_pattern now uses the same transform as PDF - move the special dash handling into cairo-pdf-operators.c
This commit is contained in:
parent
49f755ed2d
commit
6f9d71c10b
3 changed files with 219 additions and 634 deletions
|
|
@ -406,6 +406,73 @@ static cairo_int_status_t
|
|||
_cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
|
||||
cairo_stroke_style_t *style)
|
||||
{
|
||||
double *dash = style->dash;
|
||||
int num_dashes = style->num_dashes;
|
||||
double dash_offset = style->dash_offset;
|
||||
|
||||
/* PostScript has "special needs" when it comes to zero-length
|
||||
* dash segments with butt caps. It apparently (at least
|
||||
* according to ghostscript) draws hairlines for this
|
||||
* case. That's not what the cairo semantics want, so we first
|
||||
* touch up the array to eliminate any 0.0 values that will
|
||||
* result in "on" segments.
|
||||
*/
|
||||
if (num_dashes && style->line_cap == CAIRO_LINE_CAP_BUTT) {
|
||||
int i;
|
||||
|
||||
/* If there's an odd number of dash values they will each get
|
||||
* interpreted as both on and off. So we first explicitly
|
||||
* expand the array to remove the duplicate usage so that we
|
||||
* can modify some of the values.
|
||||
*/
|
||||
if (num_dashes % 2) {
|
||||
dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double));
|
||||
if (dash == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memcpy (dash, style->dash, num_dashes * sizeof (double));
|
||||
memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double));
|
||||
|
||||
num_dashes *= 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_dashes; i += 2) {
|
||||
if (dash[i] == 0.0) {
|
||||
/* If we're at the front of the list, we first rotate
|
||||
* two elements from the end of the list to the front
|
||||
* of the list before folding away the 0.0. Or, if
|
||||
* there are only two dash elements, then there is
|
||||
* nothing at all to draw.
|
||||
*/
|
||||
if (i == 0) {
|
||||
double last_two[2];
|
||||
|
||||
if (num_dashes == 2) {
|
||||
if (dash != style->dash)
|
||||
free (dash);
|
||||
return CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||
}
|
||||
/* The cases of num_dashes == 0, 1, or 3 elements
|
||||
* cannot exist, so the rotation of 2 elements
|
||||
* will always be safe */
|
||||
memcpy (last_two, dash + num_dashes - 2, sizeof (last_two));
|
||||
memmove (dash + 2, dash, (num_dashes - 2) * sizeof (double));
|
||||
memcpy (dash, last_two, sizeof (last_two));
|
||||
dash_offset += dash[0] + dash[1];
|
||||
i = 2;
|
||||
}
|
||||
dash[i-1] += dash[i+1];
|
||||
num_dashes -= 2;
|
||||
memmove (dash + i, dash + i + 2, (num_dashes - i) * sizeof (double));
|
||||
/* If we might have just rotated, it's possible that
|
||||
* we rotated a 0.0 value to the front of the list.
|
||||
* Set i to -2 so it will get incremented to 0. */
|
||||
if (i == 2)
|
||||
i = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (pdf_operators->stream,
|
||||
"%f w\r\n",
|
||||
style->line_width);
|
||||
|
|
@ -418,16 +485,19 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
|
|||
"%d j\r\n",
|
||||
_cairo_pdf_line_join (style->line_join));
|
||||
|
||||
if (style->num_dashes) {
|
||||
unsigned int d;
|
||||
if (num_dashes) {
|
||||
int d;
|
||||
|
||||
_cairo_output_stream_printf (pdf_operators->stream, "[");
|
||||
for (d = 0; d < style->num_dashes; d++)
|
||||
_cairo_output_stream_printf (pdf_operators->stream, " %f", style->dash[d]);
|
||||
for (d = 0; d < num_dashes; d++)
|
||||
_cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d]);
|
||||
_cairo_output_stream_printf (pdf_operators->stream, "] %f d\r\n",
|
||||
style->dash_offset);
|
||||
dash_offset);
|
||||
} else {
|
||||
_cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\r\n");
|
||||
}
|
||||
if (dash != style->dash)
|
||||
free (dash);
|
||||
|
||||
_cairo_output_stream_printf (pdf_operators->stream,
|
||||
"%f M ",
|
||||
|
|
@ -448,6 +518,8 @@ _cairo_pdf_operator_stroke (cairo_pdf_operators_t *pdf_operators,
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2003 University of Southern California
|
||||
|
|
@ -43,6 +44,7 @@
|
|||
#include "cairo-ps.h"
|
||||
|
||||
#include "cairo-surface-private.h"
|
||||
#include "cairo-pdf-operators-private.h"
|
||||
|
||||
typedef struct cairo_ps_surface {
|
||||
cairo_surface_t base;
|
||||
|
|
@ -62,6 +64,7 @@ typedef struct cairo_ps_surface {
|
|||
double width;
|
||||
double height;
|
||||
int bbox_x1, bbox_y1, bbox_x2, bbox_y2;
|
||||
cairo_matrix_t cairo_to_ps;
|
||||
|
||||
int num_pages;
|
||||
|
||||
|
|
@ -80,6 +83,7 @@ typedef struct cairo_ps_surface {
|
|||
cairo_ps_level_t ps_level;
|
||||
cairo_ps_level_t ps_level_used;
|
||||
|
||||
cairo_pdf_operators_t pdf_operators;
|
||||
cairo_surface_t *paginated_surface;
|
||||
} cairo_ps_surface_t;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue