% July 1998 %
% %
% %
-% Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
% obtain a copy of the License at %
% %
-% http://www.imagemagick.org/script/license.php %
+% https://www.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, %
#include "MagickCore/artifact.h"
#include "MagickCore/blob.h"
#include "MagickCore/cache.h"
+#include "MagickCore/cache-private.h"
#include "MagickCore/cache-view.h"
#include "MagickCore/channel.h"
#include "MagickCore/color.h"
#include "MagickCore/string-private.h"
#include "MagickCore/thread-private.h"
#include "MagickCore/token.h"
-#include "MagickCore/transform.h"
+#include "MagickCore/transform-private.h"
#include "MagickCore/utility.h"
\f
/*
Define declarations.
*/
#define BezierQuantum 200
+#define DrawEpsilon (1.0e-10)
+
\f
/*
Typedef declarations.
if (draw_info == (DrawInfo *) NULL)
return(clone_info);
exception=AcquireExceptionInfo();
- (void) CloneString(&clone_info->primitive,draw_info->primitive);
- (void) CloneString(&clone_info->geometry,draw_info->geometry);
+ if (clone_info->primitive != (char *) NULL)
+ (void) CloneString(&clone_info->primitive,draw_info->primitive);
+ if (draw_info->geometry != (char *) NULL)
+ (void) CloneString(&clone_info->geometry,draw_info->geometry);
clone_info->viewbox=draw_info->viewbox;
clone_info->affine=draw_info->affine;
clone_info->gravity=draw_info->gravity;
clone_info->dash_offset=draw_info->dash_offset;
clone_info->decorate=draw_info->decorate;
clone_info->compose=draw_info->compose;
- (void) CloneString(&clone_info->text,draw_info->text);
- (void) CloneString(&clone_info->font,draw_info->font);
- (void) CloneString(&clone_info->metrics,draw_info->metrics);
- (void) CloneString(&clone_info->family,draw_info->family);
+ if (draw_info->text != (char *) NULL)
+ (void) CloneString(&clone_info->text,draw_info->text);
+ if (draw_info->font != (char *) NULL)
+ (void) CloneString(&clone_info->font,draw_info->font);
+ if (draw_info->metrics != (char *) NULL)
+ (void) CloneString(&clone_info->metrics,draw_info->metrics);
+ if (draw_info->family != (char *) NULL)
+ (void) CloneString(&clone_info->family,draw_info->family);
clone_info->style=draw_info->style;
clone_info->stretch=draw_info->stretch;
clone_info->weight=draw_info->weight;
- (void) CloneString(&clone_info->encoding,draw_info->encoding);
+ if (draw_info->encoding != (char *) NULL)
+ (void) CloneString(&clone_info->encoding,draw_info->encoding);
clone_info->pointsize=draw_info->pointsize;
clone_info->kerning=draw_info->kerning;
clone_info->interline_spacing=draw_info->interline_spacing;
clone_info->interword_spacing=draw_info->interword_spacing;
clone_info->direction=draw_info->direction;
- (void) CloneString(&clone_info->density,draw_info->density);
+ if (draw_info->density != (char *) NULL)
+ (void) CloneString(&clone_info->density,draw_info->density);
clone_info->align=draw_info->align;
clone_info->undercolor=draw_info->undercolor;
clone_info->border_color=draw_info->border_color;
- (void) CloneString(&clone_info->server_name,draw_info->server_name);
+ if (draw_info->server_name != (char *) NULL)
+ (void) CloneString(&clone_info->server_name,draw_info->server_name);
if (draw_info->dash_pattern != (double *) NULL)
{
register ssize_t
x;
- for (x=0; draw_info->dash_pattern[x] != 0.0; x++) ;
+ for (x=0; fabs(draw_info->dash_pattern[x]) >= DrawEpsilon; x++) ;
clone_info->dash_pattern=(double *) AcquireQuantumMemory((size_t) x+1UL,
sizeof(*clone_info->dash_pattern));
if (clone_info->dash_pattern == (double *) NULL)
draw_info->gradient.stops,(size_t) number_stops*
sizeof(*clone_info->gradient.stops));
}
- (void) CloneString(&clone_info->clip_mask,draw_info->clip_mask);
+ if (draw_info->clip_mask != (char *) NULL)
+ (void) CloneString(&clone_info->clip_mask,draw_info->clip_mask);
clone_info->bounds=draw_info->bounds;
clone_info->clip_units=draw_info->clip_units;
clone_info->render=draw_info->render;
- clone_info->alpha=draw_info->alpha;
+ clone_info->fill_alpha=draw_info->fill_alpha;
+ clone_info->stroke_alpha=draw_info->stroke_alpha;
clone_info->element_reference=draw_info->element_reference;
clone_info->debug=IsEventLogging();
exception=DestroyExceptionInfo(exception);
*/
p=(const EdgeInfo *) x;
q=(const EdgeInfo *) y;
- if ((p->points[0].y-MagickEpsilon) > q->points[0].y)
+ if ((p->points[0].y-DrawEpsilon) > q->points[0].y)
return(1);
- if ((p->points[0].y+MagickEpsilon) < q->points[0].y)
+ if ((p->points[0].y+DrawEpsilon) < q->points[0].y)
return(-1);
- if ((p->points[0].x-MagickEpsilon) > q->points[0].x)
+ if ((p->points[0].x-DrawEpsilon) > q->points[0].x)
return(1);
- if ((p->points[0].x+MagickEpsilon) < q->points[0].x)
+ if ((p->points[0].x+DrawEpsilon) < q->points[0].x)
return(-1);
if (((p->points[1].x-p->points[0].x)*(q->points[1].y-q->points[0].y)-
(p->points[1].y-p->points[0].y)*(q->points[1].x-q->points[0].x)) > 0.0)
(void) LogMagickEvent(DrawEvent,GetMagickModule()," ghostline: %s",
p->ghostline != MagickFalse ? "transparent" : "opaque");
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
- " bounds: %g %g - %g %g",p->bounds.x1,p->bounds.y1,
+ " bounds: %g,%g - %g,%g",p->bounds.x1,p->bounds.y1,
p->bounds.x2,p->bounds.y2);
for (j=0; j < (ssize_t) p->number_points; j++)
- (void) LogMagickEvent(DrawEvent,GetMagickModule()," %g %g",
+ (void) LogMagickEvent(DrawEvent,GetMagickModule()," %g,%g",
p->points[j].x,p->points[j].y);
p++;
}
}
}
-static PolygonInfo *ConvertPathToPolygon(
- const DrawInfo *magick_unused(draw_info),const PathInfo *path_info)
+static PolygonInfo *ConvertPathToPolygon(const PathInfo *path_info)
{
long
direction,
if (polygon_info == (PolygonInfo *) NULL)
return((PolygonInfo *) NULL);
number_edges=16;
- polygon_info->edges=(EdgeInfo *) AcquireQuantumMemory((size_t) number_edges,
+ polygon_info->edges=(EdgeInfo *) AcquireQuantumMemory(number_edges,
sizeof(*polygon_info->edges));
if (polygon_info->edges == (EdgeInfo *) NULL)
return((PolygonInfo *) NULL);
+ (void) ResetMagickMemory(polygon_info->edges,0,number_edges*
+ sizeof(*polygon_info->edges));
direction=0;
edge=0;
ghostline=MagickFalse;
Line to.
*/
next_direction=((path_info[i].point.y > point.y) ||
- ((path_info[i].point.y == point.y) &&
+ ((fabs(path_info[i].point.y-point.y) < DrawEpsilon) &&
(path_info[i].point.x > point.x))) ? 1 : -1;
if ((points != (PointInfo *) NULL) && (direction != 0) &&
(direction != next_direction))
(void) LogMagickEvent(DrawEvent,GetMagickModule()," begin vector-path");
for (p=path_info; p->code != EndCode; p++)
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
- " %g %g %s",p->point.x,p->point.y,p->code == GhostlineCode ?
+ " %g,%g %s",p->point.x,p->point.y,p->code == GhostlineCode ?
"moveto ghostline" : p->code == OpenCode ? "moveto open" :
p->code == MoveToCode ? "moveto" : p->code == LineToCode ? "lineto" :
"?");
(void) LogMagickEvent(DrawEvent,GetMagickModule()," end vector-path");
}
-static PathInfo *ConvertPrimitiveToPath(
- const DrawInfo *magick_unused(draw_info),const PrimitiveInfo *primitive_info)
+static PathInfo *ConvertPrimitiveToPath(const PrimitiveInfo *primitive_info)
{
PathInfo
*path_info;
*/
switch (primitive_info->primitive)
{
- case PointPrimitive:
+ case AlphaPrimitive:
case ColorPrimitive:
- case MattePrimitive:
- case TextPrimitive:
case ImagePrimitive:
+ case PointPrimitive:
+ case TextPrimitive:
return((PathInfo *) NULL);
default:
break;
/*
Eliminate duplicate points.
*/
- if ((i == 0) || (fabs(q.x-primitive_info[i].point.x) >= MagickEpsilon) ||
- (fabs(q.y-primitive_info[i].point.y) >= MagickEpsilon))
+ if ((i == 0) || (fabs(q.x-primitive_info[i].point.x) >= DrawEpsilon) ||
+ (fabs(q.y-primitive_info[i].point.y) >= DrawEpsilon))
{
path_info[n].code=code;
path_info[n].point=primitive_info[i].point;
}
if (coordinates > 0)
continue;
- if ((fabs(p.x-primitive_info[i].point.x) < MagickEpsilon) &&
- (fabs(p.y-primitive_info[i].point.y) < MagickEpsilon))
+ if ((fabs(p.x-primitive_info[i].point.x) < DrawEpsilon) &&
+ (fabs(p.y-primitive_info[i].point.y) < DrawEpsilon))
continue;
/*
Mark the p point as open if it does not match the q.
if (draw_info->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(draw_info != (DrawInfo *) NULL);
- assert(draw_info->signature == MagickSignature);
+ assert(draw_info->signature == MagickCoreSignature);
if (draw_info->primitive != (char *) NULL)
draw_info->primitive=DestroyString(draw_info->primitive);
if (draw_info->text != (char *) NULL)
draw_info->gradient.stops);
if (draw_info->clip_mask != (char *) NULL)
draw_info->clip_mask=DestroyString(draw_info->clip_mask);
- draw_info->signature=(~MagickSignature);
+ draw_info->signature=(~MagickCoreSignature);
draw_info=(DrawInfo *) RelinquishMagickMemory(draw_info);
return(draw_info);
}
inverse_edge.x2=edge->x2;
inverse_edge.y2=edge->y2;
z=affine->ry*y+affine->tx;
- if (affine->sx >= MagickEpsilon)
+ if (affine->sx >= DrawEpsilon)
{
intercept=(-z/affine->sx);
x=intercept;
inverse_edge.x2=x;
}
else
- if (affine->sx < -MagickEpsilon)
+ if (affine->sx < -DrawEpsilon)
{
intercept=(-z+(double) image->columns)/affine->sx;
x=intercept;
Determine top and bottom edges.
*/
z=affine->sy*y+affine->ty;
- if (affine->rx >= MagickEpsilon)
+ if (affine->rx >= DrawEpsilon)
{
intercept=(-z/affine->rx);
x=intercept;
inverse_edge.x2=x;
}
else
- if (affine->rx < -MagickEpsilon)
+ if (affine->rx < -DrawEpsilon)
{
intercept=(-z+(double) image->rows)/affine->rx;
x=intercept;
return(inverse_affine);
}
-static inline ssize_t MagickAbsoluteValue(const ssize_t x)
-{
- if (x < 0)
- return(-x);
- return(x);
-}
-
-static inline double MagickMax(const double x,const double y)
-{
- if (x > y)
- return(x);
- return(y);
-}
-
-static inline double MagickMin(const double x,const double y)
-{
- if (x < y)
- return(x);
- return(y);
-}
-
MagickExport MagickBooleanType DrawAffineImage(Image *image,
const Image *source,const AffineMatrix *affine,ExceptionInfo *exception)
{
PointInfo
extent[4],
min,
- max,
- point;
+ max;
register ssize_t
i;
Determine bounding box.
*/
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(source != (const Image *) NULL);
- assert(source->signature == MagickSignature);
+ assert(source->signature == MagickCoreSignature);
assert(affine != (AffineMatrix *) NULL);
extent[0].x=0.0;
extent[0].y=0.0;
extent[3].y=(double) source->rows-1.0;
for (i=0; i < 4; i++)
{
+ PointInfo
+ point;
+
point=extent[i];
extent[i].x=point.x*affine->sx+point.y*affine->ry+affine->tx;
extent[i].y=point.x*affine->rx+point.y*affine->sy+affine->ty;
x;
register Quantum
- *restrict q;
+ *magick_restrict q;
SegmentInfo
inverse_edge;
GetPixelInfoPixel(image,q,&composite);
CompositePixelInfoOver(&pixel,pixel.alpha,&composite,composite.alpha,
&composite);
- SetPixelInfoPixel(image,&composite,q);
+ SetPixelViaPixelInfo(image,&composite,q);
x_offset++;
q+=GetPixelChannels(image);
}
coordinates;
clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
- (void) QueryColorCompliance("#0000",AllCompliance,&clone_info->fill,
+ (void) QueryColorCompliance("#000F",AllCompliance,&clone_info->fill,
exception);
- resolution.x=DefaultResolution;
- resolution.y=DefaultResolution;
+ resolution.x=96.0;
+ resolution.y=96.0;
if (clone_info->density != (char *) NULL)
{
GeometryInfo
if ((flags & SigmaValue) == MagickFalse)
resolution.y=resolution.x;
}
- mid=(resolution.x/72.0)*ExpandAffine(&clone_info->affine)*
+ mid=(resolution.x/96.0)*ExpandAffine(&clone_info->affine)*
clone_info->stroke_width/2.0;
bounds.x1=0.0;
bounds.y1=0.0;
const DrawInfo *draw_info,const char *name,ExceptionInfo *exception)
{
char
- filename[MaxTextExtent];
+ filename[MagickPathExtent];
Image
*clip_mask;
status;
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(draw_info != (const DrawInfo *) NULL);
- (void) FormatLocaleString(filename,MaxTextExtent,"%s",name);
+ (void) FormatLocaleString(filename,MagickPathExtent,"%s",name);
value=GetImageArtifact(image,filename);
if (value == (const char *) NULL)
return(MagickFalse);
return(MagickFalse);
(void) QueryColorCompliance("#0000",AllCompliance,
&clip_mask->background_color,exception);
- clip_mask->background_color.alpha=(Quantum) TransparentAlpha;
+ clip_mask->background_color.alpha=(MagickRealType) TransparentAlpha;
(void) SetImageBackgroundColor(clip_mask,exception);
if (image->debug != MagickFalse)
(void) LogMagickEvent(DrawEvent,GetMagickModule(),"\nbegin clip-path %s",
exception);
clone_info->clip_mask=(char *) NULL;
status=NegateImage(clip_mask,MagickFalse,exception);
- (void) SetImageMask(image,clip_mask,exception);
+ (void) SetImageMask(image,ReadPixelMask,clip_mask,exception);
clip_mask=DestroyImage(clip_mask);
status&=DrawImage(image,clone_info,exception);
clone_info=DestroyDrawInfo(clone_info);
assert(draw_info != (const DrawInfo *) NULL);
if (image->debug != MagickFalse)
(void) LogMagickEvent(DrawEvent,GetMagickModule()," begin draw-dash");
- clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
- clone_info->miterlimit=0;
for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++) ;
number_vertices=(size_t) i;
dash_polygon=(PrimitiveInfo *) AcquireQuantumMemory((size_t)
(2UL*number_vertices+1UL),sizeof(*dash_polygon));
if (dash_polygon == (PrimitiveInfo *) NULL)
return(MagickFalse);
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ clone_info->miterlimit=0;
dash_polygon[0]=primitive_info[0];
scale=ExpandAffine(&draw_info->affine);
length=scale*(draw_info->dash_pattern[0]-0.5);
- offset=draw_info->dash_offset != 0.0 ? scale*draw_info->dash_offset : 0.0;
+ offset=fabs(draw_info->dash_offset) >= DrawEpsilon ?
+ scale*draw_info->dash_offset : 0.0;
j=1;
for (n=0; offset > 0.0; j=0)
{
status=MagickTrue;
maximum_length=0.0;
total_length=0.0;
- for (i=1; i < (ssize_t) number_vertices; i++)
+ for (i=1; (i < (ssize_t) number_vertices) && (length >= 0.0); i++)
{
dx=primitive_info[i].point.x-primitive_info[i-1].point.x;
dy=primitive_info[i].point.y-primitive_info[i-1].point.y;
maximum_length=hypot((double) dx,dy);
- if (length == 0.0)
+ if (fabs(length) < DrawEpsilon)
{
n++;
- if (draw_info->dash_pattern[n] == 0.0)
+ if (fabs(draw_info->dash_pattern[n]) < DrawEpsilon)
n=0;
length=scale*(draw_info->dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
}
- for (total_length=0.0; (total_length+length) <= maximum_length; )
+ for (total_length=0.0; (length >= 0.0) && (maximum_length >= (total_length+length)); )
{
total_length+=length;
if ((n & 0x01) != 0)
status&=DrawStrokePolygon(image,clone_info,dash_polygon,exception);
}
n++;
- if (draw_info->dash_pattern[n] == 0.0)
+ if (fabs(draw_info->dash_pattern[n]) < DrawEpsilon)
n=0;
length=scale*(draw_info->dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
}
if ((total_length <= maximum_length) && ((n & 0x01) == 0) && (j > 1))
{
dash_polygon[j]=primitive_info[i-1];
- dash_polygon[j].point.x+=MagickEpsilon;
- dash_polygon[j].point.y+=MagickEpsilon;
+ dash_polygon[j].point.x+=DrawEpsilon;
+ dash_polygon[j].point.y+=DrawEpsilon;
dash_polygon[j].coordinates=1;
j++;
dash_polygon[0].coordinates=(size_t) j;
value;
value=StringToDouble(point,&p);
- return((value == 0.0) && (p == point) ? MagickFalse : MagickTrue);
+ return((fabs(value) < DrawEpsilon) && (p == point) ? MagickFalse : MagickTrue);
}
static inline void TracePoint(PrimitiveInfo *primitive_info,
current;
char
- key[2*MaxTextExtent],
- keyword[MaxTextExtent],
- geometry[MaxTextExtent],
- name[MaxTextExtent],
- pattern[MaxTextExtent],
+ keyword[MagickPathExtent],
+ geometry[MagickPathExtent],
+ *next_token,
+ pattern[MagickPathExtent],
*primitive,
*token;
const char
*q;
+ double
+ angle,
+ factor,
+ points_extent,
+ primitive_extent;
+
DrawInfo
**graphic_context;
MagickBooleanType
proceed;
+ MagickSizeType
+ number_points;
+
MagickStatusType
status;
- double
- angle,
- factor,
- primitive_extent;
-
PointInfo
point;
- PixelInfo
- start_color;
-
PrimitiveInfo
*primitive_info;
bounds;
size_t
- length,
- number_points;
+ extent,
+ number_stops;
ssize_t
j,
k,
n;
- /*
- Ensure the annotation info is valid.
- */
+ StopInfo
+ *stops;
+
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(draw_info != (DrawInfo *) NULL);
- assert(draw_info->signature == MagickSignature);
+ assert(draw_info->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
if ((draw_info->primitive == (char *) NULL) ||
primitive_extent=(double) strlen(primitive);
(void) SetImageArtifact(image,"MVG",primitive);
n=0;
+ number_stops=0;
+ stops=(StopInfo *) NULL;
/*
Allocate primitive info memory.
*/
- graphic_context=(DrawInfo **) AcquireMagickMemory(
- sizeof(*graphic_context));
+ graphic_context=(DrawInfo **) AcquireMagickMemory(sizeof(*graphic_context));
if (graphic_context == (DrawInfo **) NULL)
{
primitive=DestroyString(primitive);
graphic_context[n]->viewbox.height=image->rows;
}
token=AcquireString(primitive);
- (void) QueryColorCompliance("#000000",AllCompliance,&start_color,
- exception);
+ extent=strlen(token)+MagickPathExtent;
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
status=MagickTrue;
/*
Interpret graphic primitive.
*/
- GetMagickToken(q,&q,keyword);
+ GetNextToken(q,&q,MagickPathExtent,keyword);
if (*keyword == '\0')
break;
if (*keyword == '#')
{
if (LocaleCompare("affine",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- affine.sx=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ affine.sx=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- affine.rx=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ affine.rx=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- affine.ry=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ affine.ry=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- affine.sy=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ affine.sy=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- affine.tx=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ affine.tx=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- affine.ty=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ affine.ty=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ break;
+ }
+ if (LocaleCompare("alpha",keyword) == 0)
+ {
+ primitive_type=AlphaPrimitive;
break;
}
if (LocaleCompare("arc",keyword) == 0)
}
if (LocaleCompare("border-color",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
(void) QueryColorCompliance(token,AllCompliance,
&graphic_context[n]->border_color,exception);
break;
/*
Create clip mask.
*/
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
(void) CloneString(&graphic_context[n]->clip_mask,token);
(void) DrawClipPath(image,graphic_context[n],
graphic_context[n]->clip_mask,exception);
ssize_t
fill_rule;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
fill_rule=ParseCommandOption(MagickFillRuleOptions,MagickFalse,
token);
if (fill_rule == -1)
ssize_t
clip_units;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
clip_units=ParseCommandOption(MagickClipPathOptions,MagickFalse,
token);
if (clip_units == -1)
ssize_t
decorate;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
decorate=ParseCommandOption(MagickDecorateOptions,MagickFalse,
token);
if (decorate == -1)
graphic_context[n]->decorate=(DecorationType) decorate;
break;
}
+ if (LocaleCompare("density",keyword) == 0)
+ {
+ GetNextToken(q,&q,extent,token);
+ (void) CloneString(&graphic_context[n]->density,token);
+ break;
+ }
if (LocaleCompare("direction",keyword) == 0)
{
ssize_t
direction;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
direction=ParseCommandOption(MagickDirectionOptions,MagickFalse,
token);
if (direction == -1)
}
if (LocaleCompare("encoding",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
(void) CloneString(&graphic_context[n]->encoding,token);
break;
}
{
if (LocaleCompare("fill",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- (void) FormatLocaleString(pattern,MaxTextExtent,"%s",token);
+ GetNextToken(q,&q,extent,token);
+ (void) FormatLocaleString(pattern,MagickPathExtent,"%s",token);
if (GetImageArtifact(image,pattern) != (const char *) NULL)
(void) DrawPatternPath(image,draw_info,token,
&graphic_context[n]->fill_pattern,exception);
{
status&=QueryColorCompliance(token,AllCompliance,
&graphic_context[n]->fill,exception);
+ if (graphic_context[n]->fill_alpha != OpaqueAlpha)
+ graphic_context[n]->fill.alpha=graphic_context[n]->fill_alpha;
if (status == MagickFalse)
{
ImageInfo
pattern_info=AcquireImageInfo();
(void) CopyMagickString(pattern_info->filename,token,
- MaxTextExtent);
+ MagickPathExtent);
graphic_context[n]->fill_pattern=ReadImage(pattern_info,
exception);
CatchException(exception);
}
break;
}
- if (LocaleCompare("fill-alpha",keyword) == 0)
+ if (LocaleCompare("fill-opacity",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
- graphic_context[n]->fill.alpha=(double) QuantumRange*
- factor*StringToDouble(token,(char **) NULL);
+ graphic_context[n]->fill.alpha=(MagickRealType) (QuantumRange-
+ ClampToQuantum((MagickRealType) QuantumRange*(1.0-factor*
+ StringToDouble(token,&next_token))));
+ if (token == next_token)
+ status=MagickFalse;
break;
}
if (LocaleCompare("fill-rule",keyword) == 0)
ssize_t
fill_rule;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
fill_rule=ParseCommandOption(MagickFillRuleOptions,MagickFalse,
token);
if (fill_rule == -1)
}
if (LocaleCompare("font",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
(void) CloneString(&graphic_context[n]->font,token);
if (LocaleCompare("none",token) == 0)
- graphic_context[n]->font=(char *)
- RelinquishMagickMemory(graphic_context[n]->font);
+ graphic_context[n]->font=(char *) RelinquishMagickMemory(
+ graphic_context[n]->font);
break;
}
if (LocaleCompare("font-family",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
(void) CloneString(&graphic_context[n]->family,token);
break;
}
if (LocaleCompare("font-size",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- graphic_context[n]->pointsize=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ graphic_context[n]->pointsize=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
if (LocaleCompare("font-stretch",keyword) == 0)
ssize_t
stretch;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
stretch=ParseCommandOption(MagickStretchOptions,MagickFalse,token);
if (stretch == -1)
status=MagickFalse;
ssize_t
style;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
style=ParseCommandOption(MagickStyleOptions,MagickFalse,token);
if (style == -1)
status=MagickFalse;
}
if (LocaleCompare("font-weight",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- graphic_context[n]->weight=StringToUnsignedLong(token);
- if (LocaleCompare(token,"all") == 0)
- graphic_context[n]->weight=0;
- if (LocaleCompare(token,"bold") == 0)
- graphic_context[n]->weight=700;
- if (LocaleCompare(token,"bolder") == 0)
- if (graphic_context[n]->weight <= 800)
- graphic_context[n]->weight+=100;
- if (LocaleCompare(token,"lighter") == 0)
- if (graphic_context[n]->weight >= 100)
- graphic_context[n]->weight-=100;
- if (LocaleCompare(token,"normal") == 0)
- graphic_context[n]->weight=400;
+ ssize_t
+ weight;
+
+ GetNextToken(q,&q,extent,token);
+ weight=ParseCommandOption(MagickWeightOptions,MagickFalse,token);
+ if (weight == -1)
+ weight=(ssize_t) StringToUnsignedLong(token);
+ graphic_context[n]->weight=(size_t) weight;
break;
}
status=MagickFalse;
{
if (LocaleCompare("gradient-units",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
break;
}
if (LocaleCompare("gravity",keyword) == 0)
ssize_t
gravity;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,token);
if (gravity == -1)
status=MagickFalse;
compose;
primitive_type=ImagePrimitive;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
compose=ParseCommandOption(MagickComposeOptions,MagickFalse,token);
if (compose == -1)
status=MagickFalse;
}
if (LocaleCompare("interline-spacing",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->interline_spacing=StringToDouble(token,
- (char **) NULL);
+ &next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
if (LocaleCompare("interword-spacing",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->interword_spacing=StringToDouble(token,
- (char **) NULL);
+ &next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
status=MagickFalse;
{
if (LocaleCompare("kerning",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- graphic_context[n]->kerning=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ graphic_context[n]->kerning=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
status=MagickFalse;
status=MagickFalse;
break;
}
- case 'm':
- case 'M':
- {
- if (LocaleCompare("matte",keyword) == 0)
- primitive_type=MattePrimitive;
- else
- status=MagickFalse;
- break;
- }
case 'o':
case 'O':
{
if (LocaleCompare("offset",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
break;
}
if (LocaleCompare("opacity",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
- graphic_context[n]->alpha=ClampToQuantum(QuantumRange*(1.0-((1.0-
- QuantumScale*graphic_context[n]->alpha)*factor*
- StringToDouble(token,(char **) NULL))));
- graphic_context[n]->fill.alpha=(double) graphic_context[n]->alpha;
- graphic_context[n]->stroke.alpha=(double) graphic_context[n]->alpha;
+ graphic_context[n]->alpha=(Quantum) (QuantumRange*(1.0-
+ (QuantumScale*graphic_context[n]->alpha*(1.0-factor*
+ StringToDouble(token,&next_token)))));
+ graphic_context[n]->fill_alpha=QuantumRange*(1.0-(QuantumScale*
+ graphic_context[n]->fill_alpha*(1.0-factor*StringToDouble(token,
+ &next_token))));
+ graphic_context[n]->stroke_alpha=QuantumRange*(1.0-(QuantumScale*
+ graphic_context[n]->stroke_alpha*(1.0-factor*StringToDouble(token,
+ &next_token))));
+ if (token == next_token)
+ status=MagickFalse;
break;
}
status=MagickFalse;
}
if (LocaleCompare("pop",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
if (LocaleCompare("clip-path",token) == 0)
break;
if (LocaleCompare("defs",token) == 0)
{
(void) ThrowMagickException(exception,GetMagickModule(),
DrawError,"UnbalancedGraphicContextPushPop","`%s'",token);
+ status=MagickFalse;
n=0;
break;
}
if (graphic_context[n]->clip_mask != (char *) NULL)
if (LocaleCompare(graphic_context[n]->clip_mask,
graphic_context[n-1]->clip_mask) != 0)
- (void) SetImageMask(image,(Image *) NULL,exception);
+ (void) SetImageMask(image,ReadPixelMask,(Image *) NULL,
+ exception);
graphic_context[n]=DestroyDrawInfo(graphic_context[n]);
n--;
break;
}
if (LocaleCompare("push",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
if (LocaleCompare("clip-path",token) == 0)
{
char
- name[MaxTextExtent];
+ name[MagickPathExtent];
- GetMagickToken(q,&q,token);
- (void) FormatLocaleString(name,MaxTextExtent,"%s",token);
+ GetNextToken(q,&q,extent,token);
+ (void) FormatLocaleString(name,MagickPathExtent,"%s",token);
for (p=q; *q != '\0'; )
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
if (LocaleCompare(token,"pop") != 0)
continue;
- GetMagickToken(q,(const char **) NULL,token);
+ GetNextToken(q,(const char **) NULL,extent,token);
if (LocaleCompare(token,"clip-path") != 0)
continue;
break;
}
(void) CopyMagickString(token,p,(size_t) (q-p-4+1));
(void) SetImageArtifact(image,name,token);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
break;
}
if (LocaleCompare("gradient",token) == 0)
{
char
- key[2*MaxTextExtent],
- name[MaxTextExtent],
- type[MaxTextExtent];
+ key[2*MagickPathExtent],
+ name[MagickPathExtent],
+ type[MagickPathExtent];
SegmentInfo
segment;
- GetMagickToken(q,&q,token);
- (void) CopyMagickString(name,token,MaxTextExtent);
- GetMagickToken(q,&q,token);
- (void) CopyMagickString(type,token,MaxTextExtent);
- GetMagickToken(q,&q,token);
- segment.x1=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ (void) CopyMagickString(name,token,MagickPathExtent);
+ GetNextToken(q,&q,extent,token);
+ (void) CopyMagickString(type,token,MagickPathExtent);
+ GetNextToken(q,&q,extent,token);
+ segment.x1=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- segment.y1=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ segment.y1=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- segment.x2=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ segment.x2=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- segment.y2=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ segment.y2=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
if (LocaleCompare(type,"radial") == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
}
for (p=q; *q != '\0'; )
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
if (LocaleCompare(token,"pop") != 0)
continue;
- GetMagickToken(q,(const char **) NULL,token);
+ GetNextToken(q,(const char **) NULL,extent,token);
if (LocaleCompare(token,"gradient") != 0)
continue;
break;
bounds.y2=graphic_context[n]->affine.rx*segment.x2+
graphic_context[n]->affine.sy*segment.y2+
graphic_context[n]->affine.ty;
- (void) FormatLocaleString(key,MaxTextExtent,"%s",name);
+ (void) FormatLocaleString(key,MagickPathExtent,"%s",name);
(void) SetImageArtifact(image,key,token);
- (void) FormatLocaleString(key,MaxTextExtent,"%s-geometry",name);
- (void) FormatLocaleString(geometry,MaxTextExtent,
+ (void) FormatLocaleString(key,MagickPathExtent,"%s-type",name);
+ (void) SetImageArtifact(image,key,type);
+ (void) FormatLocaleString(key,MagickPathExtent,"%s-geometry",
+ name);
+ (void) FormatLocaleString(geometry,MagickPathExtent,
"%gx%g%+.15g%+.15g",
MagickMax(fabs(bounds.x2-bounds.x1+1.0),1.0),
MagickMax(fabs(bounds.y2-bounds.y1+1.0),1.0),
bounds.x1,bounds.y1);
(void) SetImageArtifact(image,key,geometry);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
break;
}
if (LocaleCompare("pattern",token) == 0)
{
+ char
+ key[2*MagickPathExtent],
+ name[MagickPathExtent];
+
RectangleInfo
- bounds;
-
- GetMagickToken(q,&q,token);
- (void) CopyMagickString(name,token,MaxTextExtent);
- GetMagickToken(q,&q,token);
- bounds.x=(ssize_t) ceil(StringToDouble(token,(char **) NULL)-
- 0.5);
- GetMagickToken(q,&q,token);
+ pattern_bounds;
+
+ GetNextToken(q,&q,extent,token);
+ (void) CopyMagickString(name,token,MagickPathExtent);
+ GetNextToken(q,&q,extent,token);
+ pattern_bounds.x=(ssize_t) ceil(StringToDouble(token,
+ &next_token)-0.5);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- bounds.y=(ssize_t) ceil(StringToDouble(token,(char **) NULL)-
- 0.5);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ pattern_bounds.y=(ssize_t) ceil(StringToDouble(token,
+ &next_token)-0.5);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- bounds.width=(size_t) floor(StringToDouble(token,
- (char **) NULL)+0.5);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ pattern_bounds.width=(size_t) floor(StringToDouble(token,
+ &next_token)+0.5);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- bounds.height=(size_t) floor(StringToDouble(token,
- (char **) NULL)+0.5);
+ GetNextToken(q,&q,extent,token);
+ pattern_bounds.height=(size_t) floor(StringToDouble(token,
+ &next_token)+0.5);
+ if (token == next_token)
+ status=MagickFalse;
for (p=q; *q != '\0'; )
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
if (LocaleCompare(token,"pop") != 0)
continue;
- GetMagickToken(q,(const char **) NULL,token);
+ GetNextToken(q,(const char **) NULL,extent,token);
if (LocaleCompare(token,"pattern") != 0)
continue;
break;
}
(void) CopyMagickString(token,p,(size_t) (q-p-4+1));
- (void) FormatLocaleString(key,MaxTextExtent,"%s",name);
+ (void) FormatLocaleString(key,MagickPathExtent,"%s",name);
(void) SetImageArtifact(image,key,token);
- (void) FormatLocaleString(key,MaxTextExtent,"%s-geometry",name);
- (void) FormatLocaleString(geometry,MaxTextExtent,
- "%.20gx%.20g%+.20g%+.20g",(double) bounds.width,(double)
- bounds.height,(double) bounds.x,(double) bounds.y);
+ (void) FormatLocaleString(key,MagickPathExtent,"%s-geometry",
+ name);
+ (void) FormatLocaleString(geometry,MagickPathExtent,
+ "%.20gx%.20g%+.20g%+.20g",(double)pattern_bounds.width,
+ (double)pattern_bounds.height,(double)pattern_bounds.x,
+ (double)pattern_bounds.y);
(void) SetImageArtifact(image,key,geometry);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
break;
}
if (LocaleCompare("graphic-context",token) == 0)
}
if (LocaleCompare("rotate",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- angle=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ angle=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
affine.sx=cos(DegreesToRadians(fmod((double) angle,360.0)));
affine.rx=sin(DegreesToRadians(fmod((double) angle,360.0)));
affine.ry=(-sin(DegreesToRadians(fmod((double) angle,360.0))));
{
if (LocaleCompare("scale",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- affine.sx=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ affine.sx=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- affine.sy=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ affine.sy=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
if (LocaleCompare("skewX",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- angle=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ angle=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
affine.ry=sin(DegreesToRadians(angle));
break;
}
if (LocaleCompare("skewY",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- angle=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ angle=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
affine.rx=(-tan(DegreesToRadians(angle)/2.0));
break;
}
PixelInfo
stop_color;
- GetMagickToken(q,&q,token);
+ number_stops++;
+ if (number_stops == 1)
+ stops=(StopInfo *) AcquireQuantumMemory(2,sizeof(*stops));
+ else if (number_stops > 2)
+ stops=(StopInfo *) ResizeQuantumMemory(stops,number_stops,
+ sizeof(*stops));
+ if (stops == (StopInfo *) NULL)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ResourceLimitError,"MemoryAllocationFailed","`%s'",
+ image->filename);
+ break;
+ }
+ GetNextToken(q,&q,extent,token);
(void) QueryColorCompliance(token,AllCompliance,&stop_color,
exception);
- (void) GradientImage(image,LinearGradient,ReflectSpread,
- &start_color,&stop_color,exception);
- start_color=stop_color;
- GetMagickToken(q,&q,token);
+ stops[number_stops-1].color=stop_color;
+ GetNextToken(q,&q,extent,token);
+ stops[number_stops-1].offset=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
if (LocaleCompare("stroke",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- (void) FormatLocaleString(pattern,MaxTextExtent,"%s",token);
+ GetNextToken(q,&q,extent,token);
+ (void) FormatLocaleString(pattern,MagickPathExtent,"%s",token);
if (GetImageArtifact(image,pattern) != (const char *) NULL)
(void) DrawPatternPath(image,draw_info,token,
&graphic_context[n]->stroke_pattern,exception);
{
status&=QueryColorCompliance(token,AllCompliance,
&graphic_context[n]->stroke,exception);
+ if (graphic_context[n]->stroke_alpha != OpaqueAlpha)
+ graphic_context[n]->stroke.alpha=
+ graphic_context[n]->stroke_alpha;
if (status == MagickFalse)
{
ImageInfo
pattern_info=AcquireImageInfo();
(void) CopyMagickString(pattern_info->filename,token,
- MaxTextExtent);
+ MagickPathExtent);
graphic_context[n]->stroke_pattern=ReadImage(pattern_info,
exception);
CatchException(exception);
}
if (LocaleCompare("stroke-antialias",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->stroke_antialias=
StringToLong(token) != 0 ? MagickTrue : MagickFalse;
break;
if (IsPoint(q) != MagickFalse)
{
const char
- *p;
+ *r;
- p=q;
- GetMagickToken(p,&p,token);
+ r=q;
+ GetNextToken(r,&r,extent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
+ GetNextToken(r,&r,extent,token);
for (x=0; IsPoint(token) != MagickFalse; x++)
{
- GetMagickToken(p,&p,token);
+ GetNextToken(r,&r,extent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
+ GetNextToken(r,&r,extent,token);
}
graphic_context[n]->dash_pattern=(double *)
AcquireQuantumMemory((size_t) (2UL*x+1UL),
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
image->filename);
+ status=MagickFalse;
break;
}
for (j=0; j < x; j++)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->dash_pattern[j]=StringToDouble(token,
- (char **) NULL);
+ &next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ if (graphic_context[n]->dash_pattern[j] < 0.0)
+ status=MagickFalse;
}
if ((x & 0x01) != 0)
for ( ; j < (2*x); j++)
graphic_context[n]->dash_pattern[j]=0.0;
break;
}
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
break;
}
if (LocaleCompare("stroke-dashoffset",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->dash_offset=StringToDouble(token,
- (char **) NULL);
+ &next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
if (LocaleCompare("stroke-linecap",keyword) == 0)
ssize_t
linecap;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
linecap=ParseCommandOption(MagickLineCapOptions,MagickFalse,token);
if (linecap == -1)
status=MagickFalse;
ssize_t
linejoin;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
linejoin=ParseCommandOption(MagickLineJoinOptions,MagickFalse,
token);
if (linejoin == -1)
}
if (LocaleCompare("stroke-miterlimit",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->miterlimit=StringToUnsignedLong(token);
break;
}
if (LocaleCompare("stroke-opacity",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
- graphic_context[n]->stroke.alpha=(double) QuantumRange*
- factor*StringToDouble(token,(char **) NULL);
+ graphic_context[n]->stroke.alpha=(MagickRealType) (QuantumRange-
+ ClampToQuantum((MagickRealType) QuantumRange*(1.0-factor*
+ StringToDouble(token,&next_token))));
+ if (token == next_token)
+ status=MagickFalse;
break;
}
if (LocaleCompare("stroke-width",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- graphic_context[n]->stroke_width=StringToDouble(token,
- (char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ graphic_context[n]->stroke_width=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
status=MagickFalse;
ssize_t
align;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
align=ParseCommandOption(MagickAlignOptions,MagickFalse,token);
if (align == -1)
status=MagickFalse;
ssize_t
align;
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
align=ParseCommandOption(MagickAlignOptions,MagickFalse,token);
if (align == -1)
status=MagickFalse;
}
if (LocaleCompare("text-antialias",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- graphic_context[n]->text_antialias=
- StringToLong(token) != 0 ? MagickTrue : MagickFalse;
+ GetNextToken(q,&q,extent,token);
+ graphic_context[n]->text_antialias=StringToLong(token) != 0 ?
+ MagickTrue : MagickFalse;
break;
}
if (LocaleCompare("text-undercolor",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
(void) QueryColorCompliance(token,AllCompliance,
&graphic_context[n]->undercolor,exception);
break;
}
if (LocaleCompare("translate",keyword) == 0)
{
- GetMagickToken(q,&q,token);
- affine.tx=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ affine.tx=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- affine.ty=StringToDouble(token,(char **) NULL);
+ GetNextToken(q,&q,extent,token);
+ affine.ty=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
status=MagickFalse;
{
if (LocaleCompare("viewbox",keyword) == 0)
{
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->viewbox.x=(ssize_t) ceil(StringToDouble(token,
- (char **) NULL)-0.5);
- GetMagickToken(q,&q,token);
+ &next_token)-0.5);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->viewbox.y=(ssize_t) ceil(StringToDouble(token,
- (char **) NULL)-0.5);
- GetMagickToken(q,&q,token);
+ &next_token)-0.5);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->viewbox.width=(size_t) floor(StringToDouble(
- token,(char **) NULL)+0.5);
- GetMagickToken(q,&q,token);
+ token,&next_token)+0.5);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
graphic_context[n]->viewbox.height=(size_t) floor(StringToDouble(
- token,(char **) NULL)+0.5);
+ token,&next_token)+0.5);
+ if (token == next_token)
+ status=MagickFalse;
break;
}
status=MagickFalse;
}
if (status == MagickFalse)
break;
- if ((affine.sx != 1.0) || (affine.rx != 0.0) || (affine.ry != 0.0) ||
- (affine.sy != 1.0) || (affine.tx != 0.0) || (affine.ty != 0.0))
+ if ((fabs(affine.sx-1.0) >= DrawEpsilon) ||
+ (fabs(affine.rx) >= DrawEpsilon) || (fabs(affine.ry) >= DrawEpsilon) ||
+ (fabs(affine.sy-1.0) >= DrawEpsilon) ||
+ (fabs(affine.tx) >= DrawEpsilon) || (fabs(affine.ty) >= DrawEpsilon))
{
graphic_context[n]->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
graphic_context[n]->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
}
if (primitive_type == UndefinedPrimitive)
{
+ if (*q == '\0')
+ {
+ if (number_stops > 1)
+ {
+ GradientType
+ type;
+
+ type=LinearGradient;
+ if (draw_info->gradient.type == RadialGradient)
+ type=RadialGradient;
+ (void) GradientImage(image,type,PadSpread,stops,number_stops,
+ exception);
+ }
+ if (number_stops > 0)
+ stops=(StopInfo *) RelinquishMagickMemory(stops);
+ }
if (image->debug != MagickFalse)
- (void) LogMagickEvent(DrawEvent,GetMagickModule()," %.*s",
- (int) (q-p),p);
+ (void) LogMagickEvent(DrawEvent,GetMagickModule()," %.*s",(int)
+ (q-p),p);
continue;
}
/*
*/
if (IsPoint(q) == MagickFalse)
break;
- GetMagickToken(q,&q,token);
- point.x=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
+ point.x=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,&q,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
- point.y=StringToDouble(token,(char **) NULL);
- GetMagickToken(q,(const char **) NULL,token);
+ GetNextToken(q,&q,extent,token);
+ point.y=StringToDouble(token,&next_token);
+ if (token == next_token)
+ status=MagickFalse;
+ GetNextToken(q,(const char **) NULL,extent,token);
if (*token == ',')
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
primitive_info[i].primitive=primitive_type;
primitive_info[i].point=point;
primitive_info[i].coordinates=0;
number_points<<=1;
primitive_info=(PrimitiveInfo *) ResizeQuantumMemory(primitive_info,
(size_t) number_points,sizeof(*primitive_info));
- if (primitive_info == (PrimitiveInfo *) NULL)
- {
- (void) ThrowMagickException(exception,GetMagickModule(),
- ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
- break;
- }
+ if ((primitive_info == (PrimitiveInfo *) NULL) ||
+ (number_points != (MagickSizeType) ((size_t) number_points)))
+ ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
+ image->filename);
}
primitive_info[j].primitive=primitive_type;
primitive_info[j].coordinates=(size_t) x;
/*
Speculate how many points our primitive might consume.
*/
- length=primitive_info[j].coordinates;
+ points_extent=(double) primitive_info[j].coordinates;
switch (primitive_type)
{
case RectanglePrimitive:
{
- length*=5;
+ points_extent*=5;
break;
}
case RoundRectanglePrimitive:
alpha=bounds.x2-bounds.x1;
beta=bounds.y2-bounds.y1;
radius=hypot((double) alpha,(double) beta);
- length*=5;
- length+=2*((size_t) ceil((double) MagickPI*radius))+6*BezierQuantum+360;
+ points_extent*=5;
+ points_extent+=2*ceil((double) MagickPI*radius)+6*BezierQuantum+360;
break;
}
case BezierPrimitive:
if (primitive_info[j].coordinates > 107)
(void) ThrowMagickException(exception,GetMagickModule(),DrawError,
"TooManyBezierCoordinates","`%s'",token);
- length=BezierQuantum*primitive_info[j].coordinates;
+ points_extent=(double) (BezierQuantum*primitive_info[j].coordinates);
break;
}
case PathPrimitive:
*s,
*t;
- GetMagickToken(q,&q,token);
- length=1;
+ GetNextToken(q,&q,extent,token);
+ points_extent=1;
t=token;
for (s=token; *s != '\0'; s=t)
{
t++;
continue;
}
- length++;
+ points_extent++;
}
- length=length*BezierQuantum/2;
+ points_extent=points_extent*BezierQuantum;
break;
}
case CirclePrimitive:
alpha=bounds.x2-bounds.x1;
beta=bounds.y2-bounds.y1;
radius=hypot((double) alpha,(double) beta);
- length=2*((size_t) ceil((double) MagickPI*radius))+6*BezierQuantum+360;
+ points_extent=2*ceil((double) MagickPI*radius)+6*BezierQuantum+360;
break;
}
default:
break;
}
- if ((size_t) (i+length) >= number_points)
+ if (((double) ((size_t) points_extent)) < points_extent)
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
+ break;
+ }
+ if (((MagickSizeType) (i+points_extent)) >= number_points)
{
/*
Resize based on speculative points required by primitive.
*/
- number_points+=length+1;
+ number_points+=points_extent+1;
primitive_info=(PrimitiveInfo *) ResizeQuantumMemory(primitive_info,
(size_t) number_points,sizeof(*primitive_info));
- if (primitive_info == (PrimitiveInfo *) NULL)
+ if ((primitive_info == (PrimitiveInfo *) NULL) ||
+ (number_points != (MagickSizeType) ((size_t) number_points)))
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
i=(ssize_t) (j+TracePath(primitive_info+j,token));
break;
}
+ case AlphaPrimitive:
case ColorPrimitive:
- case MattePrimitive:
{
ssize_t
method;
status=MagickFalse;
break;
}
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
method=ParseCommandOption(MagickMethodOptions,MagickFalse,token);
if (method == -1)
status=MagickFalse;
break;
}
if (*token != ',')
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
primitive_info[j].text=AcquireString(token);
break;
}
status=MagickFalse;
break;
}
- GetMagickToken(q,&q,token);
+ GetNextToken(q,&q,extent,token);
primitive_info[j].text=AcquireString(token);
break;
}
}
case RadialGradient:
{
- double
- length,
- offset;
-
PointInfo
v;
- v.x=(double) x-gradient->center.x;
- v.y=(double) y-gradient->center.y;
- length=sqrt(v.x*v.x+v.y*v.y);
if (gradient->spread == RepeatSpread)
- return(length);
- offset=length/gradient->radius;
- return(offset);
+ {
+ v.x=(double) x-gradient->center.x;
+ v.y=(double) y-gradient->center.y;
+ return(sqrt(v.x*v.x+v.y*v.y));
+ }
+ v.x=(double) (((x-gradient->center.x)*cos(DegreesToRadians(
+ gradient->angle)))+((y-gradient->center.y)*sin(DegreesToRadians(
+ gradient->angle))))/gradient->radii.x;
+ v.y=(double) (((x-gradient->center.x)*sin(DegreesToRadians(
+ gradient->angle)))-((y-gradient->center.y)*cos(DegreesToRadians(
+ gradient->angle))))/gradient->radii.y;
+ return(sqrt(v.x*v.x+v.y*v.y));
}
}
return(0.0);
}
+static int StopInfoCompare(const void *x,const void *y)
+{
+ StopInfo
+ *stop_1,
+ *stop_2;
+
+ stop_1=(StopInfo *) x;
+ stop_2=(StopInfo *) y;
+ if (stop_1->offset > stop_2->offset)
+ return(1);
+ if (fabs(stop_1->offset-stop_2->offset) <= DrawEpsilon)
+ return(0);
+ return(-1);
+}
+
MagickExport MagickBooleanType DrawGradientImage(Image *image,
const DrawInfo *draw_info,ExceptionInfo *exception)
{
Draw linear or radial gradient on image.
*/
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(draw_info != (const DrawInfo *) NULL);
gradient=(&draw_info->gradient);
+ qsort(gradient->stops,gradient->number_stops,sizeof(StopInfo),
+ StopInfoCompare);
gradient_vector=(&gradient->gradient_vector);
point.x=gradient_vector->x2-gradient_vector->x1;
point.y=gradient_vector->y2-gradient_vector->y1;
offset;
register Quantum
- *restrict q;
+ *magick_restrict q;
register ssize_t
i,
}
CompositePixelInfoOver(&composite,composite.alpha,&pixel,pixel.alpha,
&pixel);
- SetPixelInfoPixel(image,&pixel,q);
+ SetPixelViaPixelInfo(image,&pixel,q);
q+=GetPixelChannels(image);
}
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
ExceptionInfo *exception)
{
char
- property[MaxTextExtent];
+ property[MagickPathExtent];
const char
*geometry,
- *path;
+ *path,
+ *type;
DrawInfo
*clone_info;
status;
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(draw_info != (const DrawInfo *) NULL);
assert(name != (const char *) NULL);
- (void) FormatLocaleString(property,MaxTextExtent,"%s",name);
+ (void) FormatLocaleString(property,MagickPathExtent,"%s",name);
path=GetImageArtifact(image,property);
if (path == (const char *) NULL)
return(MagickFalse);
- (void) FormatLocaleString(property,MaxTextExtent,"%s-geometry",name);
+ (void) FormatLocaleString(property,MagickPathExtent,"%s-geometry",name);
geometry=GetImageArtifact(image,property);
if (geometry == (const char *) NULL)
return(MagickFalse);
clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
clone_info->fill_pattern=NewImageList();
clone_info->stroke_pattern=NewImageList();
+ (void) FormatLocaleString(property,MagickPathExtent,"%s-type",name);
+ type=GetImageArtifact(image,property);
+ if (type != (const char *) NULL)
+ clone_info->gradient.type=(GradientType) ParseCommandOption(
+ MagickGradientOptions,MagickFalse,type);
(void) CloneString(&clone_info->primitive,path);
status=DrawImage(*pattern,clone_info,exception);
clone_info=DestroyDrawInfo(clone_info);
return(polygon_info);
}
-static PolygonInfo **AcquirePolygonThreadSet(const DrawInfo *draw_info,
+static PolygonInfo **AcquirePolygonThreadSet(
const PrimitiveInfo *primitive_info)
{
PathInfo
- *restrict path_info;
+ *magick_restrict path_info;
PolygonInfo
**polygon_info;
if (polygon_info == (PolygonInfo **) NULL)
return((PolygonInfo **) NULL);
(void) ResetMagickMemory(polygon_info,0,number_threads*sizeof(*polygon_info));
- path_info=ConvertPrimitiveToPath(draw_info,primitive_info);
+ path_info=ConvertPrimitiveToPath(primitive_info);
if (path_info == (PathInfo *) NULL)
return(DestroyPolygonThreadSet(polygon_info));
for (i=0; i < (ssize_t) number_threads; i++)
{
- polygon_info[i]=ConvertPathToPolygon(draw_info,path_info);
+ polygon_info[i]=ConvertPathToPolygon(path_info);
if (polygon_info[i] == (PolygonInfo *) NULL)
return(DestroyPolygonThreadSet(polygon_info));
}
else
{
beta=1.0;
- if (distance != 1.0)
+ if (fabs(distance-1.0) >= DrawEpsilon)
beta=sqrt((double) distance);
alpha=beta-mid-0.5;
if (*stroke_alpha < ((alpha-0.25)*(alpha-0.25)))
}
if (distance > 1.0)
continue;
- if (beta == 0.0)
+ if (fabs(beta) < DrawEpsilon)
{
beta=1.0;
- if (distance != 1.0)
+ if (fabs(distance-1.0) >= DrawEpsilon)
beta=sqrt(distance);
}
alpha=beta-1.0;
mid;
PolygonInfo
- **restrict polygon_info;
+ **magick_restrict polygon_info;
register EdgeInfo
*p;
bounds;
ssize_t
- start,
- stop,
+ start_y,
+ stop_y,
y;
/*
Compute bounding box.
*/
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(draw_info != (DrawInfo *) NULL);
- assert(draw_info->signature == MagickSignature);
+ assert(draw_info->signature == MagickCoreSignature);
assert(primitive_info != (PrimitiveInfo *) NULL);
if (primitive_info->coordinates == 0)
return(MagickTrue);
- polygon_info=AcquirePolygonThreadSet(draw_info,primitive_info);
+ polygon_info=AcquirePolygonThreadSet(primitive_info);
if (polygon_info == (PolygonInfo **) NULL)
return(MagickFalse);
DisableMSCWarning(4127)
image->rows ? (double) image->rows-1 : bounds.y2;
status=MagickTrue;
image_view=AcquireAuthenticCacheView(image,exception);
- if (primitive_info->coordinates == 1)
+ if ((primitive_info->coordinates == 1) ||
+ (polygon_info[0]->number_edges == 0))
{
/*
Draw point.
*/
- start=(ssize_t) ceil(bounds.y1-0.5);
- stop=(ssize_t) floor(bounds.y2+0.5);
+ start_y=(ssize_t) ceil(bounds.y1-0.5);
+ stop_y=(ssize_t) floor(bounds.y2+0.5);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(status) \
magick_threads(image,image,1,1)
#endif
- for (y=start; y <= stop; y++)
+ for (y=start_y; y <= stop_y; y++)
{
MagickBooleanType
sync;
x;
register Quantum
- *restrict q;
+ *magick_restrict q;
ssize_t
- start,
- stop;
+ start_x,
+ stop_x;
if (status == MagickFalse)
continue;
- start=(ssize_t) ceil(bounds.x1-0.5);
- stop=(ssize_t) floor(bounds.x2+0.5);
- x=start;
- q=GetCacheViewAuthenticPixels(image_view,x,y,(size_t) (stop-x+1),1,
+ start_x=(ssize_t) ceil(bounds.x1-0.5);
+ stop_x=(ssize_t) floor(bounds.x2+0.5);
+ x=start_x;
+ q=GetCacheViewAuthenticPixels(image_view,x,y,(size_t) (stop_x-x+1),1,
exception);
if (q == (Quantum *) NULL)
{
continue;
}
GetPixelInfo(image,&pixel);
- for ( ; x <= stop; x++)
+ for ( ; x <= stop_x; x++)
{
if ((x == (ssize_t) ceil(primitive_info->point.x-0.5)) &&
(y == (ssize_t) ceil(primitive_info->point.y-0.5)))
{
- (void) GetStrokeColor(draw_info,x,y,&pixel,exception);
- SetPixelInfoPixel(image,&pixel,q);
+ GetFillColor(draw_info,x-start_x,y-start_y,&pixel,exception);
+ SetPixelViaPixelInfo(image,&pixel,q);
}
q+=GetPixelChannels(image);
}
/*
Draw polygon or line.
*/
- if (image->alpha_trait != BlendPixelTrait)
+ if (image->alpha_trait == UndefinedPixelTrait)
(void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
- start=(ssize_t) ceil(bounds.y1-0.5);
- stop=(ssize_t) floor(bounds.y2+0.5);
+ start_y=(ssize_t) ceil(bounds.y1-0.5);
+ stop_y=(ssize_t) floor(bounds.y2+0.5);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(status) \
magick_threads(image,image,1,1)
#endif
- for (y=start; y <= stop; y++)
+ for (y=start_y; y <= stop_y; y++)
{
const int
id = GetOpenMPThreadId();
stroke_color;
register Quantum
- *restrict q;
+ *magick_restrict q;
register ssize_t
x;
ssize_t
- start,
- stop;
+ start_x,
+ stop_x;
if (status == MagickFalse)
continue;
- start=(ssize_t) ceil(bounds.x1-0.5);
- stop=(ssize_t) floor(bounds.x2+0.5);
- q=GetCacheViewAuthenticPixels(image_view,start,y,(size_t) (stop-start+1),1,
- exception);
+ start_x=(ssize_t) ceil(bounds.x1-0.5);
+ stop_x=(ssize_t) floor(bounds.x2+0.5);
+ q=GetCacheViewAuthenticPixels(image_view,start_x,y,(size_t) (stop_x-start_x+ 1),1,exception);
if (q == (Quantum *) NULL)
{
status=MagickFalse;
continue;
}
- for (x=start; x <= stop; x++)
+ for (x=start_x; x <= stop_x; x++)
{
/*
Fill and/or stroke.
fill_alpha=fill_alpha > 0.25 ? 1.0 : 0.0;
stroke_alpha=stroke_alpha > 0.25 ? 1.0 : 0.0;
}
- (void) GetFillColor(draw_info,x,y,&fill_color,exception);
+ GetFillColor(draw_info,x-start_x,y-start_y,&fill_color,exception);
fill_alpha=fill_alpha*fill_color.alpha;
CompositePixelOver(image,&fill_color,fill_alpha,q,(double)
GetPixelAlpha(image,q),q);
- (void) GetStrokeColor(draw_info,x,y,&stroke_color,exception);
+ GetStrokeColor(draw_info,x-start_x,y-start_y,&stroke_color,exception);
stroke_alpha=stroke_alpha*stroke_color.alpha;
CompositePixelOver(image,&stroke_color,stroke_alpha,q,(double)
GetPixelAlpha(image,q),q);
y=(ssize_t) ceil(primitive_info->point.y-0.5);
switch (primitive_info->primitive)
{
- case PointPrimitive:
+ case AlphaPrimitive:
{
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
- "PointPrimitive %.20g,%.20g %s",(double) x,(double) y,
+ "AlphaPrimitive %.20g,%.20g %s",(double) x,(double) y,
methods[primitive_info->method]);
return;
}
methods[primitive_info->method]);
return;
}
- case MattePrimitive:
+ case ImagePrimitive:
{
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
- "MattePrimitive %.20g,%.20g %s",(double) x,(double) y,
- methods[primitive_info->method]);
+ "ImagePrimitive %.20g,%.20g",(double) x,(double) y);
return;
}
- case TextPrimitive:
+ case PointPrimitive:
{
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
- "TextPrimitive %.20g,%.20g",(double) x,(double) y);
+ "PointPrimitive %.20g,%.20g %s",(double) x,(double) y,
+ methods[primitive_info->method]);
return;
}
- case ImagePrimitive:
+ case TextPrimitive:
{
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
- "ImagePrimitive %.20g,%.20g",(double) x,(double) y);
+ "TextPrimitive %.20g,%.20g",(double) x,(double) y);
return;
}
default:
p=point;
}
point=primitive_info[i].point;
- if ((fabs(q.x-point.x) >= MagickEpsilon) ||
- (fabs(q.y-point.y) >= MagickEpsilon))
+ if ((fabs(q.x-point.x) >= DrawEpsilon) ||
+ (fabs(q.y-point.y) >= DrawEpsilon))
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
" %.20g: %.18g,%.18g",(double) coordinates,point.x,point.y);
else
coordinates--;
if (coordinates > 0)
continue;
- if ((fabs(p.x-point.x) >= MagickEpsilon) ||
- (fabs(p.y-point.y) >= MagickEpsilon))
+ if ((fabs(p.x-point.x) >= DrawEpsilon) ||
+ (fabs(p.y-point.y) >= DrawEpsilon))
(void) LogMagickEvent(DrawEvent,GetMagickModule()," end last (%.20g)",
(double) coordinates);
else
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
" begin draw-primitive");
(void) LogMagickEvent(DrawEvent,GetMagickModule(),
- " affine: %g %g %g %g %g %g",draw_info->affine.sx,
+ " affine: %g,%g,%g,%g,%g,%g",draw_info->affine.sx,
draw_info->affine.rx,draw_info->affine.ry,draw_info->affine.sy,
draw_info->affine.tx,draw_info->affine.ty);
}
image_view=AcquireAuthenticCacheView(image,exception);
switch (primitive_info->primitive)
{
- case PointPrimitive:
- {
- PixelInfo
- fill_color;
-
- register Quantum
- *q;
-
- if ((y < 0) || (y >= (ssize_t) image->rows))
- break;
- if ((x < 0) || (x >= (ssize_t) image->columns))
- break;
- q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
- if (q == (Quantum *) NULL)
- break;
- (void) GetFillColor(draw_info,x,y,&fill_color,exception);
- CompositePixelOver(image,&fill_color,(double) fill_color.alpha,q,
- (double) GetPixelAlpha(image,q),q);
- (void) SyncCacheViewAuthenticPixels(image_view,exception);
- break;
- }
- case ColorPrimitive:
+ case AlphaPrimitive:
{
+ if (image->alpha_trait == UndefinedPixelTrait)
+ (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
switch (primitive_info->method)
{
case PointMethod:
q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
if (q == (Quantum *) NULL)
break;
- GetPixelInfo(image,&pixel);
- (void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelInfoPixel(image,&pixel,q);
+ GetFillColor(draw_info,x,y,&pixel,exception);
+ SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
(void) SyncCacheViewAuthenticPixels(image_view,exception);
break;
}
(void) GetOneCacheViewVirtualPixelInfo(image_view,x,y,&target,
exception);
+ GetPixelInfo(image,&pixel);
for (y=0; y < (ssize_t) image->rows; y++)
{
register Quantum
- *restrict q;
+ *magick_restrict q;
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
exception);
q+=GetPixelChannels(image);
continue;
}
- (void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelInfoPixel(image,&pixel,q);
+ GetFillColor(draw_info,x,y,&pixel,exception);
+ SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
q+=GetPixelChannels(image);
}
sync=SyncCacheViewAuthenticPixels(image_view,exception);
case FloodfillMethod:
case FillToBorderMethod:
{
+ ChannelType
+ channel_mask;
+
PixelInfo
target;
target.green=(double) draw_info->border_color.green;
target.blue=(double) draw_info->border_color.blue;
}
+ channel_mask=SetImageChannelMask(image,AlphaChannel);
status&=FloodfillPaintImage(image,draw_info,&target,x,y,
primitive_info->method == FloodfillMethod ? MagickFalse :
MagickTrue,exception);
+ (void) SetImageChannelMask(image,channel_mask);
break;
}
case ResetMethod:
PixelInfo
pixel;
- GetPixelInfo(image,&pixel);
for (y=0; y < (ssize_t) image->rows; y++)
{
register Quantum
- *restrict q;
-
- register ssize_t
- x;
+ *magick_restrict q;
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
exception);
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- (void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelInfoPixel(image,&pixel,q);
+ GetFillColor(draw_info,x,y,&pixel,exception);
+ SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
q+=GetPixelChannels(image);
}
sync=SyncCacheViewAuthenticPixels(image_view,exception);
}
break;
}
- case MattePrimitive:
+ case ColorPrimitive:
{
- if (image->alpha_trait != BlendPixelTrait)
- (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
switch (primitive_info->method)
{
case PointMethod:
q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
if (q == (Quantum *) NULL)
break;
- (void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
+ GetPixelInfo(image,&pixel);
+ GetFillColor(draw_info,x,y,&pixel,exception);
+ SetPixelViaPixelInfo(image,&pixel,q);
(void) SyncCacheViewAuthenticPixels(image_view,exception);
break;
}
(void) GetOneCacheViewVirtualPixelInfo(image_view,x,y,&target,
exception);
- GetPixelInfo(image,&pixel);
for (y=0; y < (ssize_t) image->rows; y++)
{
register Quantum
- *restrict q;
-
- register ssize_t
- x;
+ *magick_restrict q;
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
exception);
q+=GetPixelChannels(image);
continue;
}
- (void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
+ GetFillColor(draw_info,x,y,&pixel,exception);
+ SetPixelViaPixelInfo(image,&pixel,q);
q+=GetPixelChannels(image);
}
sync=SyncCacheViewAuthenticPixels(image_view,exception);
case FloodfillMethod:
case FillToBorderMethod:
{
- ChannelType
- channel_mask;
-
PixelInfo
target;
target.green=(double) draw_info->border_color.green;
target.blue=(double) draw_info->border_color.blue;
}
- channel_mask=SetImageChannelMask(image,AlphaChannel);
status&=FloodfillPaintImage(image,draw_info,&target,x,y,
primitive_info->method == FloodfillMethod ? MagickFalse :
MagickTrue,exception);
- (void) SetImageChannelMask(image,channel_mask);
break;
}
case ResetMethod:
PixelInfo
pixel;
+ GetPixelInfo(image,&pixel);
for (y=0; y < (ssize_t) image->rows; y++)
{
register Quantum
- *restrict q;
-
- register ssize_t
- x;
+ *magick_restrict q;
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
exception);
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- (void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
+ GetFillColor(draw_info,x,y,&pixel,exception);
+ SetPixelViaPixelInfo(image,&pixel,q);
q+=GetPixelChannels(image);
}
sync=SyncCacheViewAuthenticPixels(image_view,exception);
}
break;
}
- case TextPrimitive:
- {
- char
- geometry[MaxTextExtent];
-
- DrawInfo
- *clone_info;
-
- if (primitive_info->text == (char *) NULL)
- break;
- clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
- (void) CloneString(&clone_info->text,primitive_info->text);
- (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
- primitive_info->point.x,primitive_info->point.y);
- (void) CloneString(&clone_info->geometry,geometry);
- status&=AnnotateImage(image,clone_info,exception);
- clone_info=DestroyDrawInfo(clone_info);
- break;
- }
case ImagePrimitive:
{
AffineMatrix
affine;
char
- composite_geometry[MaxTextExtent];
+ composite_geometry[MagickPathExtent];
Image
*composite_image;
else
{
(void) CopyMagickString(clone_info->filename,primitive_info->text,
- MaxTextExtent);
+ MagickPathExtent);
composite_image=ReadImage(clone_info,exception);
}
clone_info=DestroyImageInfo(clone_info);
if (((x1 != 0L) && (x1 != (ssize_t) composite_image->columns)) ||
((y1 != 0L) && (y1 != (ssize_t) composite_image->rows)))
{
- char
- geometry[MaxTextExtent];
-
/*
Resize image.
*/
- (void) FormatLocaleString(geometry,MaxTextExtent,"%gx%g!",
- primitive_info[1].point.x,primitive_info[1].point.y);
+ (void) FormatLocaleString(composite_geometry,MagickPathExtent,
+ "%gx%g!",primitive_info[1].point.x,primitive_info[1].point.y);
composite_image->filter=image->filter;
- (void) TransformImage(&composite_image,(char *) NULL,geometry,
- exception);
+ (void) TransformImage(&composite_image,(char *) NULL,
+ composite_geometry,exception);
}
- if (composite_image->alpha_trait != BlendPixelTrait)
+ if (composite_image->alpha_trait == UndefinedPixelTrait)
(void) SetImageAlphaChannel(composite_image,OpaqueAlphaChannel,
exception);
if (draw_info->alpha != OpaqueAlpha)
image->gravity=draw_info->gravity;
geometry.x=x;
geometry.y=y;
- (void) FormatLocaleString(composite_geometry,MaxTextExtent,
+ (void) FormatLocaleString(composite_geometry,MagickPathExtent,
"%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,(double)
composite_image->rows,(double) geometry.x,(double) geometry.y);
(void) ParseGravityGeometry(image,composite_geometry,&geometry,exception);
composite_image=DestroyImage(composite_image);
break;
}
+ case PointPrimitive:
+ {
+ PixelInfo
+ fill_color;
+
+ register Quantum
+ *q;
+
+ if ((y < 0) || (y >= (ssize_t) image->rows))
+ break;
+ if ((x < 0) || (x >= (ssize_t) image->columns))
+ break;
+ q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
+ if (q == (Quantum *) NULL)
+ break;
+ GetFillColor(draw_info,x,y,&fill_color,exception);
+ CompositePixelOver(image,&fill_color,(double) fill_color.alpha,q,
+ (double) GetPixelAlpha(image,q),q);
+ (void) SyncCacheViewAuthenticPixels(image_view,exception);
+ break;
+ }
+ case TextPrimitive:
+ {
+ char
+ geometry[MagickPathExtent];
+
+ DrawInfo
+ *clone_info;
+
+ if (primitive_info->text == (char *) NULL)
+ break;
+ clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
+ (void) CloneString(&clone_info->text,primitive_info->text);
+ (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
+ primitive_info->point.x,primitive_info->point.y);
+ (void) CloneString(&clone_info->geometry,geometry);
+ status&=AnnotateImage(image,clone_info,exception);
+ clone_info=DestroyDrawInfo(clone_info);
+ break;
+ }
default:
{
double
LogPrimitiveInfo(primitive_info);
scale=ExpandAffine(&draw_info->affine);
if ((draw_info->dash_pattern != (double *) NULL) &&
- (draw_info->dash_pattern[0] != 0.0) &&
- ((scale*draw_info->stroke_width) >= MagickEpsilon) &&
+ (fabs(draw_info->dash_pattern[0]) >= DrawEpsilon) &&
+ (fabs(scale*draw_info->stroke_width) >= DrawEpsilon) &&
(draw_info->stroke.alpha != (Quantum) TransparentAlpha))
{
/*
*/
clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
clone_info->stroke_width=0.0;
- clone_info->stroke.alpha=(Quantum) TransparentAlpha;
+ clone_info->stroke.alpha=(MagickRealType) TransparentAlpha;
status&=DrawPolygonPrimitive(image,clone_info,primitive_info,
exception);
clone_info=DestroyDrawInfo(clone_info);
}
mid=ExpandAffine(&draw_info->affine)*draw_info->stroke_width/2.0;
if ((mid > 1.0) &&
- (draw_info->stroke.alpha != (Quantum) TransparentAlpha))
+ ((draw_info->stroke.alpha != (Quantum) TransparentAlpha) ||
+ (draw_info->stroke_pattern != (Image *) NULL)))
{
MagickBooleanType
closed_path;
*/
for (i=0; primitive_info[i].primitive != UndefinedPrimitive; i++) ;
closed_path=
- (primitive_info[i-1].point.x == primitive_info[0].point.x) &&
- (primitive_info[i-1].point.y == primitive_info[0].point.y) ?
+ (fabs(primitive_info[i-1].point.x-primitive_info[0].point.x) < DrawEpsilon) &&
+ (fabs(primitive_info[i-1].point.y-primitive_info[0].point.y) < DrawEpsilon) ?
MagickTrue : MagickFalse;
i=(ssize_t) primitive_info[0].coordinates;
if ((((draw_info->linecap == RoundCap) ||
}
clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
clone_info->stroke_width=0.0;
- clone_info->stroke.alpha=(Quantum) TransparentAlpha;
+ clone_info->stroke.alpha=(MagickRealType) TransparentAlpha;
status&=DrawPolygonPrimitive(image,clone_info,primitive_info,
exception);
clone_info=DestroyDrawInfo(clone_info);
for (i=0; i < 4; i++)
linecap[i]=(*primitive_info);
linecap[0].coordinates=4;
- linecap[1].point.x+=(double) (10.0*MagickEpsilon);
- linecap[2].point.x+=(double) (10.0*MagickEpsilon);
- linecap[2].point.y+=(double) (10.0*MagickEpsilon);
- linecap[3].point.y+=(double) (10.0*MagickEpsilon);
+ linecap[1].point.x+=2.0*DrawEpsilon;
+ linecap[2].point.x+=2.0*DrawEpsilon;
+ linecap[2].point.y+=2.0*DrawEpsilon;
+ linecap[3].point.y+=2.0*DrawEpsilon;
linecap[4].primitive=UndefinedPrimitive;
(void) DrawPolygonPrimitive(image,draw_info,linecap,exception);
}
if (clone_info->stroke_pattern != (Image *) NULL)
clone_info->fill_pattern=CloneImage(clone_info->stroke_pattern,0,0,
MagickTrue,exception);
- clone_info->stroke.alpha=(Quantum) TransparentAlpha;
+ clone_info->stroke.alpha=(MagickRealType) TransparentAlpha;
clone_info->stroke_width=0.0;
clone_info->fill_rule=NonZeroRule;
status=MagickTrue;
break;
stroke_polygon=(PrimitiveInfo *) RelinquishMagickMemory(stroke_polygon);
q=p+p->coordinates-1;
- closed_path=(q->point.x == p->point.x) && (q->point.y == p->point.y) ?
- MagickTrue : MagickFalse;
+ closed_path=(fabs(q->point.x-p->point.x) < DrawEpsilon) &&
+ (fabs(q->point.y-p->point.y) < DrawEpsilon) ? MagickTrue : MagickFalse;
if ((draw_info->linecap == RoundCap) && (closed_path == MagickFalse))
{
DrawRoundLinecap(image,draw_info,p,exception);
*/
MagickExport void GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
{
+ char
+ *next_token;
+
const char
*option;
ExceptionInfo
*exception;
+ ImageInfo
+ *clone_info;
+
/*
Initialize draw attributes.
*/
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(draw_info != (DrawInfo *) NULL);
(void) ResetMagickMemory(draw_info,0,sizeof(*draw_info));
+ clone_info=CloneImageInfo(image_info);
GetAffineMatrix(&draw_info->affine);
exception=AcquireExceptionInfo();
(void) QueryColorCompliance("#000F",AllCompliance,&draw_info->fill,
(void) QueryColorCompliance("#0000",AllCompliance,&draw_info->stroke,
exception);
draw_info->stroke_width=1.0;
- draw_info->alpha=OpaqueAlpha;
draw_info->fill_rule=EvenOddRule;
+ draw_info->alpha=OpaqueAlpha;
+ draw_info->fill_alpha=OpaqueAlpha;
+ draw_info->stroke_alpha=OpaqueAlpha;
draw_info->linecap=ButtCap;
draw_info->linejoin=MiterJoin;
draw_info->miterlimit=10;
draw_info->decorate=NoDecoration;
draw_info->pointsize=12.0;
- draw_info->undercolor.alpha=(Quantum) TransparentAlpha;
+ draw_info->undercolor.alpha=(MagickRealType) TransparentAlpha;
draw_info->compose=OverCompositeOp;
draw_info->render=MagickTrue;
draw_info->debug=IsEventLogging();
- if (image_info != (ImageInfo *) NULL)
+ draw_info->stroke_antialias=clone_info->antialias;
+ if (clone_info->font != (char *) NULL)
+ draw_info->font=AcquireString(clone_info->font);
+ if (clone_info->density != (char *) NULL)
+ draw_info->density=AcquireString(clone_info->density);
+ draw_info->text_antialias=clone_info->antialias;
+ if (fabs(clone_info->pointsize) >= DrawEpsilon)
+ draw_info->pointsize=clone_info->pointsize;
+ draw_info->border_color=clone_info->border_color;
+ if (clone_info->server_name != (char *) NULL)
+ draw_info->server_name=AcquireString(clone_info->server_name);
+ option=GetImageOption(clone_info,"direction");
+ if (option != (const char *) NULL)
+ draw_info->direction=(DirectionType) ParseCommandOption(
+ MagickDirectionOptions,MagickFalse,option);
+ else
+ draw_info->direction=UndefinedDirection;
+ option=GetImageOption(clone_info,"encoding");
+ if (option != (const char *) NULL)
+ (void) CloneString(&draw_info->encoding,option);
+ option=GetImageOption(clone_info,"family");
+ if (option != (const char *) NULL)
+ (void) CloneString(&draw_info->family,option);
+ option=GetImageOption(clone_info,"fill");
+ if (option != (const char *) NULL)
+ (void) QueryColorCompliance(option,AllCompliance,&draw_info->fill,
+ exception);
+ option=GetImageOption(clone_info,"gravity");
+ if (option != (const char *) NULL)
+ draw_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
+ MagickFalse,option);
+ option=GetImageOption(clone_info,"interline-spacing");
+ if (option != (const char *) NULL)
+ draw_info->interline_spacing=StringToDouble(option,&next_token);
+ option=GetImageOption(clone_info,"interword-spacing");
+ if (option != (const char *) NULL)
+ draw_info->interword_spacing=StringToDouble(option,&next_token);
+ option=GetImageOption(clone_info,"kerning");
+ if (option != (const char *) NULL)
+ draw_info->kerning=StringToDouble(option,&next_token);
+ option=GetImageOption(clone_info,"stroke");
+ if (option != (const char *) NULL)
+ (void) QueryColorCompliance(option,AllCompliance,&draw_info->stroke,
+ exception);
+ option=GetImageOption(clone_info,"strokewidth");
+ if (option != (const char *) NULL)
+ draw_info->stroke_width=StringToDouble(option,&next_token);
+ option=GetImageOption(clone_info,"style");
+ if (option != (const char *) NULL)
+ draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
+ MagickFalse,option);
+ option=GetImageOption(clone_info,"undercolor");
+ if (option != (const char *) NULL)
+ (void) QueryColorCompliance(option,AllCompliance,&draw_info->undercolor,
+ exception);
+ option=GetImageOption(clone_info,"weight");
+ if (option != (const char *) NULL)
{
- draw_info->stroke_antialias=image_info->antialias;
- if (image_info->font != (char *) NULL)
- draw_info->font=AcquireString(image_info->font);
- if (image_info->density != (char *) NULL)
- draw_info->density=AcquireString(image_info->density);
- draw_info->text_antialias=image_info->antialias;
- if (image_info->pointsize != 0.0)
- draw_info->pointsize=image_info->pointsize;
- draw_info->border_color=image_info->border_color;
- if (image_info->server_name != (char *) NULL)
- draw_info->server_name=AcquireString(image_info->server_name);
- option=GetImageOption(image_info,"encoding");
- if (option != (const char *) NULL)
- (void) CloneString(&draw_info->encoding,option);
- option=GetImageOption(image_info,"kerning");
- if (option != (const char *) NULL)
- draw_info->kerning=StringToDouble(option,(char **) NULL);
- option=GetImageOption(image_info,"interline-spacing");
- if (option != (const char *) NULL)
- draw_info->interline_spacing=StringToDouble(option,(char **) NULL);
- option=GetImageOption(image_info,"interword-spacing");
- if (option != (const char *) NULL)
- draw_info->interword_spacing=StringToDouble(option,(char **) NULL);
- option=GetImageOption(image_info,"direction");
- if (option != (const char *) NULL)
- draw_info->direction=(DirectionType) ParseCommandOption(
- MagickDirectionOptions,MagickFalse,option);
- else
- draw_info->direction=UndefinedDirection;
- option=GetImageOption(image_info,"fill");
- if (option != (const char *) NULL)
- (void) QueryColorCompliance(option,AllCompliance,&draw_info->fill,
- exception);
- option=GetImageOption(image_info,"stroke");
- if (option != (const char *) NULL)
- (void) QueryColorCompliance(option,AllCompliance,&draw_info->stroke,
- exception);
- option=GetImageOption(image_info,"strokewidth");
- if (option != (const char *) NULL)
- draw_info->stroke_width=StringToDouble(option,(char **) NULL);
- option=GetImageOption(image_info,"undercolor");
- if (option != (const char *) NULL)
- (void) QueryColorCompliance(option,AllCompliance,&draw_info->undercolor,
- exception);
- option=GetImageOption(image_info,"gravity");
- if (option != (const char *) NULL)
- draw_info->gravity=(GravityType) ParseCommandOption(
- MagickGravityOptions,MagickFalse,option);
+ ssize_t
+ weight;
+
+ weight=ParseCommandOption(MagickWeightOptions,MagickFalse,option);
+ if (weight == -1)
+ weight=(ssize_t) StringToUnsignedLong(option);
+ draw_info->weight=(size_t) weight;
}
exception=DestroyExceptionInfo(exception);
- draw_info->signature=MagickSignature;
+ draw_info->signature=MagickCoreSignature;
+ clone_info=DestroyImageInfo(clone_info);
}
\f
/*
size_t
arc_segments;
- if ((start.x == end.x) && (start.y == end.y))
+ if ((fabs(start.x-end.x) < DrawEpsilon) &&
+ (fabs(start.y-end.y) < DrawEpsilon))
{
TracePoint(primitive_info,end);
return;
}
radii.x=fabs(arc.x);
radii.y=fabs(arc.y);
- if ((radii.x == 0.0) || (radii.y == 0.0))
+ if ((fabs(radii.x) < DrawEpsilon) || (fabs(radii.y) < DrawEpsilon))
{
TraceLine(primitive_info,start,end);
return;
center.y=(double) (cosine*(end.y-start.y)/2-sine*(end.x-start.x)/2);
delta=(center.x*center.x)/(radii.x*radii.x)+(center.y*center.y)/
(radii.y*radii.y);
- if (delta < MagickEpsilon)
+ if (delta < DrawEpsilon)
{
TraceLine(primitive_info,start,end);
return;
alpha=atan2(points[0].y-center.y,points[0].x-center.x);
theta=atan2(points[1].y-center.y,points[1].x-center.x)-alpha;
if ((theta < 0.0) && (sweep != MagickFalse))
- theta+=(double) (2.0*MagickPI);
+ theta+=2.0*MagickPI;
else
if ((theta > 0.0) && (sweep == MagickFalse))
- theta-=(double) (2.0*MagickPI);
- arc_segments=(size_t) ceil(fabs((double) (theta/(0.5*MagickPI+
- MagickEpsilon))));
+ theta-=2.0*MagickPI;
+ arc_segments=(size_t) ceil(fabs((double) (theta/(0.5*MagickPI+DrawEpsilon))));
p=primitive_info;
for (i=0; i < (ssize_t) arc_segments; i++)
{
number_coordinates,sizeof(*coefficients));
points=(PointInfo *) AcquireQuantumMemory((size_t) control_points,
sizeof(*points));
- if ((coefficients == (double *) NULL) ||
- (points == (PointInfo *) NULL))
+ if ((coefficients == (double *) NULL) || (points == (PointInfo *) NULL))
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
/*
Compute bezier points.
/*
Ellipses are just short segmented polys.
*/
- if ((stop.x == 0.0) && (stop.y == 0.0))
+ if ((fabs(stop.x) < DrawEpsilon) && (fabs(stop.y) < DrawEpsilon))
{
TracePoint(primitive_info,start);
return;
}
delta=2.0/MagickMax(stop.x,stop.y);
- step=(double) (MagickPI/8.0);
- if ((delta >= 0.0) && (delta < (double) (MagickPI/8.0)))
- step=(double) (MagickPI/(4*(MagickPI/delta/2+0.5)));
+ step=MagickPI/8.0;
+ if ((delta >= 0.0) && (delta < (MagickPI/8.0)))
+ step=MagickPI/(4*(MagickPI/delta/2+0.5));
angle.x=DegreesToRadians(degrees.x);
y=degrees.y;
while (y < degrees.x)
y+=360.0;
- angle.y=(double) DegreesToRadians(y);
+ angle.y=DegreesToRadians(y);
for (p=primitive_info; angle.x < angle.y; angle.x+=step)
{
point.x=cos(fmod(angle.x,DegreesToRadians(360.0)))*stop.x+start.x;
const PointInfo end)
{
TracePoint(primitive_info,start);
- if ((fabs(start.x-end.x) < MagickEpsilon) &&
- (fabs(start.y-end.y) < MagickEpsilon))
+ if ((fabs(start.x-end.x) < DrawEpsilon) &&
+ (fabs(start.y-end.y) < DrawEpsilon))
{
primitive_info->primitive=PointPrimitive;
primitive_info->coordinates=1;
static size_t TracePath(PrimitiveInfo *primitive_info,const char *path)
{
char
- token[MaxTextExtent];
+ *next_token,
+ token[MagickPathExtent];
const char
*p;
- int
- attribute,
- last_attribute;
-
double
x,
y;
+ int
+ attribute,
+ last_attribute;
+
PointInfo
- end,
- points[4],
- point,
- start;
+ end = {0.0, 0.0},
+ points[4] = { {0.0,0.0}, {0.0,0.0}, {0.0,0.0}, {0.0,0.0} },
+ point = {0.0, 0.0},
+ start = {0.0, 0.0};
PrimitiveType
primitive_type;
z_count;
attribute=0;
- end.x=0.0;
- end.y=0.0;
- point.x=0.0;
- point.y=0.0;
- start.x=0.0;
- start.y=0.0;
number_coordinates=0;
z_count=0;
- (void) ResetMagickMemory(points,0,sizeof(*points));
primitive_type=primitive_info->primitive;
q=primitive_info;
for (p=path; *p != '\0'; )
case 'a':
case 'A':
{
+ double
+ angle;
+
MagickBooleanType
large_arc,
sweep;
- double
- angle;
-
PointInfo
arc;
*/
do
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- arc.x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ arc.x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- arc.y=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ arc.y=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- angle=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ angle=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
large_arc=StringToLong(token) != 0 ? MagickTrue : MagickFalse;
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
sweep=StringToLong(token) != 0 ? MagickTrue : MagickFalse;
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
end.x=(double) (attribute == (int) 'A' ? x : point.x+x);
end.y=(double) (attribute == (int) 'A' ? y : point.y+y);
TraceArcPath(q,point,end,arc,angle,large_arc,sweep);
points[0]=point;
for (i=1; i < 4; i++)
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
end.x=(double) (attribute == (int) 'C' ? x : point.x+x);
end.y=(double) (attribute == (int) 'C' ? y : point.y+y);
points[i]=end;
{
do
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
point.x=(double) (attribute == (int) 'H' ? x: point.x+x);
TracePoint(q,point);
q+=q->coordinates;
{
do
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
point.x=(double) (attribute == (int) 'L' ? x : point.x+x);
point.y=(double) (attribute == (int) 'L' ? y : point.y+y);
TracePoint(q,point);
i=0;
do
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
point.x=(double) (attribute == (int) 'M' ? x : point.x+x);
point.y=(double) (attribute == (int) 'M' ? y : point.y+y);
if (i == 0)
points[0]=point;
for (i=1; i < 3; i++)
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
if (*p == ',')
p++;
end.x=(double) (attribute == (int) 'Q' ? x : point.x+x);
points[1].y=2.0*points[3].y-points[2].y;
for (i=2; i < 4; i++)
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
if (*p == ',')
p++;
end.x=(double) (attribute == (int) 'S' ? x : point.x+x);
}
if (strchr("CcSs",last_attribute) == (char *) NULL)
{
- points[0]=points[2];
- points[1]=points[3];
+ points[0]=point;
+ points[1]=point;
}
for (i=0; i < 4; i++)
(q+i)->point=points[i];
points[1].y=2.0*points[2].y-points[1].y;
for (i=2; i < 3; i++)
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- x=StringToDouble(token,(char **) NULL);
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ x=StringToDouble(token,&next_token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
end.x=(double) (attribute == (int) 'T' ? x : point.x+x);
end.y=(double) (attribute == (int) 'T' ? y : point.y+y);
points[i]=end;
}
if (strchr("QqTt",last_attribute) == (char *) NULL)
{
- points[0]=points[2];
- points[1]=points[3];
+ points[0]=point;
+ points[1]=point;
}
for (i=0; i < 3; i++)
(q+i)->point=points[i];
{
do
{
- GetMagickToken(p,&p,token);
+ GetNextToken(p,&p,MagickPathExtent,token);
if (*token == ',')
- GetMagickToken(p,&p,token);
- y=StringToDouble(token,(char **) NULL);
+ GetNextToken(p,&p,MagickPathExtent,token);
+ y=StringToDouble(token,&next_token);
point.y=(double) (attribute == (int) 'V' ? y : point.y+y);
TracePoint(q,point);
q+=q->coordinates;
{
dx=primitive_info[0].point.x-primitive_info[i].point.x;
dy=primitive_info[0].point.y-primitive_info[i].point.y;
- if ((fabs((double) dx) >= MagickEpsilon) ||
- (fabs((double) dy) >= MagickEpsilon))
+ if ((fabs((double) dx) >= DrawEpsilon) ||
+ (fabs((double) dy) >= DrawEpsilon))
break;
}
if (i == (ssize_t) number_vertices)
{
dx=primitive_info[number_vertices-1].point.x-primitive_info[j].point.x;
dy=primitive_info[number_vertices-1].point.y-primitive_info[j].point.y;
- if ((fabs((double) dx) >= MagickEpsilon) ||
- (fabs((double) dy) >= MagickEpsilon))
+ if ((fabs((double) dx) >= DrawEpsilon) ||
+ (fabs((double) dy) >= DrawEpsilon))
break;
}
distance=hypot((double) dx,(double) dy);
dy*(distance+offset)/distance);
}
-static inline double DrawEpsilonReciprocal(const double x)
-{
-#define DrawEpsilon ((double) 1.0e-10)
-
- double sign = x < (double) 0.0 ? (double) -1.0 :
- (double) 1.0;
- return((sign*x) >= DrawEpsilon ? (double) 1.0/x : sign*(
- (double) 1.0/DrawEpsilon));
-}
-
static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
const PrimitiveInfo *primitive_info)
{
q;
} LineSegment;
+ double
+ delta_theta,
+ dot_product,
+ mid,
+ miterlimit;
+
LineSegment
dx,
dy,
MagickBooleanType
closed_path;
- double
- delta_theta,
- dot_product,
- mid,
- miterlimit;
-
PointInfo
box_p[5],
box_q[5],
(void) CopyMagickMemory(polygon_primitive,primitive_info,(size_t)
number_vertices*sizeof(*polygon_primitive));
closed_path=
- (primitive_info[number_vertices-1].point.x == primitive_info[0].point.x) &&
- (primitive_info[number_vertices-1].point.y == primitive_info[0].point.y) ?
+ (fabs(primitive_info[number_vertices-1].point.x-primitive_info[0].point.x) < DrawEpsilon) &&
+ (fabs(primitive_info[number_vertices-1].point.y-primitive_info[0].point.y) < DrawEpsilon) ?
MagickTrue : MagickFalse;
- if ((draw_info->linejoin == RoundJoin) ||
- ((draw_info->linejoin == MiterJoin) && (closed_path != MagickFalse)))
+ if (((draw_info->linejoin == RoundJoin) ||
+ (draw_info->linejoin == MiterJoin)) && (closed_path != MagickFalse))
{
polygon_primitive[number_vertices]=primitive_info[1];
number_vertices++;
{
dx.p=polygon_primitive[n].point.x-polygon_primitive[0].point.x;
dy.p=polygon_primitive[n].point.y-polygon_primitive[0].point.y;
- if ((fabs(dx.p) >= MagickEpsilon) || (fabs(dy.p) >= MagickEpsilon))
+ if ((fabs(dx.p) >= DrawEpsilon) || (fabs(dy.p) >= DrawEpsilon))
break;
}
if (n == (ssize_t) number_vertices)
n=(ssize_t) number_vertices-1L;
- slope.p=DrawEpsilonReciprocal(dx.p)*dy.p;
- inverse_slope.p=(-1.0*DrawEpsilonReciprocal(slope.p));
+ slope.p=0.0;
+ inverse_slope.p=0.0;
+ if (fabs(dx.p) < DrawEpsilon)
+ {
+ if (dx.p >= 0.0)
+ slope.p=dy.p < 0.0 ? -1.0/DrawEpsilon : 1.0/DrawEpsilon;
+ else
+ slope.p=dy.p < 0.0 ? 1.0/DrawEpsilon : -1.0/DrawEpsilon;
+ }
+ else
+ if (fabs(dy.p) < DrawEpsilon)
+ {
+ if (dy.p >= 0.0)
+ inverse_slope.p=dx.p < 0.0 ? -1.0/DrawEpsilon : 1.0/DrawEpsilon;
+ else
+ inverse_slope.p=dx.p < 0.0 ? 1.0/DrawEpsilon : -1.0/DrawEpsilon;
+ }
+ else
+ {
+ slope.p=dy.p/dx.p;
+ inverse_slope.p=(-1.0/slope.p);
+ }
mid=ExpandAffine(&draw_info->affine)*draw_info->stroke_width/2.0;
- miterlimit=(double) (draw_info->miterlimit*draw_info->miterlimit*
- mid*mid);
+ miterlimit=(double) (draw_info->miterlimit*draw_info->miterlimit*mid*mid);
if ((draw_info->linecap == SquareCap) && (closed_path == MagickFalse))
TraceSquareLinecap(polygon_primitive,number_vertices,mid);
offset.x=sqrt((double) (mid*mid/(inverse_slope.p*inverse_slope.p+1.0)));
dot_product=dx.q*dx.q+dy.q*dy.q;
if (dot_product < 0.25)
continue;
- slope.q=DrawEpsilonReciprocal(dx.q)*dy.q;
- inverse_slope.q=(-1.0*DrawEpsilonReciprocal(slope.q));
+ slope.q=0.0;
+ inverse_slope.q=0.0;
+ if (fabs(dx.q) < DrawEpsilon)
+ {
+ if (dx.q >= 0.0)
+ slope.q=dy.q < 0.0 ? -1.0/DrawEpsilon : 1.0/DrawEpsilon;
+ else
+ slope.q=dy.q < 0.0 ? 1.0/DrawEpsilon : -1.0/DrawEpsilon;
+ }
+ else
+ if (fabs(dy.q) < DrawEpsilon)
+ {
+ if (dy.q >= 0.0)
+ inverse_slope.q=dx.q < 0.0 ? -1.0/DrawEpsilon : 1.0/DrawEpsilon;
+ else
+ inverse_slope.q=dx.q < 0.0 ? 1.0/DrawEpsilon : -1.0/DrawEpsilon;
+ }
+ else
+ {
+ slope.q=dy.q/dx.q;
+ inverse_slope.q=(-1.0/slope.q);
+ }
offset.x=sqrt((double) (mid*mid/(inverse_slope.q*inverse_slope.q+1.0)));
offset.y=(double) (offset.x*inverse_slope.q);
dot_product=dy.q*offset.x-dx.q*offset.y;
box_q[3].x=polygon_primitive[i].point.x-offset.x;
box_q[3].y=polygon_primitive[i].point.y-offset.y;
}
- if (fabs((double) (slope.p-slope.q)) < MagickEpsilon)
+ if (fabs((double) (slope.p-slope.q)) < DrawEpsilon)
{
box_p[4]=box_p[1];
box_q[4]=box_q[1];
}
if (q >= (ssize_t) (max_strokes-6*BezierQuantum-360))
{
- max_strokes+=6*BezierQuantum+360;
- path_p=(PointInfo *) ResizeQuantumMemory(path_p,(size_t) max_strokes,
- sizeof(*path_p));
- path_q=(PointInfo *) ResizeQuantumMemory(path_q,(size_t) max_strokes,
- sizeof(*path_q));
- if ((path_p == (PointInfo *) NULL) || (path_q == (PointInfo *) NULL))
- {
- polygon_primitive=(PrimitiveInfo *)
- RelinquishMagickMemory(polygon_primitive);
- return((PrimitiveInfo *) NULL);
- }
+ if (~max_strokes < (6*BezierQuantum+360))
+ {
+ path_p=(PointInfo *) RelinquishMagickMemory(path_p);
+ path_q=(PointInfo *) RelinquishMagickMemory(path_q);
+ }
+ else
+ {
+ max_strokes+=6*BezierQuantum+360;
+ path_p=(PointInfo *) ResizeQuantumMemory(path_p,max_strokes,
+ sizeof(*path_p));
+ path_q=(PointInfo *) ResizeQuantumMemory(path_q,max_strokes,
+ sizeof(*path_q));
+ }
+ if ((path_p == (PointInfo *) NULL) || (path_q == (PointInfo *) NULL))
+ {
+ if (path_p != (PointInfo *) NULL)
+ path_p=(PointInfo *) RelinquishMagickMemory(path_p);
+ if (path_q != (PointInfo *) NULL)
+ path_q=(PointInfo *) RelinquishMagickMemory(path_q);
+ polygon_primitive=(PrimitiveInfo *)
+ RelinquishMagickMemory(polygon_primitive);
+ return((PrimitiveInfo *) NULL);
+ }
}
dot_product=dx.q*dy.p-dx.p*dy.q;
if (dot_product <= 0.0)
theta.p=atan2(box_q[1].y-center.y,box_q[1].x-center.x);
theta.q=atan2(box_q[2].y-center.y,box_q[2].x-center.x);
if (theta.q < theta.p)
- theta.q+=(double) (2.0*MagickPI);
+ theta.q+=2.0*MagickPI;
arc_segments=(size_t) ceil((double) ((theta.q-theta.p)/
(2.0*sqrt((double) (1.0/mid)))));
path_q[q].x=box_q[1].x;
theta.p=atan2(box_p[1].y-center.y,box_p[1].x-center.x);
theta.q=atan2(box_p[2].y-center.y,box_p[2].x-center.x);
if (theta.p < theta.q)
- theta.p+=(double) (2.0*MagickPI);
+ theta.p+=2.0*MagickPI;
arc_segments=(size_t) ceil((double) ((theta.p-theta.q)/
(2.0*sqrt((double) (1.0/mid)))));
path_p[p++]=box_p[1];