% You may not use this file except in compliance with the License. You may %
% obtain a copy of the License at %
% %
-% https://www.imagemagick.org/script/license.php %
+% https://imagemagick.org/script/license.php %
% %
% Unless required by applicable law or agreed to in writing, software %
% distributed under the License is distributed on an "AS IS" BASIS, %
%
%
*/
-
-
+\f
/*
Include declarations.
*/
#include "librsvg/librsvg-features.h"
#endif
#endif
-
-
+\f
+/*
+ Define declarations.
+*/
+#define DefaultSVGDensity 96.0
+\f
/*
Typedef declarations.
*/
xmlDocPtr
document;
#endif
-} SVGInfo;
-
+ ssize_t
+ svgDepth;
+} SVGInfo;
+\f
/*
Forward declarations.
*/
{
if (length < 4)
return(MagickFalse);
- if (LocaleNCompare((const char *) magick,"?xml",4) == 0)
+ if (LocaleNCompare((const char *) magick+1,"svg",3) == 0)
+ return(MagickTrue);
+ if (length < 5)
+ return(MagickFalse);
+ if (LocaleNCompare((const char *) magick+1,"?xml",4) == 0)
return(MagickTrue);
return(MagickFalse);
}
}
GetNextToken(p,&p,MagickPathExtent,token);
if (LocaleNCompare(token,"cm",2) == 0)
- return(96.0*svg_info->scale[0]/2.54*value);
+ return(DefaultSVGDensity*svg_info->scale[0]/2.54*value);
if (LocaleNCompare(token,"em",2) == 0)
return(svg_info->pointsize*value);
if (LocaleNCompare(token,"ex",2) == 0)
return(svg_info->pointsize*value/2.0);
if (LocaleNCompare(token,"in",2) == 0)
- return(96.0*svg_info->scale[0]*value);
+ return(DefaultSVGDensity*svg_info->scale[0]*value);
if (LocaleNCompare(token,"mm",2) == 0)
- return(96.0*svg_info->scale[0]/25.4*value);
+ return(DefaultSVGDensity*svg_info->scale[0]/25.4*value);
if (LocaleNCompare(token,"pc",2) == 0)
- return(96.0*svg_info->scale[0]/6.0*value);
+ return(DefaultSVGDensity*svg_info->scale[0]/6.0*value);
if (LocaleNCompare(token,"pt",2) == 0)
- return(1.25*svg_info->scale[0]*value);
+ return(svg_info->scale[0]*value);
if (LocaleNCompare(token,"px",2) == 0)
return(value);
return(value);
}
-static void StripStyleTokens(char *message)
-{
- register char
- *p,
- *q;
-
- size_t
- length;
-
- assert(message != (char *) NULL);
- if (*message == '\0')
- return;
- length=strlen(message);
- p=message;
- while (isspace((int) ((unsigned char) *p)) != 0)
- p++;
- q=message+length-1;
- while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
- q--;
- (void) memcpy(message,p,(size_t) (q-p+1));
- message[q-p+1]='\0';
- StripString(message);
-}
-
-static char **GetStyleTokens(void *context,const char *style,
- size_t *number_tokens)
-{
- char
- *text,
- **tokens;
-
- register ssize_t
- i;
-
- SVGInfo
- *svg_info;
-
- svg_info=(SVGInfo *) context;
- (void) svg_info;
- *number_tokens=0;
- if (style == (const char *) NULL)
- return((char **) NULL);
- text=AcquireString(style);
- (void) SubstituteString(&text,":","\n");
- (void) SubstituteString(&text,";","\n");
- tokens=StringToList(text);
- text=DestroyString(text);
- for (i=0; tokens[i] != (char *) NULL; i++)
- StripStyleTokens(tokens[i]);
- *number_tokens=(size_t) i;
- return(tokens);
-}
-
-static char **GetTransformTokens(void *context,const char *text,
- size_t *number_tokens)
-{
- char
- **tokens;
-
- register const char
- *p,
- *q;
-
- register ssize_t
- i;
-
- size_t
- extent;
-
- SVGInfo
- *svg_info;
-
- svg_info=(SVGInfo *) context;
- *number_tokens=0;
- if (text == (const char *) NULL)
- return((char **) NULL);
- extent=8;
- tokens=(char **) AcquireQuantumMemory(extent+2UL,sizeof(*tokens));
- if (tokens == (char **) NULL)
- {
- (void) ThrowMagickException(svg_info->exception,GetMagickModule(),
- ResourceLimitError,"MemoryAllocationFailed","`%s'",text);
- return((char **) NULL);
- }
- /*
- Convert string to an ASCII list.
- */
- i=0;
- p=text;
- for (q=p; *q != '\0'; q++)
- {
- if ((*q != '(') && (*q != ')') && (*q != '\0'))
- continue;
- if (i == (ssize_t) extent)
- {
- extent<<=1;
- tokens=(char **) ResizeQuantumMemory(tokens,extent+2,sizeof(*tokens));
- if (tokens == (char **) NULL)
- {
- (void) ThrowMagickException(svg_info->exception,GetMagickModule(),
- ResourceLimitError,"MemoryAllocationFailed","`%s'",text);
- return((char **) NULL);
- }
- }
- tokens[i]=AcquireString(p);
- (void) CopyMagickString(tokens[i],p,(size_t) (q-p+1));
- StripString(tokens[i]);
- i++;
- p=q+1;
- }
- tokens[i]=AcquireString(p);
- (void) CopyMagickString(tokens[i],p,(size_t) (q-p+1));
- StripString(tokens[i++]);
- tokens[i]=(char *) NULL;
- *number_tokens=(size_t) i;
- return(tokens);
-}
-
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
name,(xmlElementTypeVal) type,content);
}
+static void SVGStripString(const MagickBooleanType trim,char *message)
+{
+ register char
+ *p,
+ *q;
+
+ size_t
+ length;
+
+ assert(message != (char *) NULL);
+ if (*message == '\0')
+ return;
+ /*
+ Remove comment.
+ */
+ q=message;
+ for (p=message; *p != '\0'; p++)
+ {
+ if ((*p == '/') && (*(p+1) == '*'))
+ {
+ for ( ; *p != '\0'; p++)
+ if ((*p == '*') && (*(p+1) == '/'))
+ {
+ p+=2;
+ break;
+ }
+ if (*p == '\0')
+ break;
+ }
+ *q++=(*p);
+ }
+ *q='\0';
+ if (trim != MagickFalse)
+ {
+ /*
+ Remove whitespace.
+ */
+ length=strlen(message);
+ p=message;
+ while (isspace((int) ((unsigned char) *p)) != 0)
+ p++;
+ if ((*p == '\'') || (*p == '"'))
+ p++;
+ q=message+length-1;
+ while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
+ q--;
+ if (q > p)
+ if ((*q == '\'') || (*q == '"'))
+ q--;
+ (void) memmove(message,p,(size_t) (q-p+1));
+ message[q-p+1]='\0';
+ }
+ /*
+ Convert newlines to a space.
+ */
+ for (p=message; *p != '\0'; p++)
+ if (*p == '\n')
+ *p=' ';
+}
+
+static char **SVGKeyValuePairs(void *context,const int key_sentinel,
+ const int value_sentinel,const char *text,size_t *number_tokens)
+{
+ char
+ **tokens;
+
+ register const char
+ *p,
+ *q;
+
+ register ssize_t
+ i;
+
+ size_t
+ extent;
+
+ SVGInfo
+ *svg_info;
+
+ svg_info=(SVGInfo *) context;
+ *number_tokens=0;
+ if (text == (const char *) NULL)
+ return((char **) NULL);
+ extent=8;
+ tokens=(char **) AcquireQuantumMemory(extent+2UL,sizeof(*tokens));
+ if (tokens == (char **) NULL)
+ {
+ (void) ThrowMagickException(svg_info->exception,GetMagickModule(),
+ ResourceLimitError,"MemoryAllocationFailed","`%s'",text);
+ return((char **) NULL);
+ }
+ /*
+ Convert string to an ASCII list.
+ */
+ i=0;
+ p=text;
+ for (q=p; *q != '\0'; q++)
+ {
+ if ((*q != key_sentinel) && (*q != value_sentinel) && (*q != '\0'))
+ continue;
+ if (i == (ssize_t) extent)
+ {
+ extent<<=1;
+ tokens=(char **) ResizeQuantumMemory(tokens,extent+2,sizeof(*tokens));
+ if (tokens == (char **) NULL)
+ {
+ (void) ThrowMagickException(svg_info->exception,GetMagickModule(),
+ ResourceLimitError,"MemoryAllocationFailed","`%s'",text);
+ return((char **) NULL);
+ }
+ }
+ tokens[i]=AcquireString(p);
+ (void) CopyMagickString(tokens[i],p,(size_t) (q-p+1));
+ SVGStripString(MagickTrue,tokens[i]);
+ i++;
+ p=q+1;
+ }
+ tokens[i]=AcquireString(p);
+ (void) CopyMagickString(tokens[i],p,(size_t) (q-p+1));
+ SVGStripString(MagickTrue,tokens[i++]);
+ tokens[i]=(char *) NULL;
+ *number_tokens=(size_t) i;
+ return(tokens);
+}
+
static void SVGNotationDeclaration(void *context,const xmlChar *name,
const xmlChar *public_id,const xmlChar *system_id)
{
name,public_id,system_id);
}
+static void SVGProcessStyleElement(void *context,const xmlChar *name,
+ const char *style)
+{
+ char
+ background[MagickPathExtent],
+ *color,
+ *keyword,
+ *units,
+ *value;
+
+ char
+ **tokens;
+
+ register ssize_t
+ i;
+
+ size_t
+ number_tokens;
+
+ SVGInfo
+ *svg_info;
+
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," ");
+ svg_info=(SVGInfo *) context;
+ tokens=SVGKeyValuePairs(context,':',';',style,&number_tokens);
+ if (tokens == (char **) NULL)
+ return;
+ for (i=0; i < (ssize_t) (number_tokens-1); i+=2)
+ {
+ keyword=(char *) tokens[i];
+ value=(char *) tokens[i+1];
+ if (LocaleCompare(keyword,"font-size") != 0)
+ continue;
+ svg_info->pointsize=GetUserSpaceCoordinateValue(svg_info,0,value);
+ (void) FormatLocaleFile(svg_info->file,"font-size %g\n",
+ svg_info->pointsize);
+ }
+ color=AcquireString("none");
+ units=AcquireString("userSpaceOnUse");
+ for (i=0; i < (ssize_t) (number_tokens-1); i+=2)
+ {
+ keyword=(char *) tokens[i];
+ value=(char *) tokens[i+1];
+ (void) LogMagickEvent(CoderEvent,GetMagickModule()," %s: %s",keyword,
+ value);
+ switch (*keyword)
+ {
+ case 'B':
+ case 'b':
+ {
+ if (LocaleCompare((const char *) name,"background") == 0)
+ {
+ if (LocaleCompare((const char *) name,"svg") == 0)
+ (void) CopyMagickString(background,value,MagickPathExtent);
+ break;
+ }
+ break;
+ }
+ case 'C':
+ case 'c':
+ {
+ if (LocaleCompare(keyword,"clip-path") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"clip-path \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"clip-rule") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"clip-rule \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"clipPathUnits") == 0)
+ {
+ (void) CloneString(&units,value);
+ (void) FormatLocaleFile(svg_info->file,"clip-units \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"color") == 0)
+ {
+ (void) CloneString(&color,value);
+ break;
+ }
+ break;
+ }
+ case 'F':
+ case 'f':
+ {
+ if (LocaleCompare(keyword,"fill") == 0)
+ {
+ if (LocaleCompare(value,"currentColor") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"fill \"%s\"\n",color);
+ break;
+ }
+ if (LocaleCompare(value,"#000000ff") == 0)
+ (void) FormatLocaleFile(svg_info->file,"fill '#000000'\n");
+ else
+ (void) FormatLocaleFile(svg_info->file,"fill \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fillcolor") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"fill \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fill-rule") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"fill-rule \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"fill-opacity") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"fill-opacity \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font") == 0)
+ {
+ char
+ family[MagickPathExtent],
+ size[MagickPathExtent],
+ style[MagickPathExtent];
+
+ if (sscanf(value,"%2048s %2048s %2048s",style,size,family) != 3)
+ break;
+ if (GetUserSpaceCoordinateValue(svg_info,0,style) == 0)
+ (void) FormatLocaleFile(svg_info->file,"font-style \"%s\"\n",
+ style);
+ else
+ if (sscanf(value,"%2048s %2048s",size,family) != 2)
+ break;
+ (void) FormatLocaleFile(svg_info->file,"font-size \"%s\"\n",size);
+ (void) FormatLocaleFile(svg_info->file,"font-family \"%s\"\n",
+ family);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-family") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"font-family \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-stretch") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"font-stretch \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-style") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"font-style \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-size") == 0)
+ {
+ svg_info->pointsize=GetUserSpaceCoordinateValue(svg_info,0,value);
+ (void) FormatLocaleFile(svg_info->file,"font-size %g\n",
+ svg_info->pointsize);
+ break;
+ }
+ if (LocaleCompare(keyword,"font-weight") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"font-weight \"%s\"\n",
+ value);
+ break;
+ }
+ break;
+ }
+ case 'K':
+ case 'k':
+ {
+ if (LocaleCompare(keyword,"kerning") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"kerning \"%s\"\n",value);
+ break;
+ }
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare(keyword,"letter-spacing") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"letter-spacing \"%s\"\n",
+ value);
+ break;
+ }
+ break;
+ }
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare(keyword,"mask") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"mask \"%s\"\n",value);
+ break;
+ }
+ break;
+ }
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare(keyword,"offset") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"offset %g\n",
+ GetUserSpaceCoordinateValue(svg_info,1,value));
+ break;
+ }
+ if (LocaleCompare(keyword,"opacity") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"opacity \"%s\"\n",value);
+ break;
+ }
+ break;
+ }
+ case 'S':
+ case 's':
+ {
+ if (LocaleCompare(keyword,"stop-color") == 0)
+ {
+ (void) CloneString(&svg_info->stop_color,value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke") == 0)
+ {
+ if (LocaleCompare(value,"currentColor") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke \"%s\"\n",color);
+ break;
+ }
+ if (LocaleCompare(value,"#000000ff") == 0)
+ (void) FormatLocaleFile(svg_info->file,"fill '#000000'\n");
+ else
+ (void) FormatLocaleFile(svg_info->file,
+ "stroke \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-antialiasing") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-antialias %d\n",
+ LocaleCompare(value,"true") == 0);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-dasharray") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-dasharray %s\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-dashoffset") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-dashoffset %g\n",
+ GetUserSpaceCoordinateValue(svg_info,1,value));
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-linecap") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-linecap \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-linejoin") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-linejoin \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-miterlimit") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-miterlimit \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-opacity") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-opacity \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"stroke-width") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"stroke-width %g\n",
+ GetUserSpaceCoordinateValue(svg_info,1,value));
+ break;
+ }
+ break;
+ }
+ case 't':
+ case 'T':
+ {
+ if (LocaleCompare(keyword,"text-align") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"text-align \"%s\"\n",value);
+ break;
+ }
+ if (LocaleCompare(keyword,"text-anchor") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"text-anchor \"%s\"\n",
+ value);
+ break;
+ }
+ if (LocaleCompare(keyword,"text-decoration") == 0)
+ {
+ if (LocaleCompare(value,"underline") == 0)
+ (void) FormatLocaleFile(svg_info->file,"decorate underline\n");
+ if (LocaleCompare(value,"line-through") == 0)
+ (void) FormatLocaleFile(svg_info->file,"decorate line-through\n");
+ if (LocaleCompare(value,"overline") == 0)
+ (void) FormatLocaleFile(svg_info->file,"decorate overline\n");
+ break;
+ }
+ if (LocaleCompare(keyword,"text-antialiasing") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"text-antialias %d\n",
+ LocaleCompare(value,"true") == 0);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (units != (char *) NULL)
+ units=DestroyString(units);
+ if (color != (char *) NULL)
+ color=DestroyString(color);
+ for (i=0; tokens[i] != (char *) NULL; i++)
+ tokens[i]=DestroyString(tokens[i]);
+ tokens=(char **) RelinquishMagickMemory(tokens);
+}
+
static void SVGUnparsedEntityDeclaration(void *context,const xmlChar *name,
const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
{
if (LocaleCompare(keyword,"x") == 0)
{
if (LocaleCompare((char *) name,"tspan") != 0)
- svg_info->bounds.x=GetUserSpaceCoordinateValue(svg_info,1,value)-
- svg_info->center.x;
+ svg_info->bounds.x=GetUserSpaceCoordinateValue(svg_info,1,
+ value)-svg_info->center.x;
break;
}
if (LocaleCompare(keyword,"x1") == 0)
}
break;
}
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare((const char *) name,"mask") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"push mask \"%s\"\n",id);
+ break;
+ }
+ break;
+ }
case 'P':
case 'p':
{
case 'S':
case 's':
{
- if (LocaleCompare((const char *) name,"symbol") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,"push symbol\n");
- break;
- }
+ if (LocaleCompare((char *) name,"style") == 0)
+ break;
if (LocaleCompare((const char *) name,"svg") == 0)
{
+ svg_info->svgDepth++;
PushGraphicContext(id);
+ (void) FormatLocaleFile(svg_info->file,"compliance \"SVG\"\n");
(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");
(void) FormatLocaleFile(svg_info->file,"fill-rule nonzero\n");
break;
}
+ if (LocaleCompare((const char *) name,"symbol") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"push symbol\n");
+ break;
+ }
break;
}
case 'T':
if (LocaleCompare((const char *) name,"text") == 0)
{
PushGraphicContext(id);
+ (void) FormatLocaleFile(svg_info->file,"class \"text\"\n");
+ (void) FormatLocaleFile(svg_info->file,"translate %g,%g\n",
+ svg_info->bounds.x,svg_info->bounds.y);
+ svg_info->center.x=svg_info->bounds.x;
+ svg_info->center.y=svg_info->bounds.y;
svg_info->bounds.x=0.0;
svg_info->bounds.y=0.0;
svg_info->bounds.width=0.0;
{
if (*svg_info->text != '\0')
{
- DrawInfo
- *draw_info;
-
- TypeMetric
- metrics;
-
char
*text;
svg_info->bounds.x-svg_info->center.x,svg_info->bounds.y-
svg_info->center.y,text);
text=DestroyString(text);
- draw_info=CloneDrawInfo(svg_info->image_info,(DrawInfo *) NULL);
- draw_info->pointsize=svg_info->pointsize;
- draw_info->text=AcquireString(svg_info->text);
- (void) ConcatenateString(&draw_info->text," ");
- (void) GetTypeMetrics(svg_info->image,draw_info,
- &metrics,svg_info->exception);
- svg_info->bounds.x+=metrics.width;
- draw_info=DestroyDrawInfo(draw_info);
*svg_info->text='\0';
}
PushGraphicContext(id);
case 'C':
case 'c':
{
+ if (LocaleCompare(keyword,"class") == 0)
+ {
+ const char
+ *p;
+
+ for (p=value; ; )
+ {
+ GetNextToken(p,&p,MagickPathExtent,token);
+ if (*token == ',')
+ GetNextToken(p,&p,MagickPathExtent,token);
+ if (*token != '\0')
+ {
+ (void) FormatLocaleFile(svg_info->file,"class \"%s\"\n",
+ value);
+ break;
+ }
+ }
+ break;
+ }
if (LocaleCompare(keyword,"clip-path") == 0)
{
(void) FormatLocaleFile(svg_info->file,"clip-path \"%s\"\n",
}
if (LocaleCompare(keyword,"dx") == 0)
{
- svg_info->bounds.x+=GetUserSpaceCoordinateValue(svg_info,1,value);
+ double
+ dx;
+
+ dx=GetUserSpaceCoordinateValue(svg_info,1,value);
+ svg_info->bounds.x+=dx;
+ if (LocaleCompare((char *) name,"text") == 0)
+ (void) FormatLocaleFile(svg_info->file,"translate %g,0.0\n",dx);
break;
}
if (LocaleCompare(keyword,"dy") == 0)
{
- svg_info->bounds.y+=
- GetUserSpaceCoordinateValue(svg_info,-1,value);
+ double
+ dy;
+
+ dy=GetUserSpaceCoordinateValue(svg_info,-1,value);
+ svg_info->bounds.y+=dy;
+ if (LocaleCompare((char *) name,"text") == 0)
+ (void) FormatLocaleFile(svg_info->file,"translate 0.0,%g\n",dy);
break;
}
break;
GetAffineMatrix(&transform);
(void) LogMagickEvent(CoderEvent,GetMagickModule()," ");
- tokens=GetTransformTokens(context,value,&number_tokens);
+ tokens=SVGKeyValuePairs(context,'(',')',value,&number_tokens);
if (tokens == (char **) NULL)
break;
for (j=0; j < (ssize_t) (number_tokens-1); j+=2)
}
break;
}
+ case 'K':
+ case 'k':
+ {
+ if (LocaleCompare(keyword,"kerning") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"kerning \"%s\"\n",
+ value);
+ break;
+ }
+ break;
+ }
+ case 'L':
+ case 'l':
+ {
+ if (LocaleCompare(keyword,"letter-spacing") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"letter-spacing \"%s\"\n",
+ value);
+ break;
+ }
+ break;
+ }
case 'M':
case 'm':
{
GetUserSpaceCoordinateValue(svg_info,1,value);
break;
}
+ if (LocaleCompare(keyword,"mask") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"mask \"%s\"\n",value);
+ break;
+ }
if (LocaleCompare(keyword,"minor") == 0)
{
svg_info->element.minor=
}
if (LocaleCompare(keyword,"style") == 0)
{
- (void) LogMagickEvent(CoderEvent,GetMagickModule()," ");
- tokens=GetStyleTokens(context,value,&number_tokens);
- for (j=0; j < (ssize_t) (number_tokens-1); j+=2)
- {
- keyword=(char *) tokens[j];
- value=(char *) tokens[j+1];
- (void) LogMagickEvent(CoderEvent,GetMagickModule(),
- " %s: %s",keyword,value);
- switch (*keyword)
- {
- case 'B':
- case 'b':
- {
- if (LocaleCompare((const char *) name,"background") == 0)
- {
- if (LocaleCompare((const char *) name,"svg") == 0)
- (void) CopyMagickString(background,value,
- MagickPathExtent);
- break;
- }
- break;
- }
- case 'C':
- case 'c':
- {
- if (LocaleCompare(keyword,"clip-path") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "clip-path \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"clip-rule") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "clip-rule \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"clipPathUnits") == 0)
- {
- (void) CloneString(&units,value);
- (void) FormatLocaleFile(svg_info->file,
- "clip-units \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"color") == 0)
- {
- (void) CloneString(&color,value);
- break;
- }
- break;
- }
- case 'F':
- case 'f':
- {
- if (LocaleCompare(keyword,"fill") == 0)
- {
- if (LocaleCompare(value,"currentColor") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "fill \"%s\"\n",color);
- break;
- }
- if (LocaleCompare(value,"#000000ff") == 0)
- (void) FormatLocaleFile(svg_info->file,
- "fill '#000000'\n");
- else
- (void) FormatLocaleFile(svg_info->file,
- "fill \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"fillcolor") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,"fill \"%s\"\n",
- value);
- break;
- }
- if (LocaleCompare(keyword,"fill-rule") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "fill-rule \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"fill-opacity") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "fill-opacity \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"font-family") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "font-family \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"font-stretch") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "font-stretch \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"font-style") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "font-style \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"font-size") == 0)
- {
- svg_info->pointsize=GetUserSpaceCoordinateValue(
- svg_info,0,value);
- (void) FormatLocaleFile(svg_info->file,"font-size %g\n",
- svg_info->pointsize);
- break;
- }
- if (LocaleCompare(keyword,"font-weight") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "font-weight \"%s\"\n",value);
- break;
- }
- break;
- }
- case 'O':
- case 'o':
- {
- if (LocaleCompare(keyword,"offset") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,"offset %g\n",
- GetUserSpaceCoordinateValue(svg_info,1,value));
- break;
- }
- if (LocaleCompare(keyword,"opacity") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "opacity \"%s\"\n",value);
- break;
- }
- break;
- }
- case 'S':
- case 's':
- {
- if (LocaleCompare(keyword,"stop-color") == 0)
- {
- (void) CloneString(&svg_info->stop_color,value);
- break;
- }
- if (LocaleCompare(keyword,"stroke") == 0)
- {
- if (LocaleCompare(value,"currentColor") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke \"%s\"\n",color);
- break;
- }
- if (LocaleCompare(value,"#000000ff") == 0)
- (void) FormatLocaleFile(svg_info->file,
- "fill '#000000'\n");
- else
- (void) FormatLocaleFile(svg_info->file,
- "stroke \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"stroke-antialiasing") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-antialias %d\n",
- LocaleCompare(value,"true") == 0);
- break;
- }
- if (LocaleCompare(keyword,"stroke-dasharray") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-dasharray %s\n",value);
- break;
- }
- if (LocaleCompare(keyword,"stroke-dashoffset") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-dashoffset %g\n",
- GetUserSpaceCoordinateValue(svg_info,1,value));
- break;
- }
- if (LocaleCompare(keyword,"stroke-linecap") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-linecap \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"stroke-linejoin") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-linejoin \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"stroke-miterlimit") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-miterlimit \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"stroke-opacity") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-opacity \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"stroke-width") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "stroke-width %g\n",
- GetUserSpaceCoordinateValue(svg_info,1,value));
- break;
- }
- break;
- }
- case 't':
- case 'T':
- {
- if (LocaleCompare(keyword,"text-align") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "text-align \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"text-anchor") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "text-anchor \"%s\"\n",value);
- break;
- }
- if (LocaleCompare(keyword,"text-decoration") == 0)
- {
- if (LocaleCompare(value,"underline") == 0)
- (void) FormatLocaleFile(svg_info->file,
- "decorate underline\n");
- if (LocaleCompare(value,"line-through") == 0)
- (void) FormatLocaleFile(svg_info->file,
- "decorate line-through\n");
- if (LocaleCompare(value,"overline") == 0)
- (void) FormatLocaleFile(svg_info->file,
- "decorate overline\n");
- break;
- }
- if (LocaleCompare(keyword,"text-antialiasing") == 0)
- {
- (void) FormatLocaleFile(svg_info->file,
- "text-antialias %d\n",
- LocaleCompare(value,"true") == 0);
- break;
- }
- break;
- }
- default:
- break;
- }
- }
- for (j=0; tokens[j] != (char *) NULL; j++)
- tokens[j]=DestroyString(tokens[j]);
- tokens=(char **) RelinquishMagickMemory(tokens);
+ SVGProcessStyleElement(context,name,value);
break;
}
break;
GetAffineMatrix(&transform);
(void) LogMagickEvent(CoderEvent,GetMagickModule()," ");
- tokens=GetTransformTokens(context,value,&number_tokens);
+ tokens=SVGKeyValuePairs(context,'(',')',value,&number_tokens);
if (tokens == (char **) NULL)
break;
for (j=0; j < (ssize_t) (number_tokens-1); j+=2)
p=(const char *) value;
GetNextToken(p,&p,MagickPathExtent,token);
angle=StringToDouble(value,(char **) NULL);
+ affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+ affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
GetNextToken(p,&p,MagickPathExtent,token);
y=StringToDouble(token,&next_token);
- affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
- affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
- affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
- affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
- affine.tx=x;
- affine.ty=y;
- svg_info->center.x=x;
- svg_info->center.y=y;
+ affine.tx=svg_info->bounds.x+x*
+ cos(DegreesToRadians(fmod(angle,360.0)))+y*
+ sin(DegreesToRadians(fmod(angle,360.0)));
+ affine.ty=svg_info->bounds.y-x*
+ sin(DegreesToRadians(fmod(angle,360.0)))+y*
+ cos(DegreesToRadians(fmod(angle,360.0)));
+ affine.tx-=x/2.0;
+ affine.ty-=y/2.0;
break;
}
break;
(*p == ','))
break;
affine.tx=GetUserSpaceCoordinateValue(svg_info,1,value);
- affine.ty=affine.tx;
+ affine.ty=0;
if (*p != '\0')
affine.ty=GetUserSpaceCoordinateValue(svg_info,-1,
p+1);
0.0;
(void) FormatLocaleFile(svg_info->file,"affine %g 0 0 %g %g %g\n",
sx,sy,tx,ty);
- if (*background != '\0')
+ if ((svg_info->svgDepth == 1) && (*background != '\0'))
{
PushGraphicContext(id);
(void) FormatLocaleFile(svg_info->file,"fill %s\n",background);
}
}
(void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
- units=DestroyString(units);
+ if (units != (char *) NULL)
+ units=DestroyString(units);
if (color != (char *) NULL)
color=DestroyString(color);
}
{
if (LocaleCompare((const char *) name,"circle") == 0)
{
+ (void) FormatLocaleFile(svg_info->file,"class \"circle\"\n");
(void) FormatLocaleFile(svg_info->file,"circle %g,%g %g,%g\n",
svg_info->element.cx,svg_info->element.cy,svg_info->element.cx,
svg_info->element.cy+svg_info->element.minor);
double
angle;
+ (void) FormatLocaleFile(svg_info->file,"class \"ellipse\"\n");
angle=svg_info->element.angle;
(void) FormatLocaleFile(svg_info->file,"ellipse %g,%g %g,%g 0,360\n",
svg_info->element.cx,svg_info->element.cy,
{
if (LocaleCompare((const char *) name,"line") == 0)
{
+ (void) FormatLocaleFile(svg_info->file,"class \"line\"\n");
(void) FormatLocaleFile(svg_info->file,"line %g,%g %g,%g\n",
svg_info->segment.x1,svg_info->segment.y1,svg_info->segment.x2,
svg_info->segment.y2);
}
break;
}
+ case 'M':
+ case 'm':
+ {
+ if (LocaleCompare((const char *) name,"mask") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"pop mask\n");
+ break;
+ }
+ break;
+ }
case 'P':
case 'p':
{
}
if (LocaleCompare((const char *) name,"path") == 0)
{
+ (void) FormatLocaleFile(svg_info->file,"class \"path\"\n");
(void) FormatLocaleFile(svg_info->file,"path \"%s\"\n",
svg_info->vertices);
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
}
if (LocaleCompare((const char *) name,"polygon") == 0)
{
+ (void) FormatLocaleFile(svg_info->file,"class \"polygon\"\n");
(void) FormatLocaleFile(svg_info->file,"polygon %s\n",
svg_info->vertices);
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
}
if (LocaleCompare((const char *) name,"polyline") == 0)
{
+ (void) FormatLocaleFile(svg_info->file,"class \"polyline\"\n");
(void) FormatLocaleFile(svg_info->file,"polyline %s\n",
svg_info->vertices);
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
{
if ((svg_info->radius.x == 0.0) && (svg_info->radius.y == 0.0))
{
- (void) FormatLocaleFile(svg_info->file,"rectangle %g,%g %g,%g\n",
- svg_info->bounds.x,svg_info->bounds.y,
- svg_info->bounds.x+svg_info->bounds.width,
- svg_info->bounds.y+svg_info->bounds.height);
+ (void) FormatLocaleFile(svg_info->file,"class \"rect\"\n");
+ if ((fabs(svg_info->bounds.width-1.0) < MagickEpsilon) &&
+ (fabs(svg_info->bounds.height-1.0) < MagickEpsilon))
+ (void) FormatLocaleFile(svg_info->file,"point %g,%g\n",
+ svg_info->bounds.x,svg_info->bounds.y);
+ else
+ (void) FormatLocaleFile(svg_info->file,
+ "rectangle %g,%g %g,%g\n",svg_info->bounds.x,
+ svg_info->bounds.y,svg_info->bounds.x+svg_info->bounds.width,
+ svg_info->bounds.y+svg_info->bounds.height);
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
break;
}
svg_info->stop_color,svg_info->offset);
break;
}
- if (LocaleCompare((const char *) name,"symbol") == 0)
+ if (LocaleCompare((char *) name,"style") == 0)
{
- (void) FormatLocaleFile(svg_info->file,"pop symbol\n");
+ char
+ *keyword,
+ **tokens,
+ *value;
+
+ register ssize_t
+ j;
+
+ size_t
+ number_tokens;
+
+ /*
+ Find style definitions in svg_info->text.
+ */
+ tokens=SVGKeyValuePairs(context,'{','}',svg_info->text,
+ &number_tokens);
+ if (tokens == (char **) NULL)
+ break;
+ for (j=0; j < (ssize_t) (number_tokens-1); j+=2)
+ {
+ keyword=(char *) tokens[j];
+ value=(char *) tokens[j+1];
+ (void) FormatLocaleFile(svg_info->file,"push class \"%s\"\n",
+ *keyword == '.' ? keyword+1 : keyword);
+ SVGProcessStyleElement(context,name,value);
+ (void) FormatLocaleFile(svg_info->file,"pop class\n");
+ }
break;
}
if (LocaleCompare((const char *) name,"svg") == 0)
{
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
+ svg_info->svgDepth--;
+ break;
+ }
+ if (LocaleCompare((const char *) name,"symbol") == 0)
+ {
+ (void) FormatLocaleFile(svg_info->file,"pop symbol\n");
break;
}
break;
char
*text;
+ SVGStripString(MagickTrue,svg_info->text);
text=EscapeString(svg_info->text,'\'');
- (void) FormatLocaleFile(svg_info->file,"text %g,%g \"%s\"\n",
- svg_info->bounds.x,svg_info->bounds.y,text);
+ (void) FormatLocaleFile(svg_info->file,"text 0,0 \"%s\"\n",text);
text=DestroyString(text);
*svg_info->text='\0';
+ svg_info->center.x=0.0;
+ svg_info->center.y=0.0;
}
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
break;
{
if (*svg_info->text != '\0')
{
- DrawInfo
- *draw_info;
-
- TypeMetric
- metrics;
-
char
*text;
+ (void) FormatLocaleFile(svg_info->file,"class \"tspan\"\n");
text=EscapeString(svg_info->text,'\'');
(void) FormatLocaleFile(svg_info->file,"text %g,%g \"%s\"\n",
- svg_info->bounds.x,svg_info->bounds.y,text);
+ svg_info->bounds.x-svg_info->center.x,svg_info->bounds.y-
+ svg_info->center.y,text);
text=DestroyString(text);
- draw_info=CloneDrawInfo(svg_info->image_info,(DrawInfo *) NULL);
- draw_info->pointsize=svg_info->pointsize;
- draw_info->text=AcquireString(svg_info->text);
- (void) ConcatenateString(&draw_info->text," ");
- (void) GetTypeMetrics(svg_info->image,draw_info,&metrics,
- svg_info->exception);
- svg_info->bounds.x+=metrics.width;
- draw_info=DestroyDrawInfo(draw_info);
*svg_info->text='\0';
}
(void) FormatLocaleFile(svg_info->file,"pop graphic-context\n");
for (i=0; i < (ssize_t) length; i++)
*p++=c[i];
*p='\0';
- StripString(text);
+ SVGStripString(MagickFalse,text);
if (svg_info->text == (char *) NULL)
svg_info->text=text;
else
(void) ConcatenateString(&svg_info->comment,(const char *) value);
}
+static void SVGWarning(void *,const char *,...)
+ magick_attribute((__format__ (__printf__,2,3)));
+
static void SVGWarning(void *context,const char *format,...)
{
char
va_end(operands);
}
+static void SVGError(void *,const char *,...)
+ magick_attribute((__format__ (__printf__,2,3)));
+
static void SVGError(void *context,const char *format,...)
{
char
static char
SVGDensityGeometry[] = "96.0x96.0";
-
static Image *ReadSVGImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
char
*file;
Image
- *image;
+ *image,
+ *next;
int
status,
attributes;
/*
- Our best hope of compliance with the SVG standard.
+ Our best hope for compliance with the SVG standard.
*/
status=AcquireUniqueSymbolicLink(image->filename,input_filename);
(void) AcquireUniqueFilename(output_filename);
(void) RelinquishUniqueFileResource(output_filename);
if (svg_image != (Image *) NULL)
{
+ for (next=GetFirstImageInList(svg_image); next != (Image *) NULL; )
+ {
+ (void) CopyMagickString(next->filename,image->filename,
+ MaxTextExtent);
+ (void) CopyMagickString(next->magick,image->magick,
+ MaxTextExtent);
+ next=GetNextImageInList(next);
+ }
image=DestroyImage(image);
return(svg_image);
}
(ssize_t *) NULL,&image->columns,&image->rows);
if ((image->columns != 0) || (image->rows != 0))
{
- image->resolution.x=96.0*image->columns/dimension_info.width;
- image->resolution.y=96.0*image->rows/dimension_info.height;
+ image->resolution.x=DefaultSVGDensity*image->columns/
+ dimension_info.width;
+ image->resolution.y=DefaultSVGDensity*image->rows/
+ dimension_info.height;
if (fabs(image->resolution.x) < MagickEpsilon)
image->resolution.x=image->resolution.y;
else
}
if (apply_density != MagickFalse)
{
- image->columns=image->resolution.x*dimension_info.width/96.0;
- image->rows=image->resolution.y*dimension_info.height/96.0;
+ image->columns=image->resolution.x*dimension_info.width/
+ DefaultSVGDensity;
+ image->rows=image->resolution.y*dimension_info.height/
+ DefaultSVGDensity;
}
else
{
image->rows=gdk_pixbuf_get_height(pixel_buffer);
#endif
image->alpha_trait=BlendPixelTrait;
- status=SetImageExtent(image,image->columns,image->rows,exception);
- if (status == MagickFalse)
- {
-#if !defined(MAGICKCORE_CAIRO_DELEGATE)
- g_object_unref(G_OBJECT(pixel_buffer));
-#endif
- g_object_unref(svg_handle);
- ThrowReaderException(MissingDelegateError,
- "NoDecodeDelegateForThisImageFormat");
- }
if (image_info->ping == MagickFalse)
{
#if defined(MAGICKCORE_CAIRO_DELEGATE)
size_t
stride;
+#endif
+ status=SetImageExtent(image,image->columns,image->rows,exception);
+ if (status == MagickFalse)
+ {
+#if !defined(MAGICKCORE_CAIRO_DELEGATE)
+ g_object_unref(G_OBJECT(pixel_buffer));
+#endif
+ g_object_unref(svg_handle);
+ ThrowReaderException(MissingDelegateError,
+ "NoDecodeDelegateForThisImageFormat");
+ }
+#if defined(MAGICKCORE_CAIRO_DELEGATE)
stride=4*image->columns;
#if defined(MAGICKCORE_PANGOCAIRO_DELEGATE)
stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
cairo_paint(cairo_image);
cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER);
if (apply_density != MagickFalse)
- cairo_scale(cairo_image,image->resolution.x/96.0,
- image->resolution.y/96.0);
+ cairo_scale(cairo_image,image->resolution.x/DefaultSVGDensity,
+ image->resolution.y/DefaultSVGDensity);
rsvg_handle_render_cairo(svg_handle,cairo_image);
cairo_destroy(cairo_image);
cairo_surface_destroy(cairo_surface);
g_object_unref(G_OBJECT(pixel_buffer));
#endif
(void) CloseBlob(image);
+ for (next=GetFirstImageInList(image); next != (Image *) NULL; )
+ {
+ (void) CopyMagickString(next->filename,image->filename,MaxTextExtent);
+ (void) CopyMagickString(next->magick,image->magick,MaxTextExtent);
+ next=GetNextImageInList(next);
+ }
return(GetFirstImageInList(image));
#endif
}
svg_info->image_info=image_info;
svg_info->bounds.width=image->columns;
svg_info->bounds.height=image->rows;
+ svg_info->svgDepth=0;
if (image_info->size != (char *) NULL)
(void) CloneString(&svg_info->size,image_info->size);
if (image->debug != MagickFalse)
image=(Image *) NULL;
read_info=CloneImageInfo(image_info);
SetImageInfoBlob(read_info,(void *) NULL,0);
- if (read_info->density != (char *) NULL)
- read_info->density=DestroyString(read_info->density);
(void) FormatLocaleString(read_info->filename,MagickPathExtent,"mvg:%s",
filename);
image=ReadImage(read_info,exception);
(void) SetImageProperty(image,"svg:comment",svg_info->comment,
exception);
}
+ for (next=GetFirstImageInList(image); next != (Image *) NULL; )
+ {
+ (void) CopyMagickString(next->filename,image->filename,MaxTextExtent);
+ (void) CopyMagickString(next->magick,image->magick,MaxTextExtent);
+ next=GetNextImageInList(next);
+ }
svg_info=DestroySVGInfo(svg_info);
(void) RelinquishUniqueFileResource(filename);
return(GetFirstImageInList(image));
if (LocaleCompare("clip-rule",keyword) == 0)
{
GetNextToken(q,&q,extent,token);
- (void) FormatLocaleString(message,MagickPathExtent,
- "clip-rule:%s;",token);
+ (void) FormatLocaleString(message,MagickPathExtent,"clip-rule:%s;",
+ token);
(void) WriteBlobString(image,message);
break;
}
status=MagickFalse;
break;
}
+ case 'k':
+ case 'K':
+ {
+ if (LocaleCompare("kerning",keyword) == 0)
+ {
+ GetNextToken(q,&q,extent,token);
+ (void) FormatLocaleString(message,MagickPathExtent,"kerning:%s;",
+ token);
+ (void) WriteBlobString(image,message);
+ }
+ break;
+ }
case 'l':
case 'L':
{
+ if (LocaleCompare("letter-spacing",keyword) == 0)
+ {
+ GetNextToken(q,&q,extent,token);
+ (void) FormatLocaleString(message,MagickPathExtent,
+ "letter-spacing:%s;",token);
+ (void) WriteBlobString(image,message);
+ break;
+ }
if (LocaleCompare("line",keyword) == 0)
{
primitive_type=LinePrimitive;