mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-04 11:00:21 +01:00
Add mask support and switch to SVG 1.2 for compositing operators.
return xml node instead of cairo status. (emit_composite_svg_pattern): ditto. (emit_composite_pattern): ditto. (emit_operator): use SVG 1.2 operators, since feComposite filter always composite resulting surface to current canvas. (_cairo_svg_surface_composite): removed. (_cairo_svg_surface_fill_rectangles): removed. (intersect): removed. (_cairo_svg_surface_composite_trapezoids): removed. (emit_paint): new. (_cairo_svg_surface_paint): new. (_cairo_svg_surface_mask): new. (_cairo_svg_surface_stroke): emit operator.
This commit is contained in:
parent
8ff1866724
commit
921dcc16f9
2 changed files with 105 additions and 208 deletions
19
ChangeLog
19
ChangeLog
|
|
@ -1,3 +1,22 @@
|
|||
2006-02-13 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
|
||||
|
||||
Add mask support and switch to SVG 1.2 for compositing operators.
|
||||
|
||||
* src/cairo-svg-surface.c (emit_composite_image_pattern): return xml
|
||||
node instead of cairo status.
|
||||
(emit_composite_svg_pattern): ditto.
|
||||
(emit_composite_pattern): ditto.
|
||||
(emit_operator): use SVG 1.2 operators, since feComposite filter
|
||||
always composite resulting surface to current canvas.
|
||||
(_cairo_svg_surface_composite): removed.
|
||||
(_cairo_svg_surface_fill_rectangles): removed.
|
||||
(intersect): removed.
|
||||
(_cairo_svg_surface_composite_trapezoids): removed.
|
||||
(emit_paint): new.
|
||||
(_cairo_svg_surface_paint): new.
|
||||
(_cairo_svg_surface_mask): new.
|
||||
(_cairo_svg_surface_stroke): emit operator.
|
||||
|
||||
2006-02-11 Christian Biesinger <cbiesinger@web.de>
|
||||
|
||||
* doc/public/cairo-docs.xml:
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ struct cairo_svg_document {
|
|||
unsigned int pattern_id;
|
||||
unsigned int filter_id;
|
||||
unsigned int clip_id;
|
||||
unsigned int mask_id;
|
||||
};
|
||||
|
||||
struct cairo_svg_surface {
|
||||
|
|
@ -392,7 +393,7 @@ _cairo_surface_base64_encode (cairo_surface_t *surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
static xmlNodePtr
|
||||
emit_composite_image_pattern (xmlNodePtr node,
|
||||
cairo_surface_pattern_t *pattern,
|
||||
double *width,
|
||||
|
|
@ -410,11 +411,11 @@ emit_composite_image_pattern (xmlNodePtr node,
|
|||
|
||||
status = _cairo_surface_acquire_source_image (surface, &image, &image_extra);
|
||||
if (status)
|
||||
return status;
|
||||
return NULL;
|
||||
|
||||
status = _cairo_surface_base64_encode (surface, &image_buffer);
|
||||
if (status)
|
||||
return status;
|
||||
return NULL;
|
||||
|
||||
child = xmlNewChild (node, NULL, CC2XML ("image"), NULL);
|
||||
_cairo_dtostr (buffer, sizeof buffer, image->width);
|
||||
|
|
@ -438,10 +439,10 @@ emit_composite_image_pattern (xmlNodePtr node,
|
|||
|
||||
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
||||
|
||||
return status;
|
||||
return child;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
static xmlNodePtr
|
||||
emit_composite_svg_pattern (xmlNodePtr node,
|
||||
cairo_surface_pattern_t *pattern,
|
||||
double *width,
|
||||
|
|
@ -455,7 +456,7 @@ emit_composite_svg_pattern (xmlNodePtr node,
|
|||
|
||||
/* FIXME: self copy is not supported yet */
|
||||
if (surface->id == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return NULL;
|
||||
|
||||
child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
|
||||
snprintf (buffer, sizeof buffer, "#surface%d", surface->id);
|
||||
|
|
@ -472,10 +473,10 @@ emit_composite_svg_pattern (xmlNodePtr node,
|
|||
if (height != NULL)
|
||||
*height = surface->height;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return child;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
static xmlNodePtr
|
||||
emit_composite_pattern (xmlNodePtr node,
|
||||
cairo_surface_pattern_t *pattern,
|
||||
double *width,
|
||||
|
|
@ -488,69 +489,27 @@ emit_composite_pattern (xmlNodePtr node,
|
|||
return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_composite (cairo_operator_t op,
|
||||
cairo_pattern_t *src_pattern,
|
||||
cairo_pattern_t *mask_pattern,
|
||||
void *abstract_dst,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int mask_x,
|
||||
int mask_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
unsigned int width,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_svg_surface_t *dst = abstract_dst;
|
||||
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
|
||||
|
||||
if (mask_pattern)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (src_pattern->type != CAIRO_PATTERN_SURFACE)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return emit_composite_pattern (dst->xml_node, src, NULL, NULL, FALSE);
|
||||
}
|
||||
/* FIXME: Here we use a SVG 1.2 feature. We should probably have
|
||||
* an API to limit output SVG version, and fallback to image when
|
||||
* necessary. */
|
||||
|
||||
static void
|
||||
emit_operator (cairo_operator_t op, cairo_svg_surface_t *surface,
|
||||
xmlBufferPtr style)
|
||||
emit_operator (xmlNodePtr node, cairo_operator_t op)
|
||||
{
|
||||
char const *op_str[] = {
|
||||
NULL,
|
||||
NULL, NULL, "in", "out", "atop",
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
"xor", NULL, NULL };
|
||||
|
||||
cairo_svg_document_t *document = surface->document;
|
||||
xmlNodePtr child, primitive;
|
||||
xmlBufferPtr id;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
"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 (op_str[op] == NULL)
|
||||
return;
|
||||
|
||||
child = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("filter"), NULL);
|
||||
primitive = xmlNewChild (child, NULL, CC2XML ("feComposite"), NULL);
|
||||
xmlSetProp (primitive, CC2XML ("operator"), CC2XML (op_str[op]));
|
||||
xmlSetProp (primitive, CC2XML ("in"), CC2XML ("SourceGraphic"));
|
||||
xmlSetProp (primitive, CC2XML ("in2"), CC2XML ("BackgroundImage"));
|
||||
|
||||
id = xmlBufferCreate ();
|
||||
xmlBufferCat (id, CC2XML ("filter"));
|
||||
snprintf (buffer, sizeof buffer, "%d", document->filter_id);
|
||||
xmlBufferCat (id, C2XML (buffer));
|
||||
xmlSetProp (child, CC2XML ("id"), C2XML (xmlBufferContent (id)));
|
||||
|
||||
xmlBufferCat (style, CC2XML ("filter: url(#"));
|
||||
xmlBufferCat (style, xmlBufferContent (id));
|
||||
xmlBufferCat (style, CC2XML (");"));
|
||||
|
||||
xmlBufferFree (id);
|
||||
|
||||
document->filter_id++;
|
||||
xmlSetProp (node, CC2XML ("comp-op"), C2XML (op_str[op]));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -828,7 +787,7 @@ typedef struct
|
|||
xmlBufferPtr path;
|
||||
} svg_path_info_t;
|
||||
|
||||
static cairo_status_t
|
||||
static cairo_status_t
|
||||
_cairo_svg_path_move_to (void *closure, cairo_point_t *point)
|
||||
{
|
||||
svg_path_info_t *info = closure;
|
||||
|
|
@ -917,42 +876,6 @@ _cairo_svg_path_close_path (void *closure)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_fill_rectangles (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_rectangle_t *rects,
|
||||
int num_rects)
|
||||
{
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
xmlNodePtr child;
|
||||
xmlBufferPtr style;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
int i;
|
||||
|
||||
style = xmlBufferCreate ();
|
||||
emit_color (color, style, "fill", "opacity");
|
||||
xmlBufferCat (style, " stroke: none;");
|
||||
emit_operator (op, surface, style);
|
||||
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
|
||||
_cairo_dtostr (buffer, sizeof buffer, rects[i].x);
|
||||
xmlSetProp (child, CC2XML ("x"), C2XML (buffer));
|
||||
_cairo_dtostr (buffer, sizeof buffer, rects[i].y);
|
||||
xmlSetProp (child, CC2XML ("y"), C2XML (buffer));
|
||||
_cairo_dtostr (buffer, sizeof buffer, rects[i].width);
|
||||
xmlSetProp (child, CC2XML ("width"), C2XML (buffer));
|
||||
_cairo_dtostr (buffer, sizeof buffer, rects[i].height);
|
||||
xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
|
||||
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
|
||||
}
|
||||
|
||||
xmlBufferFree (style);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_fill (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
|
|
@ -978,7 +901,6 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
xmlBufferCat (style, " stroke: none;");
|
||||
xmlBufferCat (style, " fill-rule: ");
|
||||
xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? "evenodd;" : "nonzero;");
|
||||
emit_operator (op, surface, style);
|
||||
|
||||
status = _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
|
|
@ -991,6 +913,7 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
|
||||
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
|
||||
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
|
||||
emit_operator (child, op);
|
||||
|
||||
xmlBufferFree (info.path);
|
||||
xmlBufferFree (style);
|
||||
|
|
@ -998,91 +921,6 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
|||
return status;
|
||||
}
|
||||
|
||||
static double
|
||||
intersect (cairo_line_t *line, cairo_fixed_t y)
|
||||
{
|
||||
return _cairo_fixed_to_double (line->p1.x) +
|
||||
_cairo_fixed_to_double (line->p2.x - line->p1.x) *
|
||||
_cairo_fixed_to_double (y - line->p1.y) /
|
||||
_cairo_fixed_to_double (line->p2.y - line->p1.y);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
int x_src,
|
||||
int y_src,
|
||||
int x_dst,
|
||||
int y_dst,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
cairo_trapezoid_t *traps,
|
||||
int num_traps)
|
||||
{
|
||||
cairo_svg_surface_t *surface = abstract_dst;
|
||||
xmlBufferPtr style, path;
|
||||
xmlNodePtr child;
|
||||
double left_x1, left_x2, right_x1, right_x2;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
int i;
|
||||
|
||||
style = xmlBufferCreate ();
|
||||
emit_pattern (surface, pattern, style, 0);
|
||||
xmlBufferCat (style, "stroke: none;");
|
||||
|
||||
path = xmlBufferCreate ();
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
|
||||
left_x1 = intersect (&traps[i].left, traps[i].top);
|
||||
left_x2 = intersect (&traps[i].left, traps[i].bottom);
|
||||
right_x1 = intersect (&traps[i].right, traps[i].top);
|
||||
right_x2 = intersect (&traps[i].right, traps[i].bottom);
|
||||
|
||||
xmlBufferCat (path, CC2XML ("M "));
|
||||
_cairo_dtostr (buffer, sizeof buffer, left_x1);
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" "));
|
||||
_cairo_dtostr (buffer, sizeof buffer,
|
||||
_cairo_fixed_to_double (traps[i].top));
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" L "));
|
||||
_cairo_dtostr (buffer, sizeof buffer, left_x2);
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" "));
|
||||
_cairo_dtostr (buffer, sizeof buffer,
|
||||
_cairo_fixed_to_double (traps[i].bottom));
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" L "));
|
||||
_cairo_dtostr (buffer, sizeof buffer, right_x2);
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" "));
|
||||
_cairo_dtostr (buffer, sizeof buffer,
|
||||
_cairo_fixed_to_double (traps[i].bottom));
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" L "));
|
||||
_cairo_dtostr (buffer, sizeof buffer, right_x1);
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" "));
|
||||
_cairo_dtostr (buffer, sizeof buffer,
|
||||
_cairo_fixed_to_double (traps[i].top));
|
||||
xmlBufferCat (path, CC2XML (buffer));
|
||||
xmlBufferCat (path, CC2XML (" Z"));
|
||||
}
|
||||
|
||||
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
|
||||
|
||||
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (path));
|
||||
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
|
||||
|
||||
xmlBufferFree (path);
|
||||
xmlBufferFree (style);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_get_extents (void *abstract_surface,
|
||||
cairo_rectangle_t *rectangle)
|
||||
|
|
@ -1102,26 +940,26 @@ _cairo_svg_surface_get_extents (void *abstract_surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* First attempt of paint implementation, but obviously I didn't
|
||||
* understand how it's supposed to work */
|
||||
|
||||
#if 0
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
static xmlNodePtr
|
||||
emit_paint (xmlNodePtr node,
|
||||
cairo_svg_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source)
|
||||
{
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
xmlNodePtr child;
|
||||
xmlBufferPtr style;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
if (source->type == CAIRO_PATTERN_SURFACE)
|
||||
return emit_composite_pattern (node,
|
||||
(cairo_surface_pattern_t *) source,
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
style = xmlBufferCreate ();
|
||||
emit_pattern (surface, source, style, 0);
|
||||
xmlBufferCat (style, " stroke: none;");
|
||||
emit_operator (op, surface, style);
|
||||
|
||||
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
|
||||
child = xmlNewChild (node, NULL, CC2XML ("rect"), NULL);
|
||||
xmlSetProp (child, CC2XML ("x"), CC2XML ("0"));
|
||||
xmlSetProp (child, CC2XML ("y"), CC2XML ("0"));
|
||||
_cairo_dtostr (buffer, sizeof buffer, surface->width);
|
||||
|
|
@ -1129,12 +967,51 @@ _cairo_svg_surface_paint (void *abstract_surface,
|
|||
_cairo_dtostr (buffer, sizeof buffer, surface->height);
|
||||
xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
|
||||
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
|
||||
emit_operator (child, op);
|
||||
|
||||
xmlBufferFree (style);
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
emit_paint (surface->xml_node, surface, op, source);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_mask (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
cairo_pattern_t *source,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_svg_surface_t *surface = abstract_surface;
|
||||
cairo_svg_document_t *document = surface->document;
|
||||
xmlNodePtr child, mask_node;
|
||||
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
|
||||
|
||||
mask_node = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("mask"), NULL);
|
||||
snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
|
||||
xmlSetProp (mask_node, CC2XML ("id"), C2XML (buffer));
|
||||
emit_paint (mask_node, surface, op, mask);
|
||||
|
||||
child = emit_paint (surface->xml_node, surface, op, source);
|
||||
|
||||
if (child) {
|
||||
snprintf (buffer, sizeof buffer, "url(#mask%d)", document->mask_id);
|
||||
xmlSetProp (child, CC2XML ("mask"), C2XML (buffer));
|
||||
}
|
||||
|
||||
document->mask_id++;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_svg_surface_stroke (void *abstract_dst,
|
||||
|
|
@ -1231,9 +1108,9 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
|||
&info);
|
||||
|
||||
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
|
||||
|
||||
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
|
||||
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
|
||||
emit_operator (child, op);
|
||||
|
||||
xmlBufferFree (info.path);
|
||||
xmlBufferFree (style);
|
||||
|
|
@ -1357,9 +1234,9 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
|||
NULL, /* acquire_dest_image */
|
||||
NULL, /* release_dest_image */
|
||||
NULL, /* clone_similar */
|
||||
_cairo_svg_surface_composite,
|
||||
_cairo_svg_surface_fill_rectangles,
|
||||
_cairo_svg_surface_composite_trapezoids,
|
||||
NULL, /* _cairo_svg_surface_composite, */
|
||||
NULL, /* _cairo_svg_surface_fill_rectangles, */
|
||||
NULL, /* _cairo_svg_surface_composite_trapezoids,*/
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
NULL, /* set_clip_region */
|
||||
|
|
@ -1371,8 +1248,8 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
|||
NULL, /* mark dirty rectangle */
|
||||
NULL, /* scaled font fini */
|
||||
NULL, /* scaled glyph fini */
|
||||
NULL, /*_cairo_svg_surface_paint,*/
|
||||
NULL, /* mask */
|
||||
_cairo_svg_surface_paint,
|
||||
_cairo_svg_surface_mask,
|
||||
_cairo_svg_surface_stroke,
|
||||
_cairo_svg_surface_fill,
|
||||
NULL /* show_glyphs */
|
||||
|
|
@ -1407,6 +1284,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
|
|||
document->pattern_id = 0;
|
||||
document->filter_id = 0;
|
||||
document->clip_id = 0;
|
||||
document->mask_id = 0;
|
||||
|
||||
doc = xmlNewDoc (CC2XML ("1.0"));
|
||||
node = xmlNewNode (NULL, CC2XML ("svg"));
|
||||
|
|
@ -1423,7 +1301,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
|
|||
xmlSetProp (node, CC2XML ("height"), CC2XML (buffer));
|
||||
xmlSetProp (node, CC2XML ("xmlns"), CC2XML ("http://www.w3.org/2000/svg"));
|
||||
xmlSetProp (node, CC2XML ("xmlns:xlink"), CC2XML ("http://www.w3.org/1999/xlink"));
|
||||
xmlSetProp (node, CC2XML ("version"), CC2XML ("1.1"));
|
||||
xmlSetProp (node, CC2XML ("version"), CC2XML ("1.2"));
|
||||
|
||||
return document;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue