📄 cairo-ps-surface.c
字号:
width_in_points, height_in_points);}static cairo_bool_t_cairo_surface_is_ps (cairo_surface_t *surface){ return surface->backend == &cairo_ps_surface_backend;}/* If the abstract_surface is a paginated surface, and that paginated * surface's target is a ps_surface, then set ps_surface to that * target. Otherwise return CAIRO_STATUS_SURFACE_TYPE_MISMATCH. */static cairo_status_t_extract_ps_surface (cairo_surface_t *surface, cairo_ps_surface_t **ps_surface){ cairo_surface_t *target; if (! _cairo_surface_is_paginated (surface)) return CAIRO_STATUS_SURFACE_TYPE_MISMATCH; target = _cairo_paginated_surface_get_target (surface); if (! _cairo_surface_is_ps (target)) return CAIRO_STATUS_SURFACE_TYPE_MISMATCH; *ps_surface = (cairo_ps_surface_t *) target; return CAIRO_STATUS_SUCCESS;}/** * cairo_ps_surface_set_size: * @surface: a PostScript cairo_surface_t * @width_in_points: new surface width, in points (1 point == 1/72.0 inch) * @height_in_points: new surface height, in points (1 point == 1/72.0 inch) * * Changes the size of a PostScript surface for the current (and * subsequent) pages. * * This function should only be called before any drawing operations * have been performed on the current page. The simplest way to do * this is to call this function immediately after creating the * surface or immediately after completing a page with either * cairo_show_page() or cairo_copy_page(). * * Since: 1.2 **/voidcairo_ps_surface_set_size (cairo_surface_t *surface, double width_in_points, double height_in_points){ cairo_ps_surface_t *ps_surface; cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); if (status) { _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH); return; } ps_surface->width = width_in_points; ps_surface->height = height_in_points;}/** * cairo_ps_surface_dsc_comment: * @surface: a PostScript cairo_surface_t * @comment: a comment string to be emitted into the PostScript output * * Emit a comment into the PostScript output for the given surface. * * The comment is expected to conform to the PostScript Language * Document Structuring Conventions (DSC). Please see that manual for * details on the available comments and their meanings. In * particular, the %%IncludeFeature comment allows a * device-independent means of controlling printer device features. So * the PostScript Printer Description Files Specification will also be * a useful reference. * * The comment string must begin with a percent character (%) and the * total length of the string (including any initial percent * characters) must not exceed 255 characters. Violating either of * these conditions will place @surface into an error state. But * beyond these two conditions, this function will not enforce * conformance of the comment with any particular specification. * * The comment string should not have a trailing newline. * * The DSC specifies different sections in which particular comments * can appear. This function provides for comments to be emitted * within three sections: the header, the Setup section, and the * PageSetup section. Comments appearing in the first two sections * apply to the entire document while comments in the BeginPageSetup * section apply only to a single page. * * For comments to appear in the header section, this function should * be called after the surface is created, but before a call to * cairo_ps_surface_begin_setup(). * * For comments to appear in the Setup section, this function should * be called after a call to cairo_ps_surface_begin_setup() but before * a call to cairo_ps_surface_begin_page_setup(). * * For comments to appear in the PageSetup section, this function * should be called after a call to cairo_ps_surface_begin_page_setup(). * * Note that it is only necessary to call cairo_ps_surface_begin_page_setup() * for the first page of any surface. After a call to * cairo_show_page() or cairo_copy_page() comments are unambiguously * directed to the PageSetup section of the current page. But it * doesn't hurt to call this function at the beginning of every page * as that consistency may make the calling code simpler. * * As a final note, cairo automatically generates several comments on * its own. As such, applications must not manually generate any of * the following comments: * * Header section: %!PS-Adobe-3.0, %%Creator, %%CreationDate, %%Pages, * %%BoundingBox, %%DocumentData, %%LanguageLevel, %%EndComments. * * Setup section: %%BeginSetup, %%EndSetup * * PageSetup section: %%BeginPageSetup, %%PageBoundingBox, * %%EndPageSetup. * * Other sections: %%BeginProlog, %%EndProlog, %%Page, %%Trailer, %%EOF * * Here is an example sequence showing how this function might be used: * * <informalexample><programlisting> * cairo_surface_t *surface = cairo_ps_surface_create (filename, width, height); * ... * cairo_ps_surface_dsc_comment (surface, "%%Title: My excellent document"); * cairo_ps_surface_dsc_comment (surface, "%%Copyright: Copyright (C) 2006 Cairo Lover") * ... * cairo_ps_surface_dsc_begin_setup (surface); * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaColor White"); * ... * cairo_ps_surface_dsc_begin_page_setup (surface); * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *PageSize A3"); * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *InputSlot LargeCapacity"); * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaType Glossy"); * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaColor Blue"); * ... draw to first page here .. * cairo_show_page (cr); * ... * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *PageSize A5"); * ... * </programlisting></informalexample> * * Since: 1.2 **/voidcairo_ps_surface_dsc_comment (cairo_surface_t *surface, const char *comment){ cairo_ps_surface_t *ps_surface; cairo_status_t status; char *comment_copy; status = _extract_ps_surface (surface, &ps_surface); if (status) { _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH); return; } /* A couple of sanity checks on the comment value. */ if (comment == NULL) { _cairo_surface_set_error (surface, CAIRO_STATUS_NULL_POINTER); return; } if (comment[0] != '%' || strlen (comment) > 255) { _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_DSC_COMMENT); return; } /* Then, copy the comment and store it in the appropriate array. */ comment_copy = strdup (comment); if (comment_copy == NULL) { _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY); return; } status = _cairo_array_append (ps_surface->dsc_comment_target, &comment_copy); if (status) { free (comment_copy); _cairo_surface_set_error (surface, status); return; }}/** * cairo_ps_surface_dsc_begin_setup: * @surface: a PostScript cairo_surface_t * * This function indicates that subsequent calls to * cairo_ps_surface_dsc_comment() should direct comments to the Setup * section of the PostScript output. * * This function should be called at most once per surface, and must * be called before any call to cairo_ps_surface_dsc_begin_page_setup() * and before any drawing is performed to the surface. * * See cairo_ps_surface_dsc_comment() for more details. * * Since: 1.2 **/voidcairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface){ cairo_ps_surface_t *ps_surface; cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); if (status) { _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH); return; } if (ps_surface->dsc_comment_target == &ps_surface->dsc_header_comments) { ps_surface->dsc_comment_target = &ps_surface->dsc_setup_comments; }}/** * cairo_ps_surface_dsc_begin_page_setup: * @surface: a PostScript cairo_surface_t * * This function indicates that subsequent calls to * cairo_ps_surface_dsc_comment() should direct comments to the * PageSetup section of the PostScript output. * * This function call is only needed for the first page of a * surface. It should be called after any call to * cairo_ps_surface_dsc_begin_setup() and before any drawing is * performed to the surface. * * See cairo_ps_surface_dsc_comment() for more details. * * Since: 1.2 **/voidcairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface){ cairo_ps_surface_t *ps_surface; cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); if (status) { _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_TYPE_MISMATCH); return; } if (ps_surface->dsc_comment_target == &ps_surface->dsc_header_comments || ps_surface->dsc_comment_target == &ps_surface->dsc_setup_comments) { ps_surface->dsc_comment_target = &ps_surface->dsc_page_setup_comments; }}static cairo_surface_t *_cairo_ps_surface_create_similar (void *abstract_src, cairo_content_t content, int width, int height){ cairo_format_t format = _cairo_format_from_content (content); /* Just return an image for now, until PS surface can be used * as source. */ return cairo_image_surface_create (format, width, height);}static cairo_status_t_cairo_ps_surface_finish (void *abstract_surface){ cairo_status_t status; cairo_ps_surface_t *surface = abstract_surface; int i, num_comments; char **comments; _cairo_ps_surface_emit_header (surface); _cairo_ps_surface_emit_font_subsets (surface); _cairo_ps_surface_emit_body (surface); _cairo_ps_surface_emit_footer (surface); _cairo_output_stream_close (surface->stream); status = _cairo_output_stream_get_status (surface->stream); _cairo_output_stream_destroy (surface->stream); fclose (surface->tmpfile); _cairo_output_stream_close (surface->final_stream); if (status == CAIRO_STATUS_SUCCESS) status = _cairo_output_stream_get_status (surface->final_stream); _cairo_output_stream_destroy (surface->final_stream); 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++) free (comments[i]); _cairo_array_fini (&surface->dsc_header_comments); num_comments = _cairo_array_num_elements (&surface->dsc_setup_comments); comments = _cairo_array_index (&surface->dsc_setup_comments, 0); for (i = 0; i < num_comments; i++) free (comments[i]); _cairo_array_fini (&surface->dsc_setup_comments); 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++) free (comments[i]); _cairo_array_fini (&surface->dsc_page_setup_comments); return status;}static cairo_int_status_t_cairo_ps_surface_start_page (void *abstract_surface){ cairo_ps_surface_t *surface = abstract_surface; int i, num_comments; char **comments; /* Increment before print so page numbers start at 1. */ surface->num_pages++; _cairo_output_stream_printf (surface->stream, "%%%%Page: %d %d\n", surface->num_pages, surface->num_pages); _cairo_output_stream_printf (surface->stream, "%%%%BeginPageSetup\n"); 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]); free (comments[i]); comments[i] = NULL; } _cairo_array_truncate (&surface->dsc_page_setup_comments, 0); _cairo_output_stream_printf (surface->stream, "%%%%PageBoundingBox: %d %d %d %d\n", 0, 0, (int) ceil (surface->width), (int) ceil (surface->height)); _cairo_output_stream_printf (surface->stream, "gsave %f %f translate 1.0 -1.0 scale \n", 0.0, surface->height); _cairo_output_stream_printf (surface->stream, "%%%%EndPageSetup\n"); if (surface->width > surface->max_width) surface->max_width = surface->width; if (surface->height > surface->max_height) surface->max_height = surface->height; return _cairo_output_stream_get_status (surface->stream);}static void_cairo_ps_surface_end_page (cairo_ps_surface_t *surface){ _cairo_output_stream_printf (surface->stream, "grestore\n");}static cairo_int_status_t_cairo_ps_surface_copy_page (void *abstract_surface){ cairo_ps_surface_t *surface = abstract_surface; _cairo_ps_surface_end_page (surface); _cairo_output_stream_printf (surface->stream, "copypage\n"); return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_ps_surface_show_page (void *abstract_surface){ cairo_ps_surface_t *surface = abstract_surface; _cairo_ps_surface_end_page (surface); _cairo_output_stream_printf (surface->stream, "showpage\n"); return CAIRO_STATUS_SUCCESS;}static cairo_bool_tcolor_is_gray (cairo_color_t *color){ const double epsilon = 0.00001; return (fabs (color->red - color->green) < epsilon && fabs (color->red - color->blue) < epsilon);}static cairo_bool_tsurface_pattern_supported (const cairo_surface_pattern_t *pattern){ if (pattern->surface->backend->acquire_source_image != NULL) return TRUE; return FALSE;}static cairo_bool_tpattern_supported (const cairo_pattern_t *pattern){ if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) return TRUE; if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -