⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-ps-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
{    cairo_ps_surface_t *surface = abstract_surface;    cairo_output_stream_t *stream = surface->stream;    cairo_status_t status;    const char *ps_operator;    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)	return CAIRO_STATUS_SUCCESS;    _cairo_output_stream_printf (stream,				 "%% _cairo_ps_surface_intersect_clip_path\n");    if (path == NULL) {	_cairo_output_stream_printf (stream, "initclip\n");	return CAIRO_STATUS_SUCCESS;    }    /* We're "filling" not stroking, so we pass CAIRO_LINE_CAP_ROUND. */    status = _cairo_ps_surface_emit_path (surface, stream, path,					  CAIRO_LINE_CAP_ROUND);    switch (fill_rule) {    case CAIRO_FILL_RULE_WINDING:	ps_operator = "clip";	break;    case CAIRO_FILL_RULE_EVEN_ODD:	ps_operator = "eoclip";	break;    default:	ASSERT_NOT_REACHED;    }    _cairo_output_stream_printf (stream,				 "%s newpath\n",				 ps_operator);    return status;}static cairo_int_status_t_cairo_ps_surface_get_extents (void		       *abstract_surface,			       cairo_rectangle_int16_t *rectangle){    cairo_ps_surface_t *surface = abstract_surface;    rectangle->x = 0;    rectangle->y = 0;    /* XXX: The conversion to integers here is pretty bogus, (not to     * mention the aribitray limitation of width to a short(!). We     * may need to come up with a better interface for get_extents.     */    rectangle->width  = (int) ceil (surface->width);    rectangle->height = (int) ceil (surface->height);    return CAIRO_STATUS_SUCCESS;}static void_cairo_ps_surface_get_font_options (void                  *abstract_surface,				    cairo_font_options_t  *options){    _cairo_font_options_init_default (options);    cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);    cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);}static cairo_int_status_t_cairo_ps_surface_paint (void			*abstract_surface,			 cairo_operator_t	 op,			 cairo_pattern_t	*source){    cairo_ps_surface_t *surface = abstract_surface;    cairo_output_stream_t *stream = surface->stream;    cairo_rectangle_int16_t extents;    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)	return _analyze_operation (surface, op, source);    /* XXX: It would be nice to be able to assert this condition     * here. But, we actually allow one 'cheat' that is used when     * painting the final image-based fallbacks. The final fallbacks     * do have alpha which we support by blending with white. This is     * possible only because there is nothing between the fallback     * images and the paper, nor is anything painted above. */    /*    assert (_operation_supported (op, source));    */    _cairo_output_stream_printf (stream,				 "%% _cairo_ps_surface_paint\n");    _cairo_pattern_get_extents (source, &extents);    emit_pattern (surface, source, extents.x, extents.y);    _cairo_output_stream_printf (stream, "%d %d M\n",				 extents.x, extents.y);    _cairo_output_stream_printf (stream, "%d %d L\n",				 extents.x + extents.width,				 extents.y);    _cairo_output_stream_printf (stream, "%d %d L\n",				 extents.x + extents.width,				 extents.y + extents.height);    _cairo_output_stream_printf (stream, "%d %d L\n",				 extents.x,				 extents.y + extents.height);    _cairo_output_stream_printf (stream, "P F\n");    return CAIRO_STATUS_SUCCESS;}static int_cairo_ps_line_cap (cairo_line_cap_t cap){    switch (cap) {    case CAIRO_LINE_CAP_BUTT:	return 0;    case CAIRO_LINE_CAP_ROUND:	return 1;    case CAIRO_LINE_CAP_SQUARE:	return 2;    default:	ASSERT_NOT_REACHED;	return 0;    }}static int_cairo_ps_line_join (cairo_line_join_t join){    switch (join) {    case CAIRO_LINE_JOIN_MITER:	return 0;    case CAIRO_LINE_JOIN_ROUND:	return 1;    case CAIRO_LINE_JOIN_BEVEL:	return 2;    default:	ASSERT_NOT_REACHED;	return 0;    }}static cairo_int_status_t_cairo_ps_surface_stroke (void			*abstract_surface,			  cairo_operator_t	 op,			  cairo_pattern_t	*source,			  cairo_path_fixed_t	*path,			  cairo_stroke_style_t	*style,			  cairo_matrix_t	*ctm,			  cairo_matrix_t	*ctm_inverse,			  double		 tolerance,			  cairo_antialias_t	 antialias){    cairo_ps_surface_t *surface = abstract_surface;    cairo_output_stream_t *stream = surface->stream;    cairo_int_status_t status;    double *dash = style->dash;    int num_dashes = style->num_dashes;    double dash_offset = style->dash_offset;    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)	return _analyze_operation (surface, op, source);    assert (operation_supported (surface, op, source));    _cairo_output_stream_printf (stream,				 "%% _cairo_ps_surface_stroke\n");    /* 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 = malloc (2 * num_dashes * sizeof (double));	    if (dash == NULL)		return 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_STATUS_SUCCESS;		    }		    /* 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;	    }	}    }    emit_pattern (surface, source, 0, 0);    _cairo_output_stream_printf (stream,				 "gsave\n");    status = _cairo_ps_surface_emit_path (surface, stream, path,					  style->line_cap);    /*     * Switch to user space to set line parameters     */    _cairo_output_stream_printf (stream,				 "[%f %f %f %f 0 0] concat\n",				 ctm->xx, ctm->yx, ctm->xy, ctm->yy);    /* line width */    _cairo_output_stream_printf (stream, "%f setlinewidth\n",				 style->line_width);    /* line cap */    _cairo_output_stream_printf (stream, "%d setlinecap\n",				 _cairo_ps_line_cap (style->line_cap));    /* line join */    _cairo_output_stream_printf (stream, "%d setlinejoin\n",				 _cairo_ps_line_join (style->line_join));    /* dashes */    if (num_dashes) {	int d;	_cairo_output_stream_printf (stream, "[");	for (d = 0; d < num_dashes; d++)	    _cairo_output_stream_printf (stream, " %f", dash[d]);	_cairo_output_stream_printf (stream, "] %f setdash\n",				     dash_offset);    }    if (dash != style->dash)	free (dash);    /* miter limit */    _cairo_output_stream_printf (stream, "%f setmiterlimit\n",				 style->miter_limit);    _cairo_output_stream_printf (stream,				 "stroke\n");    _cairo_output_stream_printf (stream,				 "grestore\n");    return status;}static cairo_int_status_t_cairo_ps_surface_fill (void		*abstract_surface,		 cairo_operator_t	 op,		 cairo_pattern_t	*source,		 cairo_path_fixed_t	*path,		 cairo_fill_rule_t	 fill_rule,		 double			 tolerance,		 cairo_antialias_t	 antialias){    cairo_ps_surface_t *surface = abstract_surface;    cairo_output_stream_t *stream = surface->stream;    cairo_int_status_t status;    const char *ps_operator;    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)	return _analyze_operation (surface, op, source);    assert (operation_supported (surface, op, source));    _cairo_output_stream_printf (stream,				 "%% _cairo_ps_surface_fill\n");    emit_pattern (surface, source, 0, 0);    /* We're filling not stroking, so we pass CAIRO_LINE_CAP_ROUND. */    status = _cairo_ps_surface_emit_path (surface, stream, path,					  CAIRO_LINE_CAP_ROUND);    switch (fill_rule) {    case CAIRO_FILL_RULE_WINDING:	ps_operator = "F";	break;    case CAIRO_FILL_RULE_EVEN_ODD:	ps_operator = "eofill";	break;    default:	ASSERT_NOT_REACHED;    }    _cairo_output_stream_printf (stream,				 "%s\n", ps_operator);    return status;}static cairo_int_status_t_cairo_ps_surface_show_glyphs (void		     *abstract_surface,			       cairo_operator_t	      op,			       cairo_pattern_t	     *source,			       const cairo_glyph_t   *glyphs,			       int		      num_glyphs,			       cairo_scaled_font_t   *scaled_font){    cairo_ps_surface_t *surface = abstract_surface;    cairo_output_stream_t *stream = surface->stream;    int current_subset_id = -1;    unsigned int font_id, subset_id, subset_glyph_index;    cairo_status_t status;    int i;    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)	return _analyze_operation (surface, op, source);    assert (operation_supported (surface, op, source));    _cairo_output_stream_printf (stream,				 "%% _cairo_ps_surface_show_glyphs\n");    if (num_glyphs)	emit_pattern (surface, source, 0, 0);    for (i = 0; i < num_glyphs; i++) {	status = _cairo_scaled_font_subsets_map_glyph (surface->font_subsets,						       scaled_font, glyphs[i].index,						       &font_id, &subset_id, &subset_glyph_index);	if (status)	    return status;	if (subset_id != current_subset_id) {	    _cairo_output_stream_printf (surface->stream,					 "/CairoFont-%d-%d findfont\n"					 "[ %f %f %f %f 0 0 ] makefont\n"					 "setfont\n",					 font_id,					 subset_id,					 scaled_font->scale.xx,					 scaled_font->scale.yx,					 -scaled_font->scale.xy,					 -scaled_font->scale.yy);	    current_subset_id = subset_id;	}	_cairo_output_stream_printf (surface->stream,				     "%f %f M <%02x> S\n",				     glyphs[i].x, glyphs[i].y,				     subset_glyph_index);    }    return _cairo_output_stream_get_status (surface->stream);}static void_cairo_ps_surface_set_paginated_mode (void			*abstract_surface,				      cairo_paginated_mode_t	 paginated_mode){    cairo_ps_surface_t *surface = abstract_surface;    surface->paginated_mode = paginated_mode;}static const cairo_surface_backend_t cairo_ps_surface_backend = {    CAIRO_SURFACE_TYPE_PS,    _cairo_ps_surface_create_similar,    _cairo_ps_surface_finish,    NULL, /* acquire_source_image */    NULL, /* release_source_image */    NULL, /* acquire_dest_image */    NULL, /* release_dest_image */    NULL, /* clone_similar */    NULL, /* composite */    NULL, /* fill_rectangles */    NULL, /* composite_trapezoids */    _cairo_ps_surface_copy_page,    _cairo_ps_surface_show_page,    NULL, /* set_clip_region */    _cairo_ps_surface_intersect_clip_path,    _cairo_ps_surface_get_extents,    NULL, /* old_show_glyphs */    _cairo_ps_surface_get_font_options,    NULL, /* flush */    NULL, /* mark_dirty_rectangle */    NULL, /* scaled_font_fini */    NULL, /* scaled_glyph_fini */    /* Here are the drawing functions */    _cairo_ps_surface_paint, /* paint */    NULL, /* mask */    _cairo_ps_surface_stroke,    _cairo_ps_surface_fill,    _cairo_ps_surface_show_glyphs,    NULL, /* snapshot */};static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend = {    _cairo_ps_surface_start_page,    _cairo_ps_surface_set_paginated_mode};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -