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

📄 cairo-svg-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (i >= num_elements) {	cairo_surface_t *paginated_surface;	cairo_surface_t *svg_surface;	cairo_meta_snapshot_t new_snapshot;	meta = (cairo_meta_surface_t *) _cairo_surface_snapshot ((cairo_surface_t *)surface);	paginated_surface = _cairo_svg_surface_create_for_document (document,								    meta->content,								    meta->width_pixels,								    meta->height_pixels);	svg_surface = _cairo_paginated_surface_get_target (paginated_surface);	cairo_surface_set_fallback_resolution (paginated_surface,					       document->owner->x_fallback_resolution,					       document->owner->y_fallback_resolution);	_cairo_meta_surface_replay ((cairo_surface_t *)meta, paginated_surface);	_cairo_surface_show_page (paginated_surface);	new_snapshot.meta = meta;	new_snapshot.id = ((cairo_svg_surface_t *) svg_surface)->id;	_cairo_array_append (&document->meta_snapshots, &new_snapshot);	if (meta->content == CAIRO_CONTENT_ALPHA) {	    emit_alpha_filter (document);	    _cairo_output_stream_printf (document->xml_node_defs,					 "<g id=\"surface%d\" "					 "clip-path=\"url(#clip%d)\" "					 "filter=\"url(#alpha)\">\n",					 ((cairo_svg_surface_t *) svg_surface)->id,					 ((cairo_svg_surface_t *) svg_surface)->base_clip);	} else {	    _cairo_output_stream_printf (document->xml_node_defs,					 "<g id=\"surface%d\" "					 "clip-path=\"url(#clip%d)\">\n",					 ((cairo_svg_surface_t *) svg_surface)->id,					 ((cairo_svg_surface_t *) svg_surface)->base_clip);	}	contents = ((cairo_svg_surface_t *) svg_surface)->xml_node;	_cairo_memory_stream_copy (contents, document->xml_node_defs);	for (i = 0; i < ((cairo_svg_surface_t *) svg_surface)->clip_level; i++)	    _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");	_cairo_output_stream_printf (document->xml_node_defs, "</g>\n");	id = new_snapshot.id;	cairo_surface_destroy (paginated_surface);	/* FIXME: cairo_paginated_surface doesn't take a ref to the	 * passed in target surface so we can't call destroy here.	 * cairo_paginated_surface should be fixed, but for now just	 * work around it. */	/* cairo_surface_destroy (svg_surface); */    }    return id;}static cairo_status_temit_composite_meta_pattern (cairo_output_stream_t	*output,			     cairo_svg_surface_t	*surface,			     cairo_surface_pattern_t	*pattern,			     int			 pattern_id,			     const char			*extra_attributes){    cairo_svg_document_t *document = surface->document;    cairo_meta_surface_t *meta_surface;    cairo_matrix_t p2u;    int id;    meta_surface = (cairo_meta_surface_t *) pattern->surface;    id = emit_meta_surface (document, meta_surface);    p2u = pattern->base.matrix;    cairo_matrix_invert (&p2u);    if (pattern_id != invalid_pattern_id) {	_cairo_output_stream_printf (output,				     "<pattern id=\"pattern%d\" "				     "patternUnits=\"userSpaceOnUse\" "				     "width=\"%d\" height=\"%d\"",				     pattern_id,				     meta_surface->width_pixels,				     meta_surface->height_pixels);	emit_transform (output, " patternTransform", ">\n", &p2u);    }    _cairo_output_stream_printf (output,				 "<use xlink:href=\"#surface%d\"",				 id);    if (pattern_id == invalid_pattern_id)	emit_transform (output, " transform", "", &p2u);    if (extra_attributes)	_cairo_output_stream_printf (output, " %s", extra_attributes);    _cairo_output_stream_printf (output, "/>\n");    if (pattern_id != invalid_pattern_id)	_cairo_output_stream_printf (output, "</pattern>\n");    return CAIRO_STATUS_SUCCESS;}static cairo_status_temit_composite_pattern (cairo_output_stream_t   *output,			cairo_svg_surface_t	*surface,			cairo_surface_pattern_t *pattern,			int			 pattern_id,			const char		*extra_attributes){    if (_cairo_surface_is_meta (pattern->surface)) {	return emit_composite_meta_pattern (output, surface, pattern,					    pattern_id, extra_attributes);    }    return emit_composite_image_pattern (output, surface, pattern,					 pattern_id, extra_attributes);}static voidemit_operator (cairo_output_stream_t *output,	       cairo_svg_surface_t   *surface,	      cairo_operator_t	      op){    char const *op_str[] = {	"clear",	"src",		"src-over",	"src-in",	"src-out",	"src-atop",	"dst",		"dst-over",	"dst-in",	"dst-out",	"dst-atop",	"xor", "plus",	"color-dodge"	/* FIXME: saturate ? */    };    if (surface->document->svg_version >= CAIRO_SVG_VERSION_1_2)	_cairo_output_stream_printf (output, "comp-op: %s; ", op_str[op]);}static voidemit_solid_pattern (cairo_svg_surface_t	    *surface,		    cairo_solid_pattern_t   *pattern,		    cairo_output_stream_t   *style,		    cairo_bool_t	     is_stroke){    _cairo_output_stream_printf (style,				 "%s: rgb(%f%%,%f%%,%f%%); "				 "opacity: %f;",				 is_stroke ? "stroke" : "fill",				 pattern->color.red * 100.0,				 pattern->color.green * 100.0,				 pattern->color.blue * 100.0,				 pattern->color.alpha);}static voidemit_surface_pattern (cairo_svg_surface_t	*surface,		      cairo_surface_pattern_t	*pattern,		      cairo_output_stream_t     *style,		      cairo_bool_t		 is_stroke){    cairo_svg_document_t *document = surface->document;    int pattern_id;    pattern_id = document->pattern_id++;    emit_composite_pattern (document->xml_node_defs, surface, pattern,			    pattern_id, NULL);    _cairo_output_stream_printf (style,				 "%s: url(#pattern%d);",				 is_stroke ? "color" : "fill",				 pattern_id);}static voidemit_pattern_stops (cairo_output_stream_t *output,		    cairo_gradient_pattern_t const *pattern,		    double start_offset){    double offset;    int i;    for (i = 0; i < pattern->n_stops; i++) {	offset = start_offset + (1 - start_offset ) *	    _cairo_fixed_to_double (pattern->stops[i].x);	_cairo_output_stream_printf (output,				     "<stop offset=\"%f\" style=\""				     "stop-color: rgb(%f%%,%f%%,%f%%); "				     "stop-opacity: %f;\"/>\n",				     offset,				     pattern->stops[i].color.red   / 655.35,				     pattern->stops[i].color.green / 655.35,				     pattern->stops[i].color.blue  / 655.35,				     pattern->stops[i].color.alpha / 65535.0);    }}static voidemit_pattern_extend (cairo_output_stream_t *output,		     cairo_pattern_t       *pattern){    switch (pattern->extend) {	case CAIRO_EXTEND_REPEAT:	    _cairo_output_stream_printf (output, "spreadMethod=\"repeat\" ");	    break;	case CAIRO_EXTEND_REFLECT:	    _cairo_output_stream_printf (output, "spreadMethod=\"reflect\" ");	    break;	case CAIRO_EXTEND_NONE:	    break;	case CAIRO_EXTEND_PAD:	    /* FIXME not implemented */	    break;    }}static voidemit_linear_pattern (cairo_svg_surface_t    *surface,		     cairo_linear_pattern_t *pattern,		     cairo_output_stream_t  *style,		     cairo_bool_t	     is_stroke){    cairo_svg_document_t *document = surface->document;    double x0, y0, x1, y1;    cairo_matrix_t p2u;    x0 = _cairo_fixed_to_double (pattern->gradient.p1.x);    y0 = _cairo_fixed_to_double (pattern->gradient.p1.y);    x1 = _cairo_fixed_to_double (pattern->gradient.p2.x);    y1 = _cairo_fixed_to_double (pattern->gradient.p2.y);    _cairo_output_stream_printf (document->xml_node_defs,				 "<linearGradient id=\"linear%d\" "				 "gradientUnits=\"userSpaceOnUse\" "				 "x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" ",				 document->linear_pattern_id,				 x0, y0, x1, y1);    emit_pattern_extend (document->xml_node_defs, &pattern->base.base),    p2u = pattern->base.base.matrix;    cairo_matrix_invert (&p2u);    emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u);    emit_pattern_stops (document->xml_node_defs ,&pattern->base, 0.0);    _cairo_output_stream_printf (document->xml_node_defs,				 "</linearGradient>\n");    _cairo_output_stream_printf (style,				 "%s: url(#linear%d);",				 is_stroke ? "color" : "fill",				 document->linear_pattern_id);    document->linear_pattern_id++;}static voidemit_radial_pattern (cairo_svg_surface_t    *surface,		     cairo_radial_pattern_t *pattern,		     cairo_output_stream_t  *style,		     cairo_bool_t            is_stroke){    cairo_svg_document_t *document = surface->document;    cairo_matrix_t p2u;    double x0, y0, x1, y1, r0, r1;    double fx, fy;    x0 = _cairo_fixed_to_double (pattern->gradient.inner.x);    y0 = _cairo_fixed_to_double (pattern->gradient.inner.y);    r0 = _cairo_fixed_to_double (pattern->gradient.inner.radius);    x1 = _cairo_fixed_to_double (pattern->gradient.outer.x);    y1 = _cairo_fixed_to_double (pattern->gradient.outer.y);    r1 = _cairo_fixed_to_double (pattern->gradient.outer.radius);    /* SVG doesn't have a start radius, so computing now SVG focal coordinates     * and emulating start radius by translating color stops.     * FIXME: We also need to emulate cairo behaviour inside start circle when     * extend != CAIRO_EXTEND_NONE.     * FIXME: Handle radius1 <= radius0 */    fx = (r1 * x0 - r0 * x1) / (r1 - r0);    fy = (r1 * y0 - r0 * y1) / (r1 - r0);    _cairo_output_stream_printf (document->xml_node_defs,				 "<radialGradient id=\"radial%d\" "				 "gradientUnits=\"userSpaceOnUse\" "				 "cx=\"%f\" cy=\"%f\" "				 "fx=\"%f\" fy=\"%f\" r=\"%f\" ",				 document->radial_pattern_id,				 x1, y1,				 fx, fy, r1);    emit_pattern_extend (document->xml_node_defs, &pattern->base.base),    p2u = pattern->base.base.matrix;    cairo_matrix_invert (&p2u);    emit_transform (document->xml_node_defs, "gradientTransform", ">\n", &p2u);    emit_pattern_stops (document->xml_node_defs, &pattern->base, r0 / r1);    _cairo_output_stream_printf (document->xml_node_defs,				 "</radialGradient>\n");    _cairo_output_stream_printf (style,				 "%s: url(#radial%d);",				 is_stroke ? "color" : "fill",				 document->radial_pattern_id);    document->radial_pattern_id++;}static voidemit_pattern (cairo_svg_surface_t *surface, cairo_pattern_t *pattern,	      cairo_output_stream_t *output, cairo_bool_t is_stroke){    switch (pattern->type) {    case CAIRO_PATTERN_TYPE_SOLID:	emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, output, is_stroke);	break;    case CAIRO_PATTERN_TYPE_SURFACE:	emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, output, is_stroke);	break;    case CAIRO_PATTERN_TYPE_LINEAR:	emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, output, is_stroke);	break;    case CAIRO_PATTERN_TYPE_RADIAL:	emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke);	break;    }}static cairo_int_status_t_cairo_svg_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_svg_surface_t *surface = abstract_surface;    cairo_status_t status;    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)	return _analyze_operation (surface, op, source);    assert (_operation_supported (surface, op, source));    _cairo_output_stream_printf (surface->xml_node, 				 "<path style=\"stroke: none; " 				 "fill-rule: %s; ", 				 fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? 				 "evenodd" : "nonzero");    emit_operator (surface->xml_node, surface, op);    emit_pattern (surface, source, surface->xml_node, FALSE);    _cairo_output_stream_printf (surface->xml_node, "\" ");    status = emit_path (surface->xml_node, path, NULL);    _cairo_output_stream_printf (surface->xml_node, "/>\n");    return status;}static cairo_int_status_t_cairo_svg_surface_get_extents (void		        *abstract_surface,				cairo_rectangle_int16_t *rectangle){    cairo_svg_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_size.     */    rectangle->width  = (int) ceil (surface->width);    rectangle->height = (int) ceil (surface->height);    return CAIRO_STATUS_SUCCESS;}static cairo_status_temit_paint (cairo_output_stream_t *output,	    cairo_svg_surface_t   *surface,	    cairo_operator_t	   op,	    cairo_pattern_t	  *source,	    const char		  *extra_attributes){    if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&	source->extend == CAIRO_EXTEND_NONE)	return emit_composite_pattern (output,				       surface,				       (cairo_surface_pattern_t *) source,				       invalid_pattern_id,				       extra_attributes);    _cairo_output_stream_printf (output,				 "<rect x=\"0\" y=\"0\" "				 "width=\"%f\" height=\"%f\" "				 "style=\"",				 surface->width, surface->height);    emit_operator (output, surface, op);    emit_pattern (surface, source, output, FALSE);    _cairo_output_stream_printf (output, " stroke: none;\"");    if (extra_attributes)	_cairo_output_stream_printf (output, " %s", extra_attributes);    _cairo_output_stream_printf (output, "/>\n");    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_svg_surface_paint (void		    *abstract_surface,			  cairo_operator_t   op,			  cairo_pattern_t   *source){    cairo_svg_surface_t *surface = abstract_surface;    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 (surface, op, source));    */    /* Emulation of clear and source operators, when no clipping region     * is defined. We just delete existing content of surface root node,     * and exit early if operator is clear.     * XXX: optimization of SOURCE operator doesn't work, since analyze     * above always return FALSE. In order to make it work, we need a way     * to know if there's an active clipping path.     * Optimization of CLEAR works because of a test in paginated surface,     * and an optimiszation in meta surface. */    if (surface->clip_level == 0 &&	(op == CAIRO_OPERATOR_CLEAR ||	 op == CAIRO_OPERATOR_SOURCE)) {	_cairo_output_stream_destroy (surface->xml_node);

⌨️ 快捷键说明

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