% %
% %
% Software Design %
-% John Cristy %
+% Cristy %
% July 1998 %
% %
% %
-% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2015 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 %
const double,const MagickBooleanType,const MagickBooleanType),
TraceBezier(PrimitiveInfo *,const size_t),
TraceCircle(PrimitiveInfo *,const PointInfo,const PointInfo),
- TraceEllipse(PrimitiveInfo *,const PointInfo,const PointInfo,const PointInfo),
+ TraceEllipse(PrimitiveInfo *,const PointInfo,const PointInfo,
+ const PointInfo),
TraceLine(PrimitiveInfo *,const PointInfo,const PointInfo),
TraceRectangle(PrimitiveInfo *,const PointInfo,const PointInfo),
TraceRoundRectangle(PrimitiveInfo *,const PointInfo,const PointInfo,
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
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;
next_direction=((path_info[i].point.y > point.y) ||
((path_info[i].point.y == point.y) &&
(path_info[i].point.x > point.x))) ? 1 : -1;
- if ((direction != 0) && (direction != next_direction))
+ if ((points != (PointInfo *) NULL) && (direction != 0) &&
+ (direction != next_direction))
{
/*
New edge.
*/
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;
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);
}
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)
{
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;
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);
}
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);
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);
{
offset-=length;
n++;
- length=scale*(draw_info->dash_pattern[n]+(n == 0 ? -0.5 : 0.5));
+ length=scale*(draw_info->dash_pattern[n]+0.5);
continue;
}
if (offset < length)
current;
char
- key[2*MaxTextExtent],
- keyword[MaxTextExtent],
- geometry[MaxTextExtent],
- name[MaxTextExtent],
- pattern[MaxTextExtent],
+ key[2*MagickPathExtent],
+ keyword[MagickPathExtent],
+ geometry[MagickPathExtent],
+ name[MagickPathExtent],
+ pattern[MagickPathExtent],
*primitive,
*token;
PointInfo
point;
- PixelInfo
- start_color;
-
PrimitiveInfo
*primitive_info;
size_t
length,
- number_points;
+ number_points,
+ number_stops;
ssize_t
j,
k,
n;
+ StopInfo
+ *stops;
+
/*
Ensure the annotation info is valid.
*/
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[n]->viewbox.height=image->rows;
}
token=AcquireString(primitive);
- (void) QueryColorCompliance("#000000",AllCompliance,&start_color,
- exception);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
status=MagickTrue;
affine.ty=StringToDouble(token,(char **) NULL);
break;
}
+ if (LocaleCompare("alpha",keyword) == 0)
+ {
+ primitive_type=AlphaPrimitive;
+ break;
+ }
if (LocaleCompare("arc",keyword) == 0)
{
primitive_type=ArcPrimitive;
graphic_context[n]->decorate=(DecorationType) decorate;
break;
}
+ if (LocaleCompare("density",keyword) == 0)
+ {
+ GetMagickToken(q,&q,token);
+ (void) CloneString(&graphic_context[n]->density,token);
+ break;
+ }
+ if (LocaleCompare("direction",keyword) == 0)
+ {
+ ssize_t
+ direction;
+
+ GetMagickToken(q,&q,token);
+ direction=ParseCommandOption(MagickDirectionOptions,MagickFalse,
+ token);
+ if (direction == -1)
+ status=MagickFalse;
+ else
+ graphic_context[n]->direction=(DirectionType) direction;
+ break;
+ }
status=MagickFalse;
break;
}
if (LocaleCompare("fill",keyword) == 0)
{
GetMagickToken(q,&q,token);
- (void) FormatLocaleString(pattern,MaxTextExtent,"%s",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);
else
{
- double
- alpha;
-
- alpha=graphic_context[n]->fill.alpha;
status&=QueryColorCompliance(token,AllCompliance,
&graphic_context[n]->fill,exception);
- graphic_context[n]->fill.alpha=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);
factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
}
if (LocaleCompare("font-weight",keyword) == 0)
{
+ ssize_t
+ weight;
+
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;
+ weight=ParseCommandOption(MagickWeightOptions,MagickFalse,
+ token);
+ if (weight == -1)
+ weight=StringToUnsignedLong(token);
+ graphic_context[n]->weight=(size_t) weight;
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 (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("clip-path",token) == 0)
{
char
- name[MaxTextExtent];
+ name[MagickPathExtent];
GetMagickToken(q,&q,token);
- (void) FormatLocaleString(name,MaxTextExtent,"%s",token);
+ (void) FormatLocaleString(name,MagickPathExtent,"%s",token);
for (p=q; *q != '\0'; )
{
GetMagickToken(q,&q,token);
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);
+ (void) CopyMagickString(name,token,MagickPathExtent);
GetMagickToken(q,&q,token);
- (void) CopyMagickString(type,token,MaxTextExtent);
+ (void) CopyMagickString(type,token,MagickPathExtent);
GetMagickToken(q,&q,token);
segment.x1=StringToDouble(token,(char **) NULL);
GetMagickToken(q,&q,token);
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;
GetMagickToken(q,&q,token);
- (void) CopyMagickString(name,token,MaxTextExtent);
+ (void) CopyMagickString(name,token,MagickPathExtent);
GetMagickToken(q,&q,token);
bounds.x=(ssize_t) ceil(StringToDouble(token,(char **) NULL)-
0.5);
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,
+ (void) FormatLocaleString(key,MagickPathExtent,"%s-geometry",name);
+ (void) FormatLocaleString(geometry,MagickPathExtent,
"%.20gx%.20g%+.20g%+.20g",(double) bounds.width,(double)
bounds.height,(double) bounds.x,(double) bounds.y);
(void) SetImageArtifact(image,key,geometry);
PixelInfo
stop_color;
+ 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;
+ }
GetMagickToken(q,&q,token);
(void) QueryColorCompliance(token,AllCompliance,&stop_color,
exception);
- (void) GradientImage(image,LinearGradient,ReflectSpread,
- &start_color,&stop_color,exception);
- start_color=stop_color;
+ stops[number_stops-1].color=stop_color;
GetMagickToken(q,&q,token);
+ stops[number_stops-1].offset=StringToDouble(token,(char **) NULL);
break;
}
if (LocaleCompare("stroke",keyword) == 0)
{
GetMagickToken(q,&q,token);
- (void) FormatLocaleString(pattern,MaxTextExtent,"%s",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);
else
{
- double
- alpha;
-
- alpha=graphic_context[n]->stroke.alpha;
status&=QueryColorCompliance(token,AllCompliance,
&graphic_context[n]->stroke,exception);
- graphic_context[n]->stroke.alpha=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 (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);
}
case RoundRectanglePrimitive:
{
- length*=5+8*BezierQuantum;
+ double
+ alpha,
+ beta,
+ radius;
+
+ 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;
break;
}
case BezierPrimitive:
i=(ssize_t) (j+TracePath(primitive_info+j,token));
break;
}
+ case AlphaPrimitive:
case ColorPrimitive:
- case MattePrimitive:
{
ssize_t
method;
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) <= MagickEpsilon)
+ 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;
}
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);
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);
if (polygon_info == (PolygonInfo **) NULL)
return(MagickFalse);
+DisableMSCWarning(4127)
if (0)
DrawBoundingRectangles(image,draw_info,polygon_info[0],exception);
+RestoreMSCWarning
if (image->debug != MagickFalse)
(void) LogMagickEvent(DrawEvent,GetMagickModule()," begin draw-polygon");
fill=(primitive_info->method == FillToBorderMethod) ||
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;
*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);
+ (void) 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();
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,
+ 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);
+ (void) 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);
+ (void) 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:
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);
+ 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;
+ register ssize_t
+ x;
+
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
exception);
if (q == (Quantum *) NULL)
continue;
}
(void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelInfoPixel(image,&pixel,q);
+ 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
for (x=0; x < (ssize_t) image->columns; x++)
{
(void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelInfoPixel(image,&pixel,q);
+ 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;
+ GetPixelInfo(image,&pixel);
(void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
+ SetPixelViaPixelInfo(image,&pixel,q);
(void) SyncCacheViewAuthenticPixels(image_view,exception);
break;
}
register Quantum
*restrict q;
- register ssize_t
- x;
-
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
exception);
if (q == (Quantum *) NULL)
continue;
}
(void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
+ 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
for (x=0; x < (ssize_t) image->columns; x++)
{
(void) GetFillColor(draw_info,x,y,&pixel,exception);
- SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
+ 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);
((y1 != 0L) && (y1 != (ssize_t) composite_image->rows)))
{
char
- geometry[MaxTextExtent];
+ geometry[MagickPathExtent];
/*
Resize image.
*/
- (void) FormatLocaleString(geometry,MaxTextExtent,"%gx%g!",
+ (void) FormatLocaleString(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);
}
- 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;
+ (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 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
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,
exception);
- (void) QueryColorCompliance("#FFFF",AllCompliance,&draw_info->stroke,
+ (void) QueryColorCompliance("#0000",AllCompliance,&draw_info->stroke,
exception);
draw_info->stroke_width=1.0;
draw_info->alpha=OpaqueAlpha;
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 (clone_info->pointsize != 0.0)
+ 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,(char **) NULL);
+ option=GetImageOption(clone_info,"interword-spacing");
+ if (option != (const char *) NULL)
+ draw_info->interword_spacing=StringToDouble(option,(char **) NULL);
+ option=GetImageOption(clone_info,"kerning");
+ if (option != (const char *) NULL)
+ draw_info->kerning=StringToDouble(option,(char **) NULL);
+ 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,(char **) NULL);
+ 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=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
/*
static size_t TracePath(PrimitiveInfo *primitive_info,const char *path)
{
char
- token[MaxTextExtent];
+ token[MagickPathExtent];
const char
*p;
y;
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;
primitive_type=primitive_info->primitive;
}
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];
}
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];
static inline double DrawEpsilonReciprocal(const double x)
{
-#define DrawEpsilon ((double) 1.0e-10)
+#define DrawEpsilon (1.0e-6)
- 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));
+ double sign = x < 0.0 ? -1.0 : 1.0;
+ return((sign*x) >= DrawEpsilon ? 1.0/x : sign*(1.0/DrawEpsilon));
}
static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,