Support "use" element
diff --git a/coders/svg.c b/coders/svg.c
index 2546e47..8c2e750 100644
--- a/coders/svg.c
+++ b/coders/svg.c
@@ -786,6 +786,15 @@
static void SVGStartElement(void *context,const xmlChar *name,
const xmlChar **attributes)
{
+#define PushGraphicContext(id) \
+{ \
+ if (*id == '\0') \
+ (void) FormatLocaleFile(svg_info->file,"push graphic-context\n"); \
+ else \
+ (void) FormatLocaleFile(svg_info->file,"push graphic-context \"%s\"\n", \
+ id); \
+}
+
char
*color,
background[MagickPathExtent],
@@ -992,7 +1001,7 @@
{
if (LocaleCompare((const char *) name,"circle") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
if (LocaleCompare((const char *) name,"clipPath") == 0)
@@ -1017,7 +1026,7 @@
{
if (LocaleCompare((const char *) name,"ellipse") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
break;
@@ -1027,7 +1036,7 @@
{
if (LocaleCompare((const char *) name,"foreignObject") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
break;
@@ -1037,7 +1046,7 @@
{
if (LocaleCompare((const char *) name,"g") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
break;
@@ -1047,7 +1056,7 @@
{
if (LocaleCompare((const char *) name,"image") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
break;
@@ -1057,7 +1066,7 @@
{
if (LocaleCompare((const char *) name,"line") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
if (LocaleCompare((const char *) name,"linearGradient") == 0)
@@ -1075,7 +1084,7 @@
{
if (LocaleCompare((const char *) name,"path") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
if (LocaleCompare((const char *) name,"pattern") == 0)
@@ -1088,12 +1097,12 @@
}
if (LocaleCompare((const char *) name,"polygon") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
if (LocaleCompare((const char *) name,"polyline") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
break;
@@ -1112,7 +1121,7 @@
}
if (LocaleCompare((const char *) name,"rect") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
break;
}
break;
@@ -1122,7 +1131,7 @@
{
if (LocaleCompare((const char *) name,"svg") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
(void) FormatLocaleFile(svg_info->file,"fill \"black\"\n");
(void) FormatLocaleFile(svg_info->file,"fill-opacity 1\n");
(void) FormatLocaleFile(svg_info->file,"stroke \"none\"\n");
@@ -1137,7 +1146,7 @@
{
if (LocaleCompare((const char *) name,"text") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
svg_info->bounds.x=0.0;
svg_info->bounds.y=0.0;
svg_info->bounds.width=0.0;
@@ -1172,7 +1181,17 @@
draw_info=DestroyDrawInfo(draw_info);
*svg_info->text='\0';
}
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
+ break;
+ }
+ break;
+ }
+ case 'U':
+ case 'u':
+ {
+ if (LocaleCompare((char *) name,"use") == 0)
+ {
+ PushGraphicContext(id);
break;
}
break;
@@ -1513,7 +1532,10 @@
}
if (LocaleCompare(keyword,"href") == 0)
{
- (void) CloneString(&svg_info->url,value);
+ if (*value != '#')
+ (void) CloneString(&svg_info->url,value);
+ else
+ (void) CloneString(&svg_info->url,value+1);
break;
}
break;
@@ -2196,7 +2218,10 @@
}
if (LocaleCompare(keyword,"xlink:href") == 0)
{
- (void) CloneString(&svg_info->url,value);
+ if (*value != '#')
+ (void) CloneString(&svg_info->url,value);
+ else
+ (void) CloneString(&svg_info->url,value+1);
break;
}
if (LocaleCompare(keyword,"x1") == 0)
@@ -2273,7 +2298,7 @@
sx,sy,tx,ty);
if (*background != '\0')
{
- (void) FormatLocaleFile(svg_info->file,"push graphic-context\n");
+ PushGraphicContext(id);
(void) FormatLocaleFile(svg_info->file,"fill %s\n",background);
(void) FormatLocaleFile(svg_info->file,
"rectangle 0,0 %g,%g\n",svg_info->view_box.width,
@@ -2566,6 +2591,20 @@
}
break;
}
+ case 'U':
+ case 'u':
+ {
+ if (LocaleCompare((char *) name,"use") == 0)
+ {
+ if ((svg_info->bounds.x != 0.0) || (svg_info->bounds.y != 0.0))
+ (void) FormatLocaleFile(svg_info->file,"translate %g,%g\n",
+ svg_info->bounds.x,svg_info->bounds.y);
+ (void) FormatLocaleFile(svg_info->file,"use \"%s\"\n",svg_info->url);
+ (void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
+ break;
+ }
+ break;
+ }
default:
break;
}
@@ -3708,7 +3747,7 @@
blob=(unsigned char *) RelinquishMagickMemory(blob);
(void) FormatLocaleString(message,MagickPathExtent,
" <image id=\"image%.20g\" width=\"%.20g\" height=\"%.20g\" "
- "x=\"%.20g\" y=\"%.20g\"\n xlink:href=\"data:image/png;base64,",
+ "x=\"%.20g\" y=\"%.20g\"\n href=\"data:image/png;base64,",
(double) image->scene,(double) image->columns,(double) image->rows,
(double) image->page.x,(double) image->page.y);
(void) WriteBlobString(image,message);
@@ -4817,7 +4856,7 @@
GetNextToken(q,&q,extent,token);
(void) FormatLocaleString(message,MagickPathExtent,
" <image x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" "
- "xlink:href=\"%s\"/>\n",primitive_info[j].point.x,
+ "href=\"%s\"/>\n",primitive_info[j].point.x,
primitive_info[j].point.y,primitive_info[j+1].point.x,
primitive_info[j+1].point.y,token);
(void) WriteBlobString(image,message);