mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-09 07:18:04 +02:00
PS: Add DocumentMedia/PageMedia DSC comments
Provide default DocumentMedia and PageMedia DSC comments if the user does not specify them using cairo_ps_surface_dsc_comment(). This is required so that PostScript viewers such as gv use the correct page size.
This commit is contained in:
parent
caa9eed464
commit
db5e3db0a9
2 changed files with 89 additions and 0 deletions
|
|
@ -90,6 +90,7 @@ typedef struct cairo_ps_surface {
|
|||
|
||||
cairo_scaled_font_subsets_t *font_subsets;
|
||||
|
||||
cairo_list_t document_media;
|
||||
cairo_array_t dsc_header_comments;
|
||||
cairo_array_t dsc_setup_comments;
|
||||
cairo_array_t dsc_page_setup_comments;
|
||||
|
|
|
|||
|
|
@ -106,6 +106,13 @@ static const char * _cairo_ps_level_strings[CAIRO_PS_LEVEL_LAST] =
|
|||
"PS Level 3"
|
||||
};
|
||||
|
||||
typedef struct _cairo_page_media {
|
||||
char *name;
|
||||
int width;
|
||||
int height;
|
||||
cairo_list_t link;
|
||||
} cairo_page_media_t;
|
||||
|
||||
static void
|
||||
_cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
|
||||
{
|
||||
|
|
@ -149,6 +156,27 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
|
|||
"%%%%LanguageLevel: %d\n",
|
||||
level);
|
||||
|
||||
if (!cairo_list_is_empty (&surface->document_media)) {
|
||||
cairo_page_media_t *page;
|
||||
cairo_bool_t first = TRUE;
|
||||
|
||||
cairo_list_foreach_entry (page, cairo_page_media_t, &surface->document_media, link) {
|
||||
if (first) {
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"%%%%DocumentMedia: ");
|
||||
first = FALSE;
|
||||
} else {
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"%%%%+ ");
|
||||
}
|
||||
_cairo_output_stream_printf (surface->final_stream,
|
||||
"%s %d %d 0 () ()\n",
|
||||
page->name,
|
||||
page->width,
|
||||
page->height);
|
||||
}
|
||||
}
|
||||
|
||||
num_comments = _cairo_array_num_elements (&surface->dsc_header_comments);
|
||||
comments = _cairo_array_index (&surface->dsc_header_comments, 0);
|
||||
for (i = 0; i < num_comments; i++) {
|
||||
|
|
@ -775,6 +803,39 @@ _cairo_ps_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
|||
fill_rule);
|
||||
}
|
||||
|
||||
static const char *
|
||||
_cairo_ps_surface_get_page_media (cairo_ps_surface_t *surface)
|
||||
{
|
||||
int width, height;
|
||||
char buf[50];
|
||||
cairo_page_media_t *page;
|
||||
|
||||
width = _cairo_lround (surface->width);
|
||||
height = _cairo_lround (surface->height);
|
||||
cairo_list_foreach_entry (page, cairo_page_media_t, &surface->document_media, link) {
|
||||
if (page->width == width && page->height == height)
|
||||
return page->name;
|
||||
}
|
||||
|
||||
page = malloc (sizeof (cairo_page_media_t));
|
||||
if (unlikely (page == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf (buf, sizeof (buf), "p%dx%d", width , height);
|
||||
page->name = strdup (buf);
|
||||
if (unlikely (page->name == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
page->width = width;
|
||||
page->height = height;
|
||||
cairo_list_add_tail (&page->link, &surface->document_media);
|
||||
|
||||
return page->name;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
||||
|
|
@ -841,6 +902,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
|||
surface->font_subsets);
|
||||
surface->num_pages = 0;
|
||||
|
||||
cairo_list_init (&surface->document_media);
|
||||
_cairo_array_init (&surface->dsc_header_comments, sizeof (char *));
|
||||
_cairo_array_init (&surface->dsc_setup_comments, sizeof (char *));
|
||||
_cairo_array_init (&surface->dsc_page_setup_comments, sizeof (char *));
|
||||
|
|
@ -1392,6 +1454,17 @@ CLEANUP:
|
|||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = status2;
|
||||
|
||||
while (! cairo_list_is_empty (&surface->document_media)) {
|
||||
cairo_page_media_t *page;
|
||||
|
||||
page = cairo_list_first_entry (&surface->document_media,
|
||||
cairo_page_media_t,
|
||||
link);
|
||||
cairo_list_del (&page->link);
|
||||
free (page->name);
|
||||
free (page);
|
||||
}
|
||||
|
||||
num_comments = _cairo_array_num_elements (&surface->dsc_header_comments);
|
||||
comments = _cairo_array_index (&surface->dsc_header_comments, 0);
|
||||
for (i = 0; i < num_comments; i++)
|
||||
|
|
@ -3563,6 +3636,8 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
|
|||
int i, num_comments;
|
||||
char **comments;
|
||||
int x1, y1, x2, y2;
|
||||
cairo_bool_t has_page_media;
|
||||
const char *page_media;
|
||||
|
||||
if (surface->eps) {
|
||||
x1 = floor (_cairo_fixed_to_double (bbox->p1.x));
|
||||
|
|
@ -3589,16 +3664,29 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
|
|||
_cairo_output_stream_printf (surface->stream,
|
||||
"%%%%BeginPageSetup\n");
|
||||
|
||||
has_page_media = FALSE;
|
||||
num_comments = _cairo_array_num_elements (&surface->dsc_page_setup_comments);
|
||||
comments = _cairo_array_index (&surface->dsc_page_setup_comments, 0);
|
||||
for (i = 0; i < num_comments; i++) {
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"%s\n", comments[i]);
|
||||
if (strncmp (comments[i], "%%PageMedia:", 11) == 0)
|
||||
has_page_media = TRUE;
|
||||
free (comments[i]);
|
||||
comments[i] = NULL;
|
||||
}
|
||||
_cairo_array_truncate (&surface->dsc_page_setup_comments, 0);
|
||||
|
||||
if (!has_page_media && !surface->eps) {
|
||||
page_media = _cairo_ps_surface_get_page_media (surface);
|
||||
if (unlikely (page_media == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"%%%%PageMedia: %s\n",
|
||||
page_media);
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"%%%%PageBoundingBox: %d %d %d %d\n",
|
||||
x1, y1, x2, y2);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue