]> granicus.if.org Git - imagemagick/blobdiff - magick/draw.c
(no commit message)
[imagemagick] / magick / draw.c
index d39ccf69af3a5ed5b676e92da09fa2efc4c40516..c79c0e0f5fd2f4ab3a836e984671eed540122d50 100644 (file)
@@ -18,7 +18,7 @@
 %                                 July 1998                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2011 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  %
@@ -99,16 +99,16 @@ typedef struct _EdgeInfo
   PointInfo
     *points;
 
-  unsigned long
+  size_t
     number_points;
 
-  long
+  ssize_t
     direction;
 
   MagickBooleanType
     ghostline;
 
-  unsigned long
+  size_t
     highwater;
 } EdgeInfo;
 
@@ -127,7 +127,7 @@ typedef struct _PolygonInfo
   EdgeInfo
     *edges;
 
-  unsigned long
+  size_t
     number_edges;
 } PolygonInfo;
 
@@ -158,21 +158,21 @@ static MagickBooleanType
 static PrimitiveInfo
   *TraceStrokePolygon(const DrawInfo *,const PrimitiveInfo *);
 
-static unsigned long
+static size_t
   TracePath(PrimitiveInfo *,const char *);
 
 static void
   TraceArc(PrimitiveInfo *,const PointInfo,const PointInfo,const PointInfo),
   TraceArcPath(PrimitiveInfo *,const PointInfo,const PointInfo,const PointInfo,
     const MagickRealType,const MagickBooleanType,const MagickBooleanType),
-  TraceBezier(PrimitiveInfo *,const unsigned long),
+  TraceBezier(PrimitiveInfo *,const size_t),
   TraceCircle(PrimitiveInfo *,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,
     PointInfo),
-  TraceSquareLinecap(PrimitiveInfo *,const unsigned long,const MagickRealType);
+  TraceSquareLinecap(PrimitiveInfo *,const size_t,const MagickRealType);
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -197,7 +197,7 @@ MagickExport DrawInfo *AcquireDrawInfo(void)
   DrawInfo
     *draw_info;
 
-  draw_info=(DrawInfo *) AcquireAlignedMemory(1,sizeof(*draw_info));
+  draw_info=(DrawInfo *) AcquireMagickMemory(sizeof(*draw_info));
   if (draw_info == (DrawInfo *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   GetDrawInfo((ImageInfo *) NULL,draw_info);
@@ -237,7 +237,7 @@ MagickExport DrawInfo *CloneDrawInfo(const ImageInfo *image_info,
   DrawInfo
     *clone_info;
 
-  clone_info=(DrawInfo *) AcquireAlignedMemory(1,sizeof(*clone_info));
+  clone_info=(DrawInfo *) AcquireMagickMemory(sizeof(*clone_info));
   if (clone_info == (DrawInfo *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   GetDrawInfo(image_info,clone_info);
@@ -290,6 +290,7 @@ MagickExport DrawInfo *CloneDrawInfo(const ImageInfo *image_info,
   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;
   if (draw_info->density != (char *) NULL)
     (void) CloneString(&clone_info->density,draw_info->density);
   clone_info->align=draw_info->align;
@@ -299,7 +300,7 @@ MagickExport DrawInfo *CloneDrawInfo(const ImageInfo *image_info,
     (void) CloneString(&clone_info->server_name,draw_info->server_name);
   if (draw_info->dash_pattern != (double *) NULL)
     {
-      register long
+      register ssize_t
         x;
 
       for (x=0; draw_info->dash_pattern[x] != 0.0; x++) ;
@@ -314,7 +315,7 @@ MagickExport DrawInfo *CloneDrawInfo(const ImageInfo *image_info,
   clone_info->gradient=draw_info->gradient;
   if (draw_info->gradient.stops != (StopInfo *) NULL)
     {
-      unsigned long
+      size_t
         number_stops;
 
       number_stops=clone_info->gradient.number_stops;
@@ -407,39 +408,40 @@ static void LogPolygonInfo(const PolygonInfo *polygon_info)
   register EdgeInfo
     *p;
 
-  register long
+  register ssize_t
     i,
     j;
 
   (void) LogMagickEvent(DrawEvent,GetMagickModule(),"    begin active-edge");
   p=polygon_info->edges;
-  for (i=0; i < (long) polygon_info->number_edges; i++)
+  for (i=0; i < (ssize_t) polygon_info->number_edges; i++)
   {
-    (void) LogMagickEvent(DrawEvent,GetMagickModule(),"      edge %lu:",i);
+    (void) LogMagickEvent(DrawEvent,GetMagickModule(),"      edge %.20g:",
+      (double) i);
     (void) LogMagickEvent(DrawEvent,GetMagickModule(),"      direction: %s",
       p->direction != MagickFalse ? "down" : "up");
     (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 < (long) p->number_points; j++)
-      (void) LogMagickEvent(DrawEvent,GetMagickModule(),"        %g,%g",
+    for (j=0; j < (ssize_t) p->number_points; j++)
+      (void) LogMagickEvent(DrawEvent,GetMagickModule(),"        %g %g",
         p->points[j].x,p->points[j].y);
     p++;
   }
   (void) LogMagickEvent(DrawEvent,GetMagickModule(),"    end active-edge");
 }
 
-static void ReversePoints(PointInfo *points,const unsigned long number_points)
+static void ReversePoints(PointInfo *points,const size_t number_points)
 {
   PointInfo
     point;
 
-  register long
+  register ssize_t
     i;
 
-  for (i=0; i < (long) (number_points >> 1); i++)
+  for (i=0; i < (ssize_t) (number_points >> 1); i++)
   {
     point=points[i];
     points[i]=points[number_points-(i+1)];
@@ -464,14 +466,14 @@ static PolygonInfo *ConvertPathToPolygon(
   SegmentInfo
     bounds;
 
-  register long
+  register ssize_t
     i,
     n;
 
   MagickBooleanType
     ghostline;
 
-  unsigned long
+  size_t
     edge,
     number_edges,
     number_points;
@@ -479,7 +481,7 @@ static PolygonInfo *ConvertPathToPolygon(
   /*
     Convert a path to the more efficient sorted rendering form.
   */
-  polygon_info=(PolygonInfo *) AcquireAlignedMemory(1,sizeof(*polygon_info));
+  polygon_info=(PolygonInfo *) AcquireMagickMemory(sizeof(*polygon_info));
   if (polygon_info == (PolygonInfo *) NULL)
     return((PolygonInfo *) NULL);
   number_edges=16;
@@ -514,13 +516,13 @@ static PolygonInfo *ConvertPathToPolygon(
                 if (polygon_info->edges == (EdgeInfo *) NULL)
                   return((PolygonInfo *) NULL);
               }
-            polygon_info->edges[edge].number_points=(unsigned long) n;
+            polygon_info->edges[edge].number_points=(size_t) n;
             polygon_info->edges[edge].scanline=(-1.0);
             polygon_info->edges[edge].highwater=0;
             polygon_info->edges[edge].ghostline=ghostline;
-            polygon_info->edges[edge].direction=(long) (direction > 0);
+            polygon_info->edges[edge].direction=(ssize_t) (direction > 0);
             if (direction < 0)
-              ReversePoints(points,(unsigned long) n);
+              ReversePoints(points,(size_t) n);
             polygon_info->edges[edge].points=points;
             polygon_info->edges[edge].bounds=bounds;
             polygon_info->edges[edge].bounds.y1=points[0].y;
@@ -567,13 +569,13 @@ static PolygonInfo *ConvertPathToPolygon(
             if (polygon_info->edges == (EdgeInfo *) NULL)
               return((PolygonInfo *) NULL);
           }
-        polygon_info->edges[edge].number_points=(unsigned long) n;
+        polygon_info->edges[edge].number_points=(size_t) n;
         polygon_info->edges[edge].scanline=(-1.0);
         polygon_info->edges[edge].highwater=0;
         polygon_info->edges[edge].ghostline=ghostline;
-        polygon_info->edges[edge].direction=(long) (direction > 0);
+        polygon_info->edges[edge].direction=(ssize_t) (direction > 0);
         if (direction < 0)
-          ReversePoints(points,(unsigned long) n);
+          ReversePoints(points,(size_t) n);
         polygon_info->edges[edge].points=points;
         polygon_info->edges[edge].bounds=bounds;
         polygon_info->edges[edge].bounds.y1=points[0].y;
@@ -593,7 +595,7 @@ static PolygonInfo *ConvertPathToPolygon(
     direction=next_direction;
     if (points == (PointInfo *) NULL)
       continue;
-    if (n == (long) number_points)
+    if (n == (ssize_t) number_points)
       {
         number_points<<=1;
         points=(PointInfo *) ResizeQuantumMemory(points,(size_t) number_points,
@@ -624,13 +626,13 @@ static PolygonInfo *ConvertPathToPolygon(
               if (polygon_info->edges == (EdgeInfo *) NULL)
                 return((PolygonInfo *) NULL);
             }
-          polygon_info->edges[edge].number_points=(unsigned long) n;
+          polygon_info->edges[edge].number_points=(size_t) n;
           polygon_info->edges[edge].scanline=(-1.0);
           polygon_info->edges[edge].highwater=0;
           polygon_info->edges[edge].ghostline=ghostline;
-          polygon_info->edges[edge].direction=(long) (direction > 0);
+          polygon_info->edges[edge].direction=(ssize_t) (direction > 0);
           if (direction < 0)
-            ReversePoints(points,(unsigned long) n);
+            ReversePoints(points,(size_t) n);
           polygon_info->edges[edge].points=points;
           polygon_info->edges[edge].bounds=bounds;
           polygon_info->edges[edge].bounds.y1=points[0].y;
@@ -686,7 +688,7 @@ static void LogPathInfo(const PathInfo *path_info)
   (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" :
       "?");
@@ -696,10 +698,6 @@ static void LogPathInfo(const PathInfo *path_info)
 static PathInfo *ConvertPrimitiveToPath(
   const DrawInfo *magick_unused(draw_info),const PrimitiveInfo *primitive_info)
 {
-  long
-    coordinates,
-    start;
-
   PathInfo
     *path_info;
 
@@ -710,10 +708,14 @@ static PathInfo *ConvertPrimitiveToPath(
     p,
     q;
 
-  register long
+  register ssize_t
     i,
     n;
 
+  ssize_t
+    coordinates,
+    start;
+
   /*
     Converts a PrimitiveInfo structure into a vector path structure.
   */
@@ -745,7 +747,7 @@ static PathInfo *ConvertPrimitiveToPath(
     code=LineToCode;
     if (coordinates <= 0)
       {
-        coordinates=(long) primitive_info[i].coordinates;
+        coordinates=(ssize_t) primitive_info[i].coordinates;
         p=primitive_info[i].point;
         start=n;
         code=MoveToCode;
@@ -868,7 +870,7 @@ MagickExport DrawInfo *DestroyDrawInfo(DrawInfo *draw_info)
 %
 %  The format of the DestroyEdge method is:
 %
-%      long DestroyEdge(PolygonInfo *polygon_info,const int edge)
+%      ssize_t DestroyEdge(PolygonInfo *polygon_info,const int edge)
 %
 %  A description of each parameter follows:
 %
@@ -877,8 +879,8 @@ MagickExport DrawInfo *DestroyDrawInfo(DrawInfo *draw_info)
 %    o edge: the polygon edge number to destroy.
 %
 */
-static unsigned long DestroyEdge(PolygonInfo *polygon_info,
-  const unsigned long edge)
+static size_t DestroyEdge(PolygonInfo *polygon_info,
+  const size_t edge)
 {
   assert(edge < polygon_info->number_edges);
   polygon_info->edges[edge].points=(PointInfo *) RelinquishMagickMemory(
@@ -914,10 +916,10 @@ static unsigned long DestroyEdge(PolygonInfo *polygon_info,
 */
 static PolygonInfo *DestroyPolygonInfo(PolygonInfo *polygon_info)
 {
-  register long
+  register ssize_t
     i;
 
-  for (i=0; i < (long) polygon_info->number_edges; i++)
+  for (i=0; i < (ssize_t) polygon_info->number_edges; i++)
     polygon_info->edges[i].points=(PointInfo *)
       RelinquishMagickMemory(polygon_info->edges[i].points);
   polygon_info->edges=(EdgeInfo *) RelinquishMagickMemory(polygon_info->edges);
@@ -997,7 +999,7 @@ static SegmentInfo AffineEdge(const Image *image,const AffineMatrix *affine,
           inverse_edge.x2=x;
       }
     else
-      if ((z < 0.0) || ((unsigned long) floor(z+0.5) >= image->columns))
+      if ((z < 0.0) || ((size_t) floor(z+0.5) >= image->columns))
         {
           inverse_edge.x2=edge->x1;
           return(inverse_edge);
@@ -1030,7 +1032,7 @@ static SegmentInfo AffineEdge(const Image *image,const AffineMatrix *affine,
           inverse_edge.x2=x;
       }
     else
-      if ((z < 0.0) || ((unsigned long) floor(z+0.5) >= image->rows))
+      if ((z < 0.0) || ((size_t) floor(z+0.5) >= image->rows))
         {
           inverse_edge.x2=edge->x2;
           return(inverse_edge);
@@ -1058,7 +1060,7 @@ static AffineMatrix InverseAffineMatrix(const AffineMatrix *affine)
   return(inverse_affine);
 }
 
-static inline long MagickAbsoluteValue(const long x)
+static inline ssize_t MagickAbsoluteValue(const ssize_t x)
 {
   if (x < 0)
     return(-x);
@@ -1092,9 +1094,6 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
   ExceptionInfo
     *exception;
 
-  long
-    y;
-
   MagickBooleanType
     status;
 
@@ -1107,15 +1106,15 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
     max,
     point;
 
-  register long
+  register ssize_t
     i;
 
-  ResampleFilter
-    **restrict resample_filter;
-
   SegmentInfo
     edge;
 
+  ssize_t
+    y;
+
   /*
     Determine bounding box.
   */
@@ -1166,18 +1165,13 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
   inverse_affine=InverseAffineMatrix(affine);
   GetMagickPixelPacket(image,&zero);
   exception=(&image->exception);
-  resample_filter=AcquireResampleFilterThreadSet(source,
-    UndefinedVirtualPixelMethod,MagickTrue,exception);
   image_view=AcquireCacheView(image);
   source_view=AcquireCacheView(source);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(dynamic,4) shared(status)
 #endif
-  for (y=(long) ceil(edge.y1-0.5); y <= (long) floor(edge.y2+0.5); y++)
+  for (y=(ssize_t) ceil(edge.y1-0.5); y <= (ssize_t) floor(edge.y2+0.5); y++)
   {
-    long
-      x_offset;
-
     MagickPixelPacket
       composite,
       pixel;
@@ -1188,8 +1182,7 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
     register IndexPacket
       *restrict indexes;
 
-    register long
-      id,
+    register ssize_t
       x;
 
     register PixelPacket
@@ -1198,26 +1191,29 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
     SegmentInfo
       inverse_edge;
 
+    ssize_t
+      x_offset;
+
     inverse_edge=AffineEdge(source,&inverse_affine,(double) y,&edge);
     if (inverse_edge.x2 < inverse_edge.x1)
       continue;
-    q=GetCacheViewAuthenticPixels(image_view,(long) ceil(inverse_edge.x1-0.5),y,
-      (unsigned long) ((long) floor(inverse_edge.x2+0.5)-(long) floor(
+    q=GetCacheViewAuthenticPixels(image_view,(ssize_t) ceil(inverse_edge.x1-
+      0.5),y,(size_t) ((ssize_t) floor(inverse_edge.x2+0.5)-(ssize_t) floor(
       inverse_edge.x1+0.5)+1),1,exception);
     if (q == (PixelPacket *) NULL)
       continue;
-    id=GetOpenMPThreadId();
     indexes=GetCacheViewAuthenticIndexQueue(image_view);
     pixel=zero;
     composite=zero;
     x_offset=0;
-    for (x=(long) ceil(inverse_edge.x1-0.5); x <= (long) floor(inverse_edge.x2+0.5); x++)
+    for (x=(ssize_t) ceil(inverse_edge.x1-0.5); x <= (ssize_t) floor(inverse_edge.x2+0.5); x++)
     {
       point.x=(double) x*inverse_affine.sx+y*inverse_affine.ry+
         inverse_affine.tx;
       point.y=(double) x*inverse_affine.rx+y*inverse_affine.sy+
         inverse_affine.ty;
-      (void) ResamplePixelColor(resample_filter[id],point.x,point.y,&pixel);
+      (void) InterpolateMagickPixelPacket(source,source_view,
+        UndefinedInterpolatePixel,point.x,point.y,&pixel,exception);
       SetMagickPixelPacket(image,q,indexes+x_offset,&composite);
       MagickPixelCompositeOver(&pixel,pixel.opacity,&composite,
         composite.opacity,&composite);
@@ -1228,7 +1224,6 @@ MagickExport MagickBooleanType DrawAffineImage(Image *image,
     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
       status=MagickFalse;
   }
-  resample_filter=DestroyResampleFilterThreadSet(resample_filter);
   source_view=DestroyCacheView(source_view);
   image_view=DestroyCacheView(image_view);
   return(status);
@@ -1268,9 +1263,6 @@ static void DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
   DrawInfo
     *clone_info;
 
-  long
-    coordinates;
-
   MagickRealType
     mid;
 
@@ -1282,12 +1274,15 @@ static void DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
   PrimitiveInfo
     primitive_info[6];
 
-  register long
+  register ssize_t
     i;
 
   SegmentInfo
     bounds;
 
+  ssize_t
+    coordinates;
+
   clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
   (void) QueryColorDatabase("#0000",&clone_info->fill,&image->exception);
   resolution.x=DefaultResolution;
@@ -1315,7 +1310,7 @@ static void DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
   if (polygon_info != (PolygonInfo *) NULL)
     {
       bounds=polygon_info->edges[0].bounds;
-      for (i=1; i < (long) polygon_info->number_edges; i++)
+      for (i=1; i < (ssize_t) polygon_info->number_edges; i++)
       {
         if (polygon_info->edges[i].bounds.x1 < (double) bounds.x1)
           bounds.x1=polygon_info->edges[i].bounds.x1;
@@ -1338,7 +1333,7 @@ static void DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
       bounds.y2+=mid;
       bounds.y2=bounds.y2 < 0.0 ? 0.0 : bounds.y2 >= (double)
         image->rows ? (double) image->rows-1 : bounds.y2;
-      for (i=0; i < (long) polygon_info->number_edges; i++)
+      for (i=0; i < (ssize_t) polygon_info->number_edges; i++)
       {
         if (polygon_info->edges[i].direction != 0)
           (void) QueryColorDatabase("red",&clone_info->stroke,
@@ -1353,7 +1348,7 @@ static void DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
         primitive_info[0].primitive=RectanglePrimitive;
         TraceRectangle(primitive_info,start,end);
         primitive_info[0].method=ReplaceMethod;
-        coordinates=(long) primitive_info[0].coordinates;
+        coordinates=(ssize_t) primitive_info[0].coordinates;
         primitive_info[coordinates].primitive=UndefinedPrimitive;
         (void) DrawPrimitive(image,clone_info,primitive_info);
       }
@@ -1366,7 +1361,7 @@ static void DrawBoundingRectangles(Image *image,const DrawInfo *draw_info,
   primitive_info[0].primitive=RectanglePrimitive;
   TraceRectangle(primitive_info,start,end);
   primitive_info[0].method=ReplaceMethod;
-  coordinates=(long) primitive_info[0].coordinates;
+  coordinates=(ssize_t) primitive_info[0].coordinates;
   primitive_info[coordinates].primitive=UndefinedPrimitive;
   (void) DrawPrimitive(image,clone_info,primitive_info);
   clone_info=DestroyDrawInfo(clone_info);
@@ -1419,7 +1414,7 @@ MagickExport MagickBooleanType DrawClipPath(Image *image,
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(draw_info != (const DrawInfo *) NULL);
-  (void) FormatMagickString(clip_mask,MaxTextExtent,"%s",name);
+  (void) FormatLocaleString(clip_mask,MaxTextExtent,"%s",name);
   value=GetImageArtifact(image,clip_mask);
   if (value == (const char *) NULL)
     return(MagickFalse);
@@ -1489,10 +1484,6 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
   DrawInfo
     *clone_info;
 
-  long
-    j,
-    n;
-
   MagickRealType
     length,
     maximum_length,
@@ -1506,23 +1497,27 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
   PrimitiveInfo
     *dash_polygon;
 
-  register long
+  register ssize_t
     i;
 
   register MagickRealType
     dx,
     dy;
 
-  unsigned long
+  size_t
     number_vertices;
 
+  ssize_t
+    j,
+    n;
+
   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=(unsigned long) i;
+  number_vertices=(size_t) i;
   dash_polygon=(PrimitiveInfo *) AcquireQuantumMemory((size_t)
     (2UL*number_vertices+1UL),sizeof(*dash_polygon));
   if (dash_polygon == (PrimitiveInfo *) NULL)
@@ -1556,7 +1551,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
   status=MagickTrue;
   maximum_length=0.0;
   total_length=0.0;
-  for (i=1; i < (long) number_vertices; i++)
+  for (i=1; i < (ssize_t) number_vertices; 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;
@@ -1582,7 +1577,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
         }
       else
         {
-          if ((j+1) > (long) (2*number_vertices))
+          if ((j+1) > (ssize_t) (2*number_vertices))
             break;
           dash_polygon[j]=primitive_info[i-1];
           dash_polygon[j].point.x=(double) (primitive_info[i-1].point.x+dx*
@@ -1591,7 +1586,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
             total_length/maximum_length);
           dash_polygon[j].coordinates=1;
           j++;
-          dash_polygon[0].coordinates=(unsigned long) j;
+          dash_polygon[0].coordinates=(size_t) j;
           dash_polygon[j].primitive=UndefinedPrimitive;
           status|=DrawStrokePolygon(image,clone_info,dash_polygon);
         }
@@ -1614,7 +1609,7 @@ static MagickBooleanType DrawDashPolygon(const DrawInfo *draw_info,
       dash_polygon[j].point.y+=MagickEpsilon;
       dash_polygon[j].coordinates=1;
       j++;
-      dash_polygon[0].coordinates=(unsigned long) j;
+      dash_polygon[0].coordinates=(size_t) j;
       dash_polygon[j].primitive=UndefinedPrimitive;
       status|=DrawStrokePolygon(image,clone_info,dash_polygon);
     }
@@ -1662,7 +1657,7 @@ static inline MagickBooleanType IsPoint(const char *point)
   double
     value;
 
-  value=strtod(point,&p);
+  value=InterpretLocaleValue(point,&p);
   return((value == 0.0) && (p == point) ? MagickFalse : MagickTrue);
 }
 
@@ -1696,11 +1691,6 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
   DrawInfo
     **graphic_context;
 
-  long
-    j,
-    k,
-    n;
-
   MagickBooleanType
     proceed,
     status;
@@ -1725,7 +1715,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
   register const char
     *p;
 
-  register long
+  register ssize_t
     i,
     x;
 
@@ -1733,11 +1723,14 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
     bounds;
 
   size_t
-    length;
-
-  unsigned long
+    length,
     number_points;
 
+  ssize_t
+    j,
+    k,
+    n;
+
   /*
     Ensure the annotation info is valid.
   */
@@ -1766,7 +1759,8 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
   /*
     Allocate primitive info memory.
   */
-  graphic_context=(DrawInfo **) AcquireAlignedMemory(1,sizeof(*graphic_context));
+  graphic_context=(DrawInfo **) AcquireMagickMemory(
+    sizeof(*graphic_context));
   if (graphic_context == (DrawInfo **) NULL)
     {
       primitive=DestroyString(primitive);
@@ -1828,27 +1822,27 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("affine",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            affine.sx=StringToDouble(token);
+            affine.sx=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            affine.rx=StringToDouble(token);
+            affine.rx=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            affine.ry=StringToDouble(token);
+            affine.ry=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            affine.sy=StringToDouble(token);
+            affine.sy=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            affine.tx=StringToDouble(token);
+            affine.tx=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            affine.ty=StringToDouble(token);
+            affine.ty=InterpretLocaleValue(token,(char **) NULL);
             break;
           }
         if (LocaleCompare("arc",keyword) == 0)
@@ -1893,11 +1887,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         if (LocaleCompare("clip-rule",keyword) == 0)
           {
-            long
+            ssize_t
               fill_rule;
 
             GetMagickToken(q,&q,token);
-            fill_rule=ParseMagickOption(MagickFillRuleOptions,MagickFalse,
+            fill_rule=ParseCommandOption(MagickFillRuleOptions,MagickFalse,
               token);
             if (fill_rule == -1)
               {
@@ -1909,11 +1903,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         if (LocaleCompare("clip-units",keyword) == 0)
           {
-            long
+            ssize_t
               clip_units;
 
             GetMagickToken(q,&q,token);
-            clip_units=ParseMagickOption(MagickClipPathOptions,MagickFalse,
+            clip_units=ParseCommandOption(MagickClipPathOptions,MagickFalse,
               token);
             if (clip_units == -1)
               {
@@ -1950,11 +1944,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
       {
         if (LocaleCompare("decorate",keyword) == 0)
           {
-            long
+            ssize_t
               decorate;
 
             GetMagickToken(q,&q,token);
-            decorate=ParseMagickOption(MagickDecorateOptions,MagickFalse,
+            decorate=ParseCommandOption(MagickDecorateOptions,MagickFalse,
               token);
             if (decorate == -1)
               {
@@ -1990,7 +1984,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("fill",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            (void) FormatMagickString(pattern,MaxTextExtent,"%s",token);
+            (void) FormatLocaleString(pattern,MaxTextExtent,"%s",token);
             if (GetImageArtifact(image,pattern) != (const char *) NULL)
               (void) DrawPatternPath(image,draw_info,token,
                 &graphic_context[n]->fill_pattern);
@@ -2019,16 +2013,17 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
             GetMagickToken(q,&q,token);
             factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
             graphic_context[n]->fill.opacity=ClampToQuantum((MagickRealType)
-              QuantumRange*(1.0-factor*StringToDouble(token)));
+              QuantumRange*(1.0-factor*InterpretLocaleValue(token,
+              (char **) NULL)));
             break;
           }
         if (LocaleCompare("fill-rule",keyword) == 0)
           {
-            long
+            ssize_t
               fill_rule;
 
             GetMagickToken(q,&q,token);
-            fill_rule=ParseMagickOption(MagickFillRuleOptions,MagickFalse,
+            fill_rule=ParseCommandOption(MagickFillRuleOptions,MagickFalse,
               token);
             if (fill_rule == -1)
               {
@@ -2056,16 +2051,17 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("font-size",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->pointsize=StringToDouble(token);
+            graphic_context[n]->pointsize=InterpretLocaleValue(token,
+              (char **) NULL);
             break;
           }
         if (LocaleCompare("font-stretch",keyword) == 0)
           {
-            long
+            ssize_t
               stretch;
 
             GetMagickToken(q,&q,token);
-            stretch=ParseMagickOption(MagickStretchOptions,MagickFalse,token);
+            stretch=ParseCommandOption(MagickStretchOptions,MagickFalse,token);
             if (stretch == -1)
               {
                 status=MagickFalse;
@@ -2076,11 +2072,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         if (LocaleCompare("font-style",keyword) == 0)
           {
-            long
+            ssize_t
               style;
 
             GetMagickToken(q,&q,token);
-            style=ParseMagickOption(MagickStyleOptions,MagickFalse,token);
+            style=ParseCommandOption(MagickStyleOptions,MagickFalse,token);
             if (style == -1)
               {
                 status=MagickFalse;
@@ -2120,11 +2116,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         if (LocaleCompare("gravity",keyword) == 0)
           {
-            long
+            ssize_t
               gravity;
 
             GetMagickToken(q,&q,token);
-            gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,token);
+            gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,token);
             if (gravity == -1)
               {
                 status=MagickFalse;
@@ -2141,12 +2137,12 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
       {
         if (LocaleCompare("image",keyword) == 0)
           {
-            long
+            ssize_t
               compose;
 
             primitive_type=ImagePrimitive;
             GetMagickToken(q,&q,token);
-            compose=ParseMagickOption(MagickComposeOptions,MagickFalse,token);
+            compose=ParseCommandOption(MagickComposeOptions,MagickFalse,token);
             if (compose == -1)
               {
                 status=MagickFalse;
@@ -2158,13 +2154,15 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("interline-spacing",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->interline_spacing=StringToDouble(token);
+            graphic_context[n]->interline_spacing=InterpretLocaleValue(token,
+              (char **) NULL);
             break;
           }
         if (LocaleCompare("interword-spacing",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->interword_spacing=StringToDouble(token);
+            graphic_context[n]->interword_spacing=InterpretLocaleValue(token,
+              (char **) NULL);
             break;
           }
         status=MagickFalse;
@@ -2176,7 +2174,8 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("kerning",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->kerning=StringToDouble(token);
+            graphic_context[n]->kerning=InterpretLocaleValue(token,
+              (char **) NULL);
             break;
           }
         status=MagickFalse;
@@ -2218,7 +2217,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
             factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
             graphic_context[n]->opacity=ClampToQuantum((MagickRealType)
               QuantumRange*(1.0-((1.0-QuantumScale*graphic_context[n]->opacity)*
-              factor*StringToDouble(token))));
+              factor*InterpretLocaleValue(token,(char **) NULL))));
             graphic_context[n]->fill.opacity=graphic_context[n]->opacity;
             graphic_context[n]->stroke.opacity=graphic_context[n]->opacity;
             break;
@@ -2290,7 +2289,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
                   name[MaxTextExtent];
 
                 GetMagickToken(q,&q,token);
-                (void) FormatMagickString(name,MaxTextExtent,"%s",token);
+                (void) FormatLocaleString(name,MaxTextExtent,"%s",token);
                 for (p=q; *q != '\0'; )
                 {
                   GetMagickToken(q,&q,token);
@@ -2313,9 +2312,6 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
                   name[MaxTextExtent],
                   type[MaxTextExtent];
 
-                ElementInfo
-                  element;
-
                 SegmentInfo
                   segment;
 
@@ -2324,29 +2320,24 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
                 GetMagickToken(q,&q,token);
                 (void) CopyMagickString(type,token,MaxTextExtent);
                 GetMagickToken(q,&q,token);
-                segment.x1=StringToDouble(token);
-                element.cx=StringToDouble(token);
+                segment.x1=InterpretLocaleValue(token,(char **) NULL);
                 GetMagickToken(q,&q,token);
                 if (*token == ',')
                   GetMagickToken(q,&q,token);
-                segment.y1=StringToDouble(token);
-                element.cy=StringToDouble(token);
+                segment.y1=InterpretLocaleValue(token,(char **) NULL);
                 GetMagickToken(q,&q,token);
                 if (*token == ',')
                   GetMagickToken(q,&q,token);
-                segment.x2=StringToDouble(token);
-                element.major=StringToDouble(token);
+                segment.x2=InterpretLocaleValue(token,(char **) NULL);
                 GetMagickToken(q,&q,token);
                 if (*token == ',')
                   GetMagickToken(q,&q,token);
-                segment.y2=StringToDouble(token);
-                element.minor=StringToDouble(token);
+                segment.y2=InterpretLocaleValue(token,(char **) NULL);
                 if (LocaleCompare(type,"radial") == 0)
                   {
                     GetMagickToken(q,&q,token);
                     if (*token == ',')
                       GetMagickToken(q,&q,token);
-                    element.angle=StringToDouble(token);
                   }
                 for (p=q; *q != '\0'; )
                 {
@@ -2371,10 +2362,10 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
                 bounds.y2=graphic_context[n]->affine.rx*segment.x2+
                   graphic_context[n]->affine.sy*segment.y2+
                   graphic_context[n]->affine.ty;
-                (void) FormatMagickString(key,MaxTextExtent,"%s",name);
+                (void) FormatLocaleString(key,MaxTextExtent,"%s",name);
                 (void) SetImageArtifact(image,key,token);
-                (void) FormatMagickString(key,MaxTextExtent,"%s-geometry",name);
-                (void) FormatMagickString(geometry,MaxTextExtent,
+                (void) FormatLocaleString(key,MaxTextExtent,"%s-geometry",name);
+                (void) FormatLocaleString(geometry,MaxTextExtent,
                   "%gx%g%+.15g%+.15g",
                   MagickMax(fabs(bounds.x2-bounds.x1+1.0),1.0),
                   MagickMax(fabs(bounds.y2-bounds.y1+1.0),1.0),
@@ -2391,19 +2382,23 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
                 GetMagickToken(q,&q,token);
                 (void) CopyMagickString(name,token,MaxTextExtent);
                 GetMagickToken(q,&q,token);
-                bounds.x=(long) ceil(StringToDouble(token)-0.5);
+                bounds.x=(ssize_t) ceil(InterpretLocaleValue(token,
+                  (char **) NULL)-0.5);
                 GetMagickToken(q,&q,token);
                 if (*token == ',')
                   GetMagickToken(q,&q,token);
-                bounds.y=(long) ceil(StringToDouble(token)-0.5);
+                bounds.y=(ssize_t) ceil(InterpretLocaleValue(token,
+                  (char **) NULL)-0.5);
                 GetMagickToken(q,&q,token);
                 if (*token == ',')
                   GetMagickToken(q,&q,token);
-                bounds.width=(unsigned long) floor(StringToDouble(token)+0.5);
+                bounds.width=(size_t) floor(InterpretLocaleValue(token,
+                  (char **) NULL)+0.5);
                 GetMagickToken(q,&q,token);
                 if (*token == ',')
                   GetMagickToken(q,&q,token);
-                bounds.height=(unsigned long) floor(StringToDouble(token)+0.5);
+                bounds.height=(size_t) floor(InterpretLocaleValue(token,
+                  (char **) NULL)+0.5);
                 for (p=q; *q != '\0'; )
                 {
                   GetMagickToken(q,&q,token);
@@ -2415,12 +2410,12 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
                   break;
                 }
                 (void) CopyMagickString(token,p,(size_t) (q-p-4+1));
-                (void) FormatMagickString(key,MaxTextExtent,"%s",name);
+                (void) FormatLocaleString(key,MaxTextExtent,"%s",name);
                 (void) SetImageArtifact(image,key,token);
-                (void) FormatMagickString(key,MaxTextExtent,"%s-geometry",name);
-                (void) FormatMagickString(geometry,MaxTextExtent,
-                  "%lux%lu%+ld%+ld",bounds.width,bounds.height,bounds.x,
-                  bounds.y);
+                (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) SetImageArtifact(image,key,geometry);
                 GetMagickToken(q,&q,token);
                 break;
@@ -2460,7 +2455,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("rotate",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            angle=StringToDouble(token);
+            angle=InterpretLocaleValue(token,(char **) NULL);
             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))));
@@ -2481,24 +2476,24 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("scale",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            affine.sx=StringToDouble(token);
+            affine.sx=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            affine.sy=StringToDouble(token);
+            affine.sy=InterpretLocaleValue(token,(char **) NULL);
             break;
           }
         if (LocaleCompare("skewX",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            angle=StringToDouble(token);
+            angle=InterpretLocaleValue(token,(char **) NULL);
             affine.ry=sin(DegreesToRadians(angle));
             break;
           }
         if (LocaleCompare("skewY",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            angle=StringToDouble(token);
+            angle=InterpretLocaleValue(token,(char **) NULL);
             affine.rx=(-tan(DegreesToRadians(angle)/2.0));
             break;
           }
@@ -2518,7 +2513,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("stroke",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            (void) FormatMagickString(pattern,MaxTextExtent,"%s",token);
+            (void) FormatLocaleString(pattern,MaxTextExtent,"%s",token);
             if (GetImageArtifact(image,pattern) != (const char *) NULL)
               (void) DrawPatternPath(image,draw_info,token,
                 &graphic_context[n]->stroke_pattern);
@@ -2584,7 +2579,8 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
                   GetMagickToken(q,&q,token);
                   if (*token == ',')
                     GetMagickToken(q,&q,token);
-                  graphic_context[n]->dash_pattern[j]=StringToDouble(token);
+                  graphic_context[n]->dash_pattern[j]=InterpretLocaleValue(
+                    token,(char **) NULL);
                 }
                 if ((x & 0x01) != 0)
                   for ( ; j < (2*x); j++)
@@ -2599,16 +2595,17 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("stroke-dashoffset",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->dash_offset=StringToDouble(token);
+            graphic_context[n]->dash_offset=InterpretLocaleValue(token,
+              (char **) NULL);
             break;
           }
         if (LocaleCompare("stroke-linecap",keyword) == 0)
           {
-            long
+            ssize_t
               linecap;
 
             GetMagickToken(q,&q,token);
-            linecap=ParseMagickOption(MagickLineCapOptions,MagickFalse,token);
+            linecap=ParseCommandOption(MagickLineCapOptions,MagickFalse,token);
             if (linecap == -1)
               {
                 status=MagickFalse;
@@ -2619,11 +2616,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         if (LocaleCompare("stroke-linejoin",keyword) == 0)
           {
-            long
+            ssize_t
               linejoin;
 
             GetMagickToken(q,&q,token);
-            linejoin=ParseMagickOption(MagickLineJoinOptions,MagickFalse,token);
+            linejoin=ParseCommandOption(MagickLineJoinOptions,MagickFalse,token);
             if (linejoin == -1)
               {
                 status=MagickFalse;
@@ -2643,13 +2640,15 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
             GetMagickToken(q,&q,token);
             factor=strchr(token,'%') != (char *) NULL ? 0.01 : 1.0;
             graphic_context[n]->stroke.opacity=ClampToQuantum((MagickRealType)
-              QuantumRange*(1.0-factor*StringToDouble(token)));
+              QuantumRange*(1.0-factor*InterpretLocaleValue(token,
+              (char **) NULL)));
             break;
           }
         if (LocaleCompare("stroke-width",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->stroke_width=StringToDouble(token);
+            graphic_context[n]->stroke_width=InterpretLocaleValue(token,
+              (char **) NULL);
             break;
           }
         status=MagickFalse;
@@ -2665,11 +2664,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         if (LocaleCompare("text-align",keyword) == 0)
           {
-            long
+            ssize_t
               align;
 
             GetMagickToken(q,&q,token);
-            align=ParseMagickOption(MagickAlignOptions,MagickFalse,token);
+            align=ParseCommandOption(MagickAlignOptions,MagickFalse,token);
             if (align == -1)
               {
                 status=MagickFalse;
@@ -2680,11 +2679,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         if (LocaleCompare("text-anchor",keyword) == 0)
           {
-            long
+            ssize_t
               align;
 
             GetMagickToken(q,&q,token);
-            align=ParseMagickOption(MagickAlignOptions,MagickFalse,token);
+            align=ParseCommandOption(MagickAlignOptions,MagickFalse,token);
             if (align == -1)
               {
                 status=MagickFalse;
@@ -2710,11 +2709,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("translate",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            affine.tx=StringToDouble(token);
+            affine.tx=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            affine.ty=StringToDouble(token);
+            affine.ty=InterpretLocaleValue(token,(char **) NULL);
             break;
           }
         status=MagickFalse;
@@ -2726,23 +2725,23 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         if (LocaleCompare("viewbox",keyword) == 0)
           {
             GetMagickToken(q,&q,token);
-            graphic_context[n]->viewbox.x=(long) ceil(StringToDouble(token)-
-              0.5);
+            graphic_context[n]->viewbox.x=(ssize_t) ceil(InterpretLocaleValue(
+              token,(char **) NULL)-0.5);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            graphic_context[n]->viewbox.y=(long) ceil(StringToDouble(token)-
-              0.5);
+            graphic_context[n]->viewbox.y=(ssize_t) ceil(InterpretLocaleValue(
+              token,(char **) NULL)-0.5);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            graphic_context[n]->viewbox.width=(unsigned long) floor(
-              StringToDouble(token)+0.5);
+            graphic_context[n]->viewbox.width=(size_t) floor(
+              InterpretLocaleValue(token,(char **) NULL)+0.5);
             GetMagickToken(q,&q,token);
             if (*token == ',')
               GetMagickToken(q,&q,token);
-            graphic_context[n]->viewbox.height=(unsigned long) floor(
-              StringToDouble(token)+0.5);
+            graphic_context[n]->viewbox.height=(size_t) floor(
+              InterpretLocaleValue(token,(char **) NULL)+0.5);
             break;
           }
         status=MagickFalse;
@@ -2763,10 +2762,10 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         graphic_context[n]->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
         graphic_context[n]->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
         graphic_context[n]->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
-        graphic_context[n]->affine.tx=
-          current.sx*affine.tx+current.ry*affine.ty+current.tx;
-        graphic_context[n]->affine.ty=
-          current.rx*affine.tx+current.sy*affine.ty+current.ty;
+        graphic_context[n]->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
+          current.tx;
+        graphic_context[n]->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
+          current.ty;
       }
     if (primitive_type == UndefinedPrimitive)
       {
@@ -2790,11 +2789,11 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
       if (IsPoint(q) == MagickFalse)
         break;
       GetMagickToken(q,&q,token);
-      point.x=StringToDouble(token);
+      point.x=InterpretLocaleValue(token,(char **) NULL);
       GetMagickToken(q,&q,token);
       if (*token == ',')
         GetMagickToken(q,&q,token);
-      point.y=StringToDouble(token);
+      point.y=InterpretLocaleValue(token,(char **) NULL);
       GetMagickToken(q,(const char **) NULL,token);
       if (*token == ',')
         GetMagickToken(q,&q,token);
@@ -2803,7 +2802,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
       primitive_info[i].coordinates=0;
       primitive_info[i].method=FloodfillMethod;
       i++;
-      if (i < (long) number_points)
+      if (i < (ssize_t) number_points)
         continue;
       number_points<<=1;
       primitive_info=(PrimitiveInfo *) ResizeQuantumMemory(primitive_info,
@@ -2816,7 +2815,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         }
     }
     primitive_info[j].primitive=primitive_type;
-    primitive_info[j].coordinates=(unsigned long) x;
+    primitive_info[j].coordinates=(size_t) x;
     primitive_info[j].method=FloodfillMethod;
     primitive_info[j].text=(char *) NULL;
     /*
@@ -2826,7 +2825,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
     bounds.y1=primitive_info[j].point.y;
     bounds.x2=primitive_info[j].point.x;
     bounds.y2=primitive_info[j].point.y;
-    for (k=1; k < (long) primitive_info[j].coordinates; k++)
+    for (k=1; k < (ssize_t) primitive_info[j].coordinates; k++)
     {
       point=primitive_info[j+k].point;
       if (point.x < bounds.x1)
@@ -2851,7 +2850,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
       }
       case RoundRectanglePrimitive:
       {
-        length*=5+4*BezierQuantum;
+        length*=5+8*BezierQuantum;
         break;
       }
       case BezierPrimitive:
@@ -2876,7 +2875,8 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           double
             value;
 
-          value=strtod(s,&t);
+          value=InterpretLocaleValue(s,&t);
+          (void) value;
           if (s == t)
             {
               t++;
@@ -2884,7 +2884,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
             }
           length++;
         }
-        length=6*(3*length/2+BezierQuantum)+360+1;
+        length=3*length/2+6*BezierQuantum+360;
         break;
       }
       case CirclePrimitive:
@@ -2899,19 +2899,18 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         alpha=bounds.x2-bounds.x1;
         beta=bounds.y2-bounds.y1;
         radius=hypot((double) alpha,(double) beta);
-        length=2*((size_t) (MagickPI*radius))+6*BezierQuantum+360+1;
+        length=2*((size_t) ceil((double) MagickPI*radius))+6*BezierQuantum+360;
         break;
       }
       default:
         break;
     }
-    if ((unsigned long) (i+length) >= number_points)
+    if ((size_t) (i+length) >= number_points)
       {
         /*
           Resize based on speculative points required by primitive.
         */
-        while ((unsigned long) (i+length) >= number_points)
-          number_points<<=1;
+        number_points+=length+1;
         primitive_info=(PrimitiveInfo *) ResizeQuantumMemory(primitive_info,
           (size_t) number_points,sizeof(*primitive_info));
         if (primitive_info == (PrimitiveInfo *) NULL)
@@ -2933,7 +2932,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
             break;
           }
         TracePoint(primitive_info+j,primitive_info[j].point);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case LinePrimitive:
@@ -2945,7 +2944,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         TraceLine(primitive_info+j,primitive_info[j].point,
           primitive_info[j+1].point);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case RectanglePrimitive:
@@ -2957,7 +2956,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         TraceRectangle(primitive_info+j,primitive_info[j].point,
           primitive_info[j+1].point);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case RoundRectanglePrimitive:
@@ -2969,7 +2968,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         TraceRoundRectangle(primitive_info+j,primitive_info[j].point,
           primitive_info[j+1].point,primitive_info[j+2].point);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case ArcPrimitive:
@@ -2981,7 +2980,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         TraceArc(primitive_info+j,primitive_info[j].point,
           primitive_info[j+1].point,primitive_info[j+2].point);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case EllipsePrimitive:
@@ -2993,7 +2992,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         TraceEllipse(primitive_info+j,primitive_info[j].point,
           primitive_info[j+1].point,primitive_info[j+2].point);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case CirclePrimitive:
@@ -3005,7 +3004,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
           }
         TraceCircle(primitive_info+j,primitive_info[j].point,
           primitive_info[j+1].point);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case PolylinePrimitive:
@@ -3026,18 +3025,18 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
             break;
           }
         TraceBezier(primitive_info+j,primitive_info[j].coordinates);
-        i=(long) (j+primitive_info[j].coordinates);
+        i=(ssize_t) (j+primitive_info[j].coordinates);
         break;
       }
       case PathPrimitive:
       {
-        i=(long) (j+TracePath(primitive_info+j,token));
+        i=(ssize_t) (j+TracePath(primitive_info+j,token));
         break;
       }
       case ColorPrimitive:
       case MattePrimitive:
       {
-        long
+        ssize_t
           method;
 
         if (primitive_info[j].coordinates != 1)
@@ -3046,7 +3045,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
             break;
           }
         GetMagickToken(q,&q,token);
-        method=ParseMagickOption(MagickMethodOptions,MagickFalse,token);
+        method=ParseCommandOption(MagickMethodOptions,MagickFalse,token);
         if (method == -1)
           {
             status=MagickFalse;
@@ -3109,9 +3108,9 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
         graphic_context[n]->bounds.y2=point.y;
       if (primitive_info[i].primitive == ImagePrimitive)
         break;
+      if (i >= (ssize_t) number_points)
+        ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
     }
-    if (i >= (long) number_points)
-      ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
     if (graphic_context[n]->render != MagickFalse)
       {
         if ((n != 0) && (graphic_context[n]->clip_mask != (char *) NULL) &&
@@ -3174,7 +3173,7 @@ MagickExport MagickBooleanType DrawImage(Image *image,const DrawInfo *draw_info)
 */
 
 static inline MagickRealType GetStopColorOffset(const GradientInfo *gradient,
-  const long x,const long y)
+  const ssize_t x,const ssize_t y)
 {
   switch (gradient->type)
   {
@@ -3242,9 +3241,6 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
   ExceptionInfo
     *exception;
 
-  long
-    y;
-
   MagickBooleanType
     status;
 
@@ -3260,6 +3256,9 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
   RectangleInfo
     bounding_box;
 
+  ssize_t
+    y;
+
   /*
     Draw linear or radial gradient on image.
   */
@@ -3281,11 +3280,8 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(dynamic,4) shared(status)
 #endif
-  for (y=bounding_box.y; y < (long) bounding_box.height; y++)
+  for (y=bounding_box.y; y < (ssize_t) bounding_box.height; y++)
   {
-    long
-      j;
-
     MagickPixelPacket
       composite,
       pixel;
@@ -3297,13 +3293,16 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
     register IndexPacket
       *restrict indexes;
 
-    register long
+    register ssize_t
       i,
       x;
 
     register PixelPacket
       *restrict q;
 
+    ssize_t
+      j;
+
     if (status == MagickFalse)
       continue;
     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
@@ -3318,7 +3317,7 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
     offset=GetStopColorOffset(gradient,0,y);
     if (gradient->type != RadialGradient)
       offset/=length;
-    for (x=bounding_box.x; x < (long) bounding_box.width; x++)
+    for (x=bounding_box.x; x < (ssize_t) bounding_box.width; x++)
     {
       SetMagickPixelPacket(image,q,indexes+x,&pixel);
       switch (gradient->spread)
@@ -3326,20 +3325,20 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
         case UndefinedSpread:
         case PadSpread:
         {
-          if ((x != (long) ceil(gradient_vector->x1-0.5)) ||
-              (y != (long) ceil(gradient_vector->y1-0.5)))
+          if ((x != (ssize_t) ceil(gradient_vector->x1-0.5)) ||
+              (y != (ssize_t) ceil(gradient_vector->y1-0.5)))
             {
               offset=GetStopColorOffset(gradient,x,y);
               if (gradient->type != RadialGradient)
                 offset/=length;
             }
-          for (i=0; i < (long) gradient->number_stops; i++)
+          for (i=0; i < (ssize_t) gradient->number_stops; i++)
             if (offset < gradient->stops[i].offset)
               break;
           if ((offset < 0.0) || (i == 0))
             composite=gradient->stops[0].color;
           else
-            if ((offset > 1.0) || (i == (long) gradient->number_stops))
+            if ((offset > 1.0) || (i == (ssize_t) gradient->number_stops))
               composite=gradient->stops[gradient->number_stops-1].color;
             else
               {
@@ -3354,8 +3353,8 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
         }
         case ReflectSpread:
         {
-          if ((x != (long) ceil(gradient_vector->x1-0.5)) ||
-              (y != (long) ceil(gradient_vector->y1-0.5)))
+          if ((x != (ssize_t) ceil(gradient_vector->x1-0.5)) ||
+              (y != (ssize_t) ceil(gradient_vector->y1-0.5)))
             {
               offset=GetStopColorOffset(gradient,x,y);
               if (gradient->type != RadialGradient)
@@ -3363,17 +3362,17 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
             }
           if (offset < 0.0)
             offset=(-offset);
-          if ((long) fmod(offset,2.0) == 0)
+          if ((ssize_t) fmod(offset,2.0) == 0)
             offset=fmod(offset,1.0);
           else
             offset=1.0-fmod(offset,1.0);
-          for (i=0; i < (long) gradient->number_stops; i++)
+          for (i=0; i < (ssize_t) gradient->number_stops; i++)
             if (offset < gradient->stops[i].offset)
               break;
           if (i == 0)
             composite=gradient->stops[0].color;
           else
-            if (i == (long) gradient->number_stops)
+            if (i == (ssize_t) gradient->number_stops)
               composite=gradient->stops[gradient->number_stops-1].color;
             else
               {
@@ -3396,8 +3395,8 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
 
           antialias=MagickFalse;
           repeat=0.0;
-          if ((x != (long) ceil(gradient_vector->x1-0.5)) ||
-              (y != (long) ceil(gradient_vector->y1-0.5)))
+          if ((x != (ssize_t) ceil(gradient_vector->x1-0.5)) ||
+              (y != (ssize_t) ceil(gradient_vector->y1-0.5)))
             {
               offset=GetStopColorOffset(gradient,x,y);
               if (gradient->type == LinearGradient)
@@ -3423,13 +3422,13 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
                   offset=repeat/gradient->radius;
                 }
             }
-          for (i=0; i < (long) gradient->number_stops; i++)
+          for (i=0; i < (ssize_t) gradient->number_stops; i++)
             if (offset < gradient->stops[i].offset)
               break;
           if (i == 0)
             composite=gradient->stops[0].color;
           else
-            if (i == (long) gradient->number_stops)
+            if (i == (ssize_t) gradient->number_stops)
               composite=gradient->stops[gradient->number_stops-1].color;
             else
               {
@@ -3444,7 +3443,7 @@ MagickExport MagickBooleanType DrawGradientImage(Image *image,
                     else
                       alpha=gradient->radius-repeat;
                     i=0;
-                    j=(long) gradient->number_stops-1L;
+                    j=(ssize_t) gradient->number_stops-1L;
                   }
                 MagickPixelCompositeBlend(&gradient->stops[i].color,1.0-alpha,
                   &gradient->stops[j].color,alpha,&composite);
@@ -3518,11 +3517,11 @@ MagickExport MagickBooleanType DrawPatternPath(Image *image,
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   assert(draw_info != (const DrawInfo *) NULL);
   assert(name != (const char *) NULL);
-  (void) FormatMagickString(property,MaxTextExtent,"%s",name);
+  (void) FormatLocaleString(property,MaxTextExtent,"%s",name);
   path=GetImageArtifact(image,property);
   if (path == (const char *) NULL)
     return(MagickFalse);
-  (void) FormatMagickString(property,MaxTextExtent,"%s-geometry",name);
+  (void) FormatLocaleString(property,MaxTextExtent,"%s-geometry",name);
   geometry=GetImageArtifact(image,property);
   if (geometry == (const char *) NULL)
     return(MagickFalse);
@@ -3579,14 +3578,14 @@ MagickExport MagickBooleanType DrawPatternPath(Image *image,
 
 static PolygonInfo **DestroyPolygonThreadSet(PolygonInfo **polygon_info)
 {
-  register long
+  register ssize_t
     i;
 
   assert(polygon_info != (PolygonInfo **) NULL);
-  for (i=0; i < (long) GetOpenMPMaximumThreads(); i++)
+  for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
     if (polygon_info[i] != (PolygonInfo *) NULL)
       polygon_info[i]=DestroyPolygonInfo(polygon_info[i]);
-  polygon_info=(PolygonInfo **) RelinquishAlignedMemory(polygon_info);
+  polygon_info=(PolygonInfo **) RelinquishMagickMemory(polygon_info);
   return(polygon_info);
 }
 
@@ -3596,17 +3595,17 @@ static PolygonInfo **AcquirePolygonThreadSet(const DrawInfo *draw_info,
   PathInfo
     *restrict path_info;
 
-  register long
-    i;
-
   PolygonInfo
     **polygon_info;
 
-  unsigned long
+  register ssize_t
+    i;
+
+  size_t
     number_threads;
 
   number_threads=GetOpenMPMaximumThreads();
-  polygon_info=(PolygonInfo **) AcquireAlignedMemory(number_threads,
+  polygon_info=(PolygonInfo **) AcquireQuantumMemory(number_threads,
     sizeof(*polygon_info));
   if (polygon_info == (PolygonInfo **) NULL)
     return((PolygonInfo **) NULL);
@@ -3615,7 +3614,7 @@ static PolygonInfo **AcquirePolygonThreadSet(const DrawInfo *draw_info,
   path_info=ConvertPrimitiveToPath(draw_info,primitive_info);
   if (path_info == (PathInfo *) NULL)
     return(DestroyPolygonThreadSet(polygon_info));
-  for (i=0; i < (long) number_threads; i++)
+  for (i=0; i < (ssize_t) number_threads; i++)
   {
     polygon_info[i]=ConvertPathToPolygon(draw_info,path_info);
     if (polygon_info[i] == (PolygonInfo *) NULL)
@@ -3627,15 +3626,9 @@ static PolygonInfo **AcquirePolygonThreadSet(const DrawInfo *draw_info,
 
 static MagickRealType GetPixelOpacity(PolygonInfo *polygon_info,
   const MagickRealType mid,const MagickBooleanType fill,
-  const FillRule fill_rule,const long x,const long y,
+  const FillRule fill_rule,const double x,const double y,
   MagickRealType *stroke_opacity)
 {
-  int
-    winding_number;
-
-  long
-    j;
-
   MagickRealType
     alpha,
     beta,
@@ -3651,27 +3644,32 @@ static MagickRealType GetPixelOpacity(PolygonInfo *polygon_info,
   register const PointInfo
     *q;
 
-  register long
+  register ssize_t
     i;
 
+  ssize_t
+    j,
+    winding_number;
+
   /*
     Compute fill & stroke opacity for this (x,y) point.
   */
   *stroke_opacity=0.0;
   subpath_opacity=0.0;
   p=polygon_info->edges;
-  for (j=0; j < (long) polygon_info->number_edges; j++, p++)
+  for (j=0; j < (ssize_t) polygon_info->number_edges; j++, p++)
   {
     if (y <= (p->bounds.y1-mid-0.5))
       break;
     if (y > (p->bounds.y2+mid+0.5))
       {
-        (void) DestroyEdge(polygon_info,j);
+        (void) DestroyEdge(polygon_info,(size_t) j);
         continue;
       }
     if ((x <= (p->bounds.x1-mid-0.5)) || (x > (p->bounds.x2+mid+0.5)))
       continue;
-    for (i=MagickMax(p->highwater,1); i < (long) p->number_points; i++)
+    i=(ssize_t) MagickMax((double) p->highwater,1.0);
+    for ( ; i < (ssize_t) p->number_points; i++)
     {
       if (y <= (p->points[i-1].y-mid-0.5))
         break;
@@ -3680,7 +3678,7 @@ static MagickRealType GetPixelOpacity(PolygonInfo *polygon_info,
       if (p->scanline != y)
         {
           p->scanline=y;
-          p->highwater=i;
+          p->highwater=(size_t) i;
         }
       /*
         Compute distance between a point and an edge.
@@ -3767,7 +3765,7 @@ static MagickRealType GetPixelOpacity(PolygonInfo *polygon_info,
   */
   winding_number=0;
   p=polygon_info->edges;
-  for (j=0; j < (long) polygon_info->number_edges; j++, p++)
+  for (j=0; j < (ssize_t) polygon_info->number_edges; j++, p++)
   {
     if (y <= p->bounds.y1)
       break;
@@ -3778,7 +3776,8 @@ static MagickRealType GetPixelOpacity(PolygonInfo *polygon_info,
         winding_number+=p->direction ? 1 : -1;
         continue;
       }
-    for (i=MagickMax(p->highwater,1); i < (long) p->number_points; i++)
+    i=(ssize_t) MagickMax((double) p->highwater,1.0);
+    for ( ; i < (ssize_t) p->number_points; i++)
       if (y <= p->points[i].y)
         break;
     q=p->points+i-1;
@@ -3805,11 +3804,6 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
   ExceptionInfo
     *exception;
 
-  long
-    start,
-    stop,
-    y;
-
   MagickBooleanType
     fill,
     status;
@@ -3823,12 +3817,17 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
   register EdgeInfo
     *p;
 
-  register long
+  register ssize_t
     i;
 
   SegmentInfo
     bounds;
 
+  ssize_t
+    start,
+    stop,
+    y;
+
   /*
     Compute bounding box.
   */
@@ -3852,7 +3851,7 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
     (primitive_info->method == FloodfillMethod) ? MagickTrue : MagickFalse;
   mid=ExpandAffine(&draw_info->affine)*draw_info->stroke_width/2.0;
   bounds=polygon_info[0]->edges[0].bounds;
-  for (i=1; i < (long) polygon_info[0]->number_edges; i++)
+  for (i=1; i < (ssize_t) polygon_info[0]->number_edges; i++)
   {
     p=polygon_info[0]->edges+i;
     if (p->bounds.x1 < bounds.x1)
@@ -3865,21 +3864,21 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
       bounds.y2=p->bounds.y2;
   }
   bounds.x1-=(mid+1.0);
-  bounds.x1=bounds.x1 < 0.0 ? 0.0 : (unsigned long) ceil(bounds.x1-0.5) >=
+  bounds.x1=bounds.x1 < 0.0 ? 0.0 : (size_t) ceil(bounds.x1-0.5) >=
     image->columns ? (double) image->columns-1.0 : bounds.x1;
   bounds.y1-=(mid+1.0);
-  bounds.y1=bounds.y1 < 0.0 ? 0.0 : (unsigned long) ceil(bounds.y1-0.5) >=
+  bounds.y1=bounds.y1 < 0.0 ? 0.0 : (size_t) ceil(bounds.y1-0.5) >=
     image->rows ? (double) image->rows-1.0 : bounds.y1;
   bounds.x2+=(mid+1.0);
-  bounds.x2=bounds.x2 < 0.0 ? 0.0 : (unsigned long) floor(bounds.x2+0.5) >=
+  bounds.x2=bounds.x2 < 0.0 ? 0.0 : (size_t) floor(bounds.x2+0.5) >=
     image->columns ? (double) image->columns-1.0 : bounds.x2;
   bounds.y2+=(mid+1.0);
-  bounds.y2=bounds.y2 < 0.0 ? 0.0 : (unsigned long) floor(bounds.y2+0.5) >=
+  bounds.y2=bounds.y2 < 0.0 ? 0.0 : (size_t) floor(bounds.y2+0.5) >=
     image->rows ? (double) image->rows-1.0 : bounds.y2;
   status=MagickTrue;
   exception=(&image->exception);
-  start=(long) ceil(bounds.x1-0.5);
-  stop=(long) floor(bounds.x2+0.5);
+  start=(ssize_t) ceil(bounds.x1-0.5);
+  stop=(ssize_t) floor(bounds.x2+0.5);
   image_view=AcquireCacheView(image);
   if (primitive_info->coordinates == 1)
     {
@@ -3889,12 +3888,12 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(dynamic,4) shared(status)
 #endif
-      for (y=(long) ceil(bounds.y1-0.5); y <= (long) floor(bounds.y2+0.5); y++)
+      for (y=(ssize_t) ceil(bounds.y1-0.5); y <= (ssize_t) floor(bounds.y2+0.5); y++)
       {
         MagickBooleanType
           sync;
 
-        register long
+        register ssize_t
           x;
 
         register PixelPacket
@@ -3903,7 +3902,7 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
         if (status == MagickFalse)
           continue;
         x=start;
-        q=GetCacheViewAuthenticPixels(image_view,x,y,(unsigned long) (stop-x+1),
+        q=GetCacheViewAuthenticPixels(image_view,x,y,(size_t) (stop-x+1),
           1,exception);
         if (q == (PixelPacket *) NULL)
           {
@@ -3912,8 +3911,8 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
           }
         for ( ; x <= stop; x++)
         {
-          if ((x == (long) ceil(primitive_info->point.x-0.5)) &&
-              (y == (long) ceil(primitive_info->point.y-0.5)))
+          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,q);
           q++;
         }
@@ -3936,8 +3935,11 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(dynamic,4) shared(status)
 #endif
-  for (y=(long) ceil(bounds.y1-0.5); y <= (long) floor(bounds.y2+0.5); y++)
+  for (y=(ssize_t) ceil(bounds.y1-0.5); y <= (ssize_t) floor(bounds.y2+0.5); y++)
   {
+    const int
+      id = GetOpenMPThreadId();
+
     MagickRealType
       fill_opacity,
       stroke_opacity;
@@ -3946,30 +3948,28 @@ static MagickBooleanType DrawPolygonPrimitive(Image *image,
       fill_color,
       stroke_color;
 
-    register long
-      id,
-      x;
-
     register PixelPacket
       *restrict q;
 
+    register ssize_t
+      x;
+
     if (status == MagickFalse)
       continue;
-    q=GetCacheViewAuthenticPixels(image_view,start,y,(unsigned long) (stop-
+    q=GetCacheViewAuthenticPixels(image_view,start,y,(size_t) (stop-
       start+1),1,exception);
     if (q == (PixelPacket *) NULL)
       {
         status=MagickFalse;
         continue;
       }
-    id=GetOpenMPThreadId();
     for (x=start; x <= stop; x++)
     {
       /*
         Fill and/or stroke.
       */
       fill_opacity=GetPixelOpacity(polygon_info[id],mid,fill,
-        draw_info->fill_rule,x,y,&stroke_opacity);
+        draw_info->fill_rule,(double) x,(double) y,&stroke_opacity);
       if (draw_info->stroke_antialias == MagickFalse)
         {
           fill_opacity=fill_opacity > 0.25 ? 1.0 : 0.0;
@@ -4038,51 +4038,54 @@ static void LogPrimitiveInfo(const PrimitiveInfo *primitive_info)
       "?"
     };
 
-  long
-    coordinates,
-    y;
-
   PointInfo
     p,
     q,
     point;
 
-  register long
+  register ssize_t
     i,
     x;
 
-  x=(long) ceil(primitive_info->point.x-0.5);
-  y=(long) ceil(primitive_info->point.y-0.5);
+  ssize_t
+    coordinates,
+    y;
+
+  x=(ssize_t) ceil(primitive_info->point.x-0.5);
+  y=(ssize_t) ceil(primitive_info->point.y-0.5);
   switch (primitive_info->primitive)
   {
     case PointPrimitive:
     {
       (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-        "PointPrimitive %ld,%ld %s",x,y,methods[primitive_info->method]);
+        "PointPrimitive %.20g,%.20g %s",(double) x,(double) y,
+        methods[primitive_info->method]);
       return;
     }
     case ColorPrimitive:
     {
       (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-        "ColorPrimitive %ld,%ld %s",x,y,methods[primitive_info->method]);
+        "ColorPrimitive %.20g,%.20g %s",(double) x,(double) y,
+        methods[primitive_info->method]);
       return;
     }
     case MattePrimitive:
     {
       (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-        "MattePrimitive %ld,%ld %s",x,y,methods[primitive_info->method]);
+        "MattePrimitive %.20g,%.20g %s",(double) x,(double) y,
+        methods[primitive_info->method]);
       return;
     }
     case TextPrimitive:
     {
       (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-        "TextPrimitive %ld,%ld",x,y);
+        "TextPrimitive %.20g,%.20g",(double) x,(double) y);
       return;
     }
     case ImagePrimitive:
     {
       (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-        "ImagePrimitive %ld,%ld",x,y);
+        "ImagePrimitive %.20g,%.20g",(double) x,(double) y);
       return;
     }
     default:
@@ -4097,30 +4100,30 @@ static void LogPrimitiveInfo(const PrimitiveInfo *primitive_info)
     point=primitive_info[i].point;
     if (coordinates <= 0)
       {
-        coordinates=(long) primitive_info[i].coordinates;
+        coordinates=(ssize_t) primitive_info[i].coordinates;
         (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-          "    begin open (%ld)",coordinates);
+          "    begin open (%.20g)",(double) coordinates);
         p=point;
       }
     point=primitive_info[i].point;
     if ((fabs(q.x-point.x) > MagickEpsilon) ||
         (fabs(q.y-point.y) > MagickEpsilon))
       (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-        "      %ld: %.18g,%.18g",coordinates,point.x,point.y);
+        "      %.20g: %.18g,%.18g",(double) coordinates,point.x,point.y);
     else
       (void) LogMagickEvent(DrawEvent,GetMagickModule(),
-        "      %ld: %g,%g (duplicate)",coordinates,point.x,point.y);
+        "      %.20g: %g %g (duplicate)",(double) coordinates,point.x,point.y);
     q=point;
     coordinates--;
     if (coordinates > 0)
       continue;
     if ((fabs(p.x-point.x) > MagickEpsilon) ||
         (fabs(p.y-point.y) > MagickEpsilon))
-      (void) LogMagickEvent(DrawEvent,GetMagickModule(),"    end last (%ld)",
-        coordinates);
+      (void) LogMagickEvent(DrawEvent,GetMagickModule(),"    end last (%.20g)",
+        (double) coordinates);
     else
-      (void) LogMagickEvent(DrawEvent,GetMagickModule(),"    end open (%ld)",
-        coordinates);
+      (void) LogMagickEvent(DrawEvent,GetMagickModule(),"    end open (%.20g)",
+        (double) coordinates);
   }
 }
 
@@ -4133,29 +4136,29 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
   ExceptionInfo
     *exception;
 
-  long
-    y;
-
   MagickStatusType
     status;
 
-  register long
+  register ssize_t
     i,
     x;
 
+  ssize_t
+    y;
+
   if (image->debug != MagickFalse)
     {
       (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);
     }
   status=MagickTrue;
   exception=(&image->exception);
-  x=(long) ceil(primitive_info->point.x-0.5);
-  y=(long) ceil(primitive_info->point.y-0.5);
+  x=(ssize_t) ceil(primitive_info->point.x-0.5);
+  y=(ssize_t) ceil(primitive_info->point.y-0.5);
   image_view=AcquireCacheView(image);
   switch (primitive_info->primitive)
   {
@@ -4167,9 +4170,9 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
       PixelPacket
         *q;
 
-      if ((y < 0) || (y >= (long) image->rows))
+      if ((y < 0) || (y >= (ssize_t) image->rows))
         break;
-      if ((x < 0) || (x >= (long) image->columns))
+      if ((x < 0) || (x >= (ssize_t) image->columns))
         break;
       q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
       if (q == (PixelPacket *) NULL)
@@ -4206,7 +4209,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
             target;
 
           (void) GetOneCacheViewVirtualPixel(image_view,x,y,&target,exception);
-          for (y=0; y < (long) image->rows; y++)
+          for (y=0; y < (ssize_t) image->rows; y++)
           {
             register PixelPacket
               *restrict q;
@@ -4215,7 +4218,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
               exception);
             if (q == (PixelPacket *) NULL)
               break;
-            for (x=0; x < (long) image->columns; x++)
+            for (x=0; x < (ssize_t) image->columns; x++)
             {
               if (IsColorSimilar(image,q,&target) == MagickFalse)
                 {
@@ -4254,19 +4257,19 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
           MagickBooleanType
             sync;
 
-          for (y=0; y < (long) image->rows; y++)
+          for (y=0; y < (ssize_t) image->rows; y++)
           {
-            register long
-              x;
-
             register PixelPacket
               *restrict q;
 
+            register ssize_t
+              x;
+
             q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
               exception);
             if (q == (PixelPacket *) NULL)
               break;
-            for (x=0; x < (long) image->columns; x++)
+            for (x=0; x < (ssize_t) image->columns; x++)
             {
               (void) GetFillColor(draw_info,x,y,q);
               q++;
@@ -4299,7 +4302,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
           if (q == (PixelPacket *) NULL)
             break;
           (void) GetFillColor(draw_info,x,y,&pixel);
-          q->opacity=pixel.opacity;
+          SetOpacityPixelComponent(q,pixel.opacity);
           (void) SyncCacheViewAuthenticPixels(image_view,exception);
           break;
         }
@@ -4313,19 +4316,19 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
             target;
 
           (void) GetOneCacheViewVirtualPixel(image_view,x,y,&target,exception);
-          for (y=0; y < (long) image->rows; y++)
+          for (y=0; y < (ssize_t) image->rows; y++)
           {
-            register long
-              x;
-
             register PixelPacket
               *restrict q;
 
+            register ssize_t
+              x;
+
             q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
               exception);
             if (q == (PixelPacket *) NULL)
               break;
-            for (x=0; x < (long) image->columns; x++)
+            for (x=0; x < (ssize_t) image->columns; x++)
             {
               if (IsColorSimilar(image,q,&target) == MagickFalse)
                 {
@@ -4333,7 +4336,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
                   continue;
                 }
               (void) GetFillColor(draw_info,x,y,&pixel);
-              q->opacity=pixel.opacity;
+              SetOpacityPixelComponent(q,pixel.opacity);
               q++;
             }
             sync=SyncCacheViewAuthenticPixels(image_view,exception);
@@ -4368,22 +4371,22 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
           PixelPacket
             pixel;
 
-          for (y=0; y < (long) image->rows; y++)
+          for (y=0; y < (ssize_t) image->rows; y++)
           {
-            register long
-              x;
-
             register PixelPacket
               *restrict q;
 
+            register ssize_t
+              x;
+
             q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
               exception);
             if (q == (PixelPacket *) NULL)
               break;
-            for (x=0; x < (long) image->columns; x++)
+            for (x=0; x < (ssize_t) image->columns; x++)
             {
               (void) GetFillColor(draw_info,x,y,&pixel);
-              q->opacity=pixel.opacity;
+              SetOpacityPixelComponent(q,pixel.opacity);
               q++;
             }
             sync=SyncCacheViewAuthenticPixels(image_view,exception);
@@ -4407,7 +4410,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
         break;
       clone_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
       (void) CloneString(&clone_info->text,primitive_info->text);
-      (void) FormatMagickString(geometry,MaxTextExtent,"%+f%+f",
+      (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);
@@ -4428,13 +4431,13 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
       ImageInfo
         *clone_info;
 
-      long
-        x1,
-        y1;
-
       RectangleInfo
         geometry;
 
+      ssize_t
+        x1,
+        y1;
+
       if (primitive_info->text == (char *) NULL)
         break;
       clone_info=AcquireImageInfo();
@@ -4452,10 +4455,10 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
         break;
       (void) SetImageProgressMonitor(composite_image,(MagickProgressMonitor)
         NULL,(void *) NULL);
-      x1=(long) ceil(primitive_info[1].point.x-0.5);
-      y1=(long) ceil(primitive_info[1].point.y-0.5);
-      if (((x1 != 0L) && (x1 != (long) composite_image->columns)) ||
-          ((y1 != 0L) && (y1 != (long) composite_image->rows)))
+      x1=(ssize_t) ceil(primitive_info[1].point.x-0.5);
+      y1=(ssize_t) ceil(primitive_info[1].point.y-0.5);
+      if (((x1 != 0L) && (x1 != (ssize_t) composite_image->columns)) ||
+          ((y1 != 0L) && (y1 != (ssize_t) composite_image->rows)))
         {
           char
             geometry[MaxTextExtent];
@@ -4463,7 +4466,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
           /*
             Resize image.
           */
-          (void) FormatMagickString(geometry,MaxTextExtent,"%gx%g!",
+          (void) FormatLocaleString(geometry,MaxTextExtent,"%gx%g!",
             primitive_info[1].point.x,primitive_info[1].point.y);
           composite_image->filter=image->filter;
           (void) TransformImage(&composite_image,(char *) NULL,geometry);
@@ -4476,9 +4479,9 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
       image->gravity=draw_info->gravity;
       geometry.x=x;
       geometry.y=y;
-      (void) FormatMagickString(composite_geometry,MaxTextExtent,
-        "%lux%lu%+ld%+ld",composite_image->columns,composite_image->rows,
-        geometry.x,geometry.y);
+      (void) FormatLocaleString(composite_geometry,MaxTextExtent,
+        "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,(double)
+        composite_image->rows,(double) geometry.x,(double) geometry.y);
       (void) ParseGravityGeometry(image,composite_geometry,&geometry,
         &image->exception);
       affine=draw_info->affine;
@@ -4536,7 +4539,7 @@ MagickExport MagickBooleanType DrawPrimitive(Image *image,
             (primitive_info[i-1].point.x == primitive_info[0].point.x) &&
             (primitive_info[i-1].point.y == primitive_info[0].point.y) ?
             MagickTrue : MagickFalse;
-          i=(long) primitive_info[0].coordinates;
+          i=(ssize_t) primitive_info[0].coordinates;
           if ((((draw_info->linecap == RoundCap) ||
                 (closed_path != MagickFalse)) &&
                (draw_info->linejoin == RoundJoin)) ||
@@ -4599,7 +4602,7 @@ static void DrawRoundLinecap(Image *image,const DrawInfo *draw_info,
   PrimitiveInfo
     linecap[5];
 
-  register long
+  register ssize_t
     i;
 
   for (i=0; i < 4; i++)
@@ -4769,13 +4772,18 @@ MagickExport void GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
     (void) CloneString(&draw_info->encoding,option);
   option=GetImageOption(clone_info,"kerning");
   if (option != (const char *) NULL)
-    draw_info->kerning=StringToDouble(option);
+    draw_info->kerning=InterpretLocaleValue(option,(char **) NULL);
   option=GetImageOption(clone_info,"interline-spacing");
   if (option != (const char *) NULL)
-    draw_info->interline_spacing=StringToDouble(option);
+    draw_info->interline_spacing=InterpretLocaleValue(option,(char **) NULL);
+  draw_info->direction=UndefinedDirection;
   option=GetImageOption(clone_info,"interword-spacing");
   if (option != (const char *) NULL)
-    draw_info->interword_spacing=StringToDouble(option);
+    draw_info->interword_spacing=InterpretLocaleValue(option,(char **) NULL);
+  option=GetImageOption(clone_info,"direction");
+  if (option != (const char *) NULL)
+    draw_info->direction=(DirectionType) ParseCommandOption(
+      MagickDirectionOptions,MagickFalse,option);
   option=GetImageOption(clone_info,"fill");
   if (option != (const char *) NULL)
     (void) QueryColorDatabase(option,&draw_info->fill,exception);
@@ -4784,13 +4792,13 @@ MagickExport void GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
     (void) QueryColorDatabase(option,&draw_info->stroke,exception);
   option=GetImageOption(clone_info,"strokewidth");
   if (option != (const char *) NULL)
-    draw_info->stroke_width=StringToDouble(option);
+    draw_info->stroke_width=InterpretLocaleValue(option,(char **) NULL);
   option=GetImageOption(clone_info,"undercolor");
   if (option != (const char *) NULL)
     (void) QueryColorDatabase(option,&draw_info->undercolor,exception);
   option=GetImageOption(clone_info,"gravity");
   if (option != (const char *) NULL)
-    draw_info->gravity=(GravityType) ParseMagickOption(MagickGravityOptions,
+    draw_info->gravity=(GravityType) ParseCommandOption(MagickGravityOptions,
       MagickFalse,option);
   exception=DestroyExceptionInfo(exception);
   draw_info->signature=MagickSignature;
@@ -4812,7 +4820,7 @@ MagickExport void GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
 %
 %  The format of the Permutate method is:
 %
-%      void Permutate(long n,long k)
+%      void Permutate(ssize_t n,ssize_t k)
 %
 %  A description of each parameter follows:
 %
@@ -4822,12 +4830,12 @@ MagickExport void GetDrawInfo(const ImageInfo *image_info,DrawInfo *draw_info)
 %
 %
 */
-static inline MagickRealType Permutate(const long n,const long k)
+static inline MagickRealType Permutate(const ssize_t n,const ssize_t k)
 {
   MagickRealType
     r;
 
-  register long
+  register ssize_t
     i;
 
   r=1.0;
@@ -4892,10 +4900,10 @@ static void TraceArcPath(PrimitiveInfo *primitive_info,const PointInfo start,
   register PrimitiveInfo
     *p;
 
-  register long
+  register ssize_t
     i;
 
-  unsigned long
+  size_t
     arc_segments;
 
   if ((start.x == end.x) && (start.y == end.y))
@@ -4950,10 +4958,10 @@ static void TraceArcPath(PrimitiveInfo *primitive_info,const PointInfo start,
   else
     if ((theta > 0.0) && (sweep == MagickFalse))
       theta-=(MagickRealType) (2.0*MagickPI);
-  arc_segments=(unsigned long) ceil(fabs((double) (theta/(0.5*MagickPI+
-    MagickEpsilon)))-0.5);
+  arc_segments=(size_t) ceil(fabs((double) (theta/(0.5*MagickPI+
+    MagickEpsilon))));
   p=primitive_info;
-  for (i=0; i < (long) arc_segments; i++)
+  for (i=0; i < (ssize_t) arc_segments; i++)
   {
     beta=0.5*((alpha+(i+1)*theta/arc_segments)-(alpha+i*theta/arc_segments));
     gamma=(8.0/3.0)*sin(fmod((double) (0.5*beta),DegreesToRadians(360.0)))*
@@ -4987,13 +4995,13 @@ static void TraceArcPath(PrimitiveInfo *primitive_info,const PointInfo start,
       points[2].y);
     (p+3)->point.y=(double) (sine*radii.x*points[2].x+cosine*radii.y*
       points[2].y);
-    if (i == (long) (arc_segments-1))
+    if (i == (ssize_t) (arc_segments-1))
       (p+3)->point=end;
     TraceBezier(p,4);
     p+=p->coordinates;
   }
-  primitive_info->coordinates=(unsigned long) (p-primitive_info);
-  for (i=0; i < (long) primitive_info->coordinates; i++)
+  primitive_info->coordinates=(size_t) (p-primitive_info);
+  for (i=0; i < (ssize_t) primitive_info->coordinates; i++)
   {
     p->primitive=primitive_info->primitive;
     p--;
@@ -5001,7 +5009,7 @@ static void TraceArcPath(PrimitiveInfo *primitive_info,const PointInfo start,
 }
 
 static void TraceBezier(PrimitiveInfo *primitive_info,
-  const unsigned long number_coordinates)
+  const size_t number_coordinates)
 {
   MagickRealType
     alpha,
@@ -5013,14 +5021,14 @@ static void TraceBezier(PrimitiveInfo *primitive_info,
     point,
     *points;
 
-  register long
-    i,
-    j;
-
   register PrimitiveInfo
     *p;
 
-  unsigned long
+  register ssize_t
+    i,
+    j;
+
+  size_t
     control_points,
     quantum;
 
@@ -5028,19 +5036,19 @@ static void TraceBezier(PrimitiveInfo *primitive_info,
     Allocate coeficients.
   */
   quantum=number_coordinates;
-  for (i=0; i < (long) number_coordinates; i++)
+  for (i=0; i < (ssize_t) number_coordinates; i++)
   {
-    for (j=i+1; j < (long) number_coordinates; j++)
+    for (j=i+1; j < (ssize_t) number_coordinates; j++)
     {
       alpha=fabs(primitive_info[j].point.x-primitive_info[i].point.x);
       if (alpha > (MagickRealType) quantum)
-        quantum=(unsigned long) alpha;
+        quantum=(size_t) alpha;
       alpha=fabs(primitive_info[j].point.y-primitive_info[i].point.y);
       if (alpha > (MagickRealType) quantum)
-        quantum=(unsigned long) alpha;
+        quantum=(size_t) alpha;
     }
   }
-  quantum=(unsigned long) MagickMin((double) quantum/number_coordinates,
+  quantum=(size_t) MagickMin((double) quantum/number_coordinates,
     (double) BezierQuantum);
   control_points=quantum*number_coordinates;
   coefficients=(MagickRealType *) AcquireQuantumMemory((size_t)
@@ -5054,16 +5062,16 @@ static void TraceBezier(PrimitiveInfo *primitive_info,
     Compute bezier points.
   */
   end=primitive_info[number_coordinates-1].point;
-  for (i=0; i < (long) number_coordinates; i++)
-    coefficients[i]=Permutate((long) number_coordinates-1,i);
+  for (i=0; i < (ssize_t) number_coordinates; i++)
+    coefficients[i]=Permutate((ssize_t) number_coordinates-1,i);
   weight=0.0;
-  for (i=0; i < (long) control_points; i++)
+  for (i=0; i < (ssize_t) control_points; i++)
   {
     p=primitive_info;
     point.x=0.0;
     point.y=0.0;
     alpha=pow((double) (1.0-weight),(double) number_coordinates-1.0);
-    for (j=0; j < (long) number_coordinates; j++)
+    for (j=0; j < (ssize_t) number_coordinates; j++)
     {
       point.x+=alpha*coefficients[j]*p->point.x;
       point.y+=alpha*coefficients[j]*p->point.y;
@@ -5077,15 +5085,15 @@ static void TraceBezier(PrimitiveInfo *primitive_info,
     Bezier curves are just short segmented polys.
   */
   p=primitive_info;
-  for (i=0; i < (long) control_points; i++)
+  for (i=0; i < (ssize_t) control_points; i++)
   {
     TracePoint(p,points[i]);
     p+=p->coordinates;
   }
   TracePoint(p,end);
   p+=p->coordinates;
-  primitive_info->coordinates=(unsigned long) (p-primitive_info);
-  for (i=0; i < (long) primitive_info->coordinates; i++)
+  primitive_info->coordinates=(size_t) (p-primitive_info);
+  for (i=0; i < (ssize_t) primitive_info->coordinates; i++)
   {
     p->primitive=primitive_info->primitive;
     p--;
@@ -5131,7 +5139,7 @@ static void TraceEllipse(PrimitiveInfo *primitive_info,const PointInfo start,
   register PrimitiveInfo
     *p;
 
-  register long
+  register ssize_t
     i;
 
   /*
@@ -5144,8 +5152,8 @@ static void TraceEllipse(PrimitiveInfo *primitive_info,const PointInfo start,
     }
   delta=2.0/MagickMax(stop.x,stop.y);
   step=(MagickRealType) (MagickPI/8.0);
-  if (delta < (MagickPI/8.0))
-    step=MagickPI/(4*(MagickPI/delta/2+0.5));
+  if ((delta >= 0.0) && (delta < (MagickRealType) (MagickPI/8.0)))
+    step=(MagickRealType) (MagickPI/(4*(MagickPI/delta/2+0.5)));
   angle.x=DegreesToRadians(degrees.x);
   y=degrees.y;
   while (y < degrees.x)
@@ -5162,8 +5170,8 @@ static void TraceEllipse(PrimitiveInfo *primitive_info,const PointInfo start,
   point.y=sin(fmod(angle.y,DegreesToRadians(360.0)))*stop.y+start.y;
   TracePoint(p,point);
   p+=p->coordinates;
-  primitive_info->coordinates=(unsigned long) (p-primitive_info);
-  for (i=0; i < (long) primitive_info->coordinates; i++)
+  primitive_info->coordinates=(size_t) (p-primitive_info);
+  for (i=0; i < (ssize_t) primitive_info->coordinates; i++)
   {
     p->primitive=primitive_info->primitive;
     p--;
@@ -5186,7 +5194,7 @@ static void TraceLine(PrimitiveInfo *primitive_info,const PointInfo start,
   primitive_info->coordinates=2;
 }
 
-static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
+static size_t TracePath(PrimitiveInfo *primitive_info,const char *path)
 {
   char
     token[MaxTextExtent];
@@ -5214,10 +5222,10 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
   register PrimitiveInfo
     *q;
 
-  register long
+  register ssize_t
     i;
 
-  unsigned long
+  size_t
     number_coordinates,
     z_count;
 
@@ -5261,15 +5269,15 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          arc.x=StringToDouble(token);
+          arc.x=InterpretLocaleValue(token,(char **) NULL);
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          arc.y=StringToDouble(token);
+          arc.y=InterpretLocaleValue(token,(char **) NULL);
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          angle=StringToDouble(token);
+          angle=InterpretLocaleValue(token,(char **) NULL);
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
@@ -5281,11 +5289,11 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          x=StringToDouble(token);
+          x=InterpretLocaleValue(token,(char **) NULL);
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          y=StringToDouble(token);
+          y=InterpretLocaleValue(token,(char **) NULL);
           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);
@@ -5308,11 +5316,11 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            x=StringToDouble(token);
+            x=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            y=StringToDouble(token);
+            y=InterpretLocaleValue(token,(char **) NULL);
             end.x=(double) (attribute == (int) 'C' ? x : point.x+x);
             end.y=(double) (attribute == (int) 'C' ? y : point.y+y);
             points[i]=end;
@@ -5333,7 +5341,7 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          x=StringToDouble(token);
+          x=InterpretLocaleValue(token,(char **) NULL);
           point.x=(double) (attribute == (int) 'H' ? x: point.x+x);
           TracePoint(q,point);
           q+=q->coordinates;
@@ -5348,11 +5356,11 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          x=StringToDouble(token);
+          x=InterpretLocaleValue(token,(char **) NULL);
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          y=StringToDouble(token);
+          y=InterpretLocaleValue(token,(char **) NULL);
           point.x=(double) (attribute == (int) 'L' ? x : point.x+x);
           point.y=(double) (attribute == (int) 'L' ? y : point.y+y);
           TracePoint(q,point);
@@ -5365,7 +5373,7 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
       {
         if (q != primitive_info)
           {
-            primitive_info->coordinates=(unsigned long) (q-primitive_info);
+            primitive_info->coordinates=(size_t) (q-primitive_info);
             number_coordinates+=primitive_info->coordinates;
             primitive_info=q;
           }
@@ -5375,11 +5383,11 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          x=StringToDouble(token);
+          x=InterpretLocaleValue(token,(char **) NULL);
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          y=StringToDouble(token);
+          y=InterpretLocaleValue(token,(char **) NULL);
           point.x=(double) (attribute == (int) 'M' ? x : point.x+x);
           point.y=(double) (attribute == (int) 'M' ? y : point.y+y);
           if (i == 0)
@@ -5387,7 +5395,7 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
           i++;
           TracePoint(q,point);
           q+=q->coordinates;
-          if (attribute == (int) 'M')
+          if ((i != 0) && (attribute == (int) 'M'))
             {
               TracePoint(q,point);
               q+=q->coordinates;
@@ -5409,11 +5417,11 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            x=StringToDouble(token);
+            x=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            y=StringToDouble(token);
+            y=InterpretLocaleValue(token,(char **) NULL);
             if (*p == ',')
               p++;
             end.x=(double) (attribute == (int) 'Q' ? x : point.x+x);
@@ -5444,11 +5452,11 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            x=StringToDouble(token);
+            x=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            y=StringToDouble(token);
+            y=InterpretLocaleValue(token,(char **) NULL);
             if (*p == ',')
               p++;
             end.x=(double) (attribute == (int) 'S' ? x : point.x+x);
@@ -5484,11 +5492,11 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            x=StringToDouble(token);
+            x=InterpretLocaleValue(token,(char **) NULL);
             GetMagickToken(p,&p,token);
             if (*token == ',')
               GetMagickToken(p,&p,token);
-            y=StringToDouble(token);
+            y=InterpretLocaleValue(token,(char **) NULL);
             end.x=(double) (attribute == (int) 'T' ? x : point.x+x);
             end.y=(double) (attribute == (int) 'T' ? y : point.y+y);
             points[i]=end;
@@ -5514,7 +5522,7 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
           GetMagickToken(p,&p,token);
           if (*token == ',')
             GetMagickToken(p,&p,token);
-          y=StringToDouble(token);
+          y=InterpretLocaleValue(token,(char **) NULL);
           point.y=(double) (attribute == (int) 'V' ? y : point.y+y);
           TracePoint(q,point);
           q+=q->coordinates;
@@ -5527,7 +5535,7 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
         point=start;
         TracePoint(q,point);
         q+=q->coordinates;
-        primitive_info->coordinates=(unsigned long) (q-primitive_info);
+        primitive_info->coordinates=(size_t) (q-primitive_info);
         number_coordinates+=primitive_info->coordinates;
         primitive_info=q;
         z_count++;
@@ -5536,14 +5544,15 @@ static unsigned long TracePath(PrimitiveInfo *primitive_info,const char *path)
       default:
       {
         if (isalpha((int) ((unsigned char) attribute)) != 0)
-          (void) fprintf(stderr,"attribute not recognized: %c\n",attribute);
+          (void) FormatLocaleFile(stderr,"attribute not recognized: %c\n",
+            attribute);
         break;
       }
     }
   }
-  primitive_info->coordinates=(unsigned long) (q-primitive_info);
+  primitive_info->coordinates=(size_t) (q-primitive_info);
   number_coordinates+=primitive_info->coordinates;
-  for (i=0; i < (long) number_coordinates; i++)
+  for (i=0; i < (ssize_t) number_coordinates; i++)
   {
     q--;
     q->primitive=primitive_type;
@@ -5563,7 +5572,7 @@ static void TraceRectangle(PrimitiveInfo *primitive_info,const PointInfo start,
   register PrimitiveInfo
     *p;
 
-  register long
+  register ssize_t
     i;
 
   p=primitive_info;
@@ -5581,8 +5590,8 @@ static void TraceRectangle(PrimitiveInfo *primitive_info,const PointInfo start,
   p+=p->coordinates;
   TracePoint(p,start);
   p+=p->coordinates;
-  primitive_info->coordinates=(unsigned long) (p-primitive_info);
-  for (i=0; i < (long) primitive_info->coordinates; i++)
+  primitive_info->coordinates=(size_t) (p-primitive_info);
+  for (i=0; i < (ssize_t) primitive_info->coordinates; i++)
   {
     p->primitive=primitive_info->primitive;
     p--;
@@ -5600,7 +5609,7 @@ static void TraceRoundRectangle(PrimitiveInfo *primitive_info,
   register PrimitiveInfo
     *p;
 
-  register long
+  register ssize_t
     i;
 
   p=primitive_info;
@@ -5636,8 +5645,8 @@ static void TraceRoundRectangle(PrimitiveInfo *primitive_info,
   p+=p->coordinates;
   TracePoint(p,primitive_info->point);
   p+=p->coordinates;
-  primitive_info->coordinates=(unsigned long) (p-primitive_info);
-  for (i=0; i < (long) primitive_info->coordinates; i++)
+  primitive_info->coordinates=(size_t) (p-primitive_info);
+  for (i=0; i < (ssize_t) primitive_info->coordinates; i++)
   {
     p->primitive=primitive_info->primitive;
     p--;
@@ -5645,24 +5654,24 @@ static void TraceRoundRectangle(PrimitiveInfo *primitive_info,
 }
 
 static void TraceSquareLinecap(PrimitiveInfo *primitive_info,
-  const unsigned long number_vertices,const MagickRealType offset)
+  const size_t number_vertices,const MagickRealType offset)
 {
   MagickRealType
     distance;
 
-  long
-    j;
-
   register MagickRealType
     dx,
     dy;
 
-  register long
+  register ssize_t
     i;
 
+  ssize_t
+    j;
+
   dx=0.0;
   dy=0.0;
-  for (i=1; i < (long) number_vertices; i++)
+  for (i=1; i < (ssize_t) number_vertices; i++)
   {
     dx=primitive_info[0].point.x-primitive_info[i].point.x;
     dy=primitive_info[0].point.y-primitive_info[i].point.y;
@@ -5670,14 +5679,14 @@ static void TraceSquareLinecap(PrimitiveInfo *primitive_info,
         (fabs((double) dy) >= MagickEpsilon))
       break;
   }
-  if (i == (long) number_vertices)
-    i=(long) number_vertices-1L;
+  if (i == (ssize_t) number_vertices)
+    i=(ssize_t) number_vertices-1L;
   distance=hypot((double) dx,(double) dy);
   primitive_info[0].point.x=(double) (primitive_info[i].point.x+
     dx*(distance+offset)/distance);
   primitive_info[0].point.y=(double) (primitive_info[i].point.y+
     dy*(distance+offset)/distance);
-  for (j=(long) number_vertices-2; j >= 0;  j--)
+  for (j=(ssize_t) number_vertices-2; j >= 0;  j--)
   {
     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;
@@ -5709,12 +5718,6 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
     slope,
     theta;
 
-  long
-    j,
-    n,
-    p,
-    q;
-
   MagickBooleanType
     closed_path;
 
@@ -5736,14 +5739,20 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
     *polygon_primitive,
     *stroke_polygon;
 
-  register long
+  register ssize_t
     i;
 
-  unsigned long
+  size_t
     arc_segments,
     max_strokes,
     number_vertices;
 
+  ssize_t
+    j,
+    n,
+    p,
+    q;
+
   /*
     Allocate paths.
   */
@@ -5776,15 +5785,15 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
   */
   dx.p=0.0;
   dy.p=0.0;
-  for (n=1; n < (long) number_vertices; n++)
+  for (n=1; n < (ssize_t) number_vertices; n++)
   {
     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))
       break;
   }
-  if (n == (long) number_vertices)
-    n=(long) number_vertices-1L;
+  if (n == (ssize_t) number_vertices)
+    n=(ssize_t) number_vertices-1L;
   slope.p=0.0;
   inverse_slope.p=0.0;
   if (fabs(dx.p) <= MagickEpsilon)
@@ -5843,7 +5852,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
   q=0;
   path_q[p++]=box_q[0];
   path_p[q++]=box_p[0];
-  for (i=(long) n+1; i < (long) number_vertices; i++)
+  for (i=(ssize_t) n+1; i < (ssize_t) number_vertices; i++)
   {
     /*
       Compute the slope for this line segment, q.
@@ -5914,7 +5923,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
           box_q[3].y)/(slope.p-slope.q));
         box_q[4].y=(double) (slope.p*(box_q[4].x-box_q[0].x)+box_q[0].y);
       }
-    if (q >= (long) (max_strokes-6*BezierQuantum-360))
+    if (q >= (ssize_t) (max_strokes-6*BezierQuantum-360))
       {
          max_strokes+=6*BezierQuantum+360;
          path_p=(PointInfo *) ResizeQuantumMemory(path_p,(size_t) max_strokes,
@@ -5981,12 +5990,12 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
           theta.q=atan2(box_q[2].y-center.y,box_q[2].x-center.x);
           if (theta.q < theta.p)
             theta.q+=(MagickRealType) (2.0*MagickPI);
-          arc_segments=(unsigned long) ceil((double) ((theta.q-theta.p)/
+          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;
           path_q[q].y=box_q[1].y;
           q++;
-          for (j=1; j < (long) arc_segments; j++)
+          for (j=1; j < (ssize_t) arc_segments; j++)
           {
             delta_theta=(MagickRealType) (j*(theta.q-theta.p)/arc_segments);
             path_q[q].x=(double) (center.x+mid*cos(fmod((double)
@@ -6053,10 +6062,10 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
           theta.q=atan2(box_p[2].y-center.y,box_p[2].x-center.x);
           if (theta.p < theta.q)
             theta.p+=(MagickRealType) (2.0*MagickPI);
-          arc_segments=(unsigned long) ceil((double) ((theta.p-theta.q)/
+          arc_segments=(size_t) ceil((double) ((theta.p-theta.q)/
             (2.0*sqrt((double) (1.0/mid)))));
           path_p[p++]=box_p[1];
-          for (j=1; j < (long) arc_segments; j++)
+          for (j=1; j < (ssize_t) arc_segments; j++)
           {
             delta_theta=(MagickRealType) (j*(theta.q-theta.p)/arc_segments);
             path_p[p].x=(double) (center.x+mid*cos(fmod((double)
@@ -6090,7 +6099,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
     (p+q+2UL*closed_path+2UL),sizeof(*stroke_polygon));
   if (stroke_polygon != (PrimitiveInfo *) NULL)
     {
-      for (i=0; i < (long) p; i++)
+      for (i=0; i < (ssize_t) p; i++)
       {
         stroke_polygon[i]=polygon_primitive[0];
         stroke_polygon[i].point=path_p[i];
@@ -6101,7 +6110,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
           stroke_polygon[i].point=stroke_polygon[0].point;
           i++;
         }
-      for ( ; i < (long) (p+q+closed_path); i++)
+      for ( ; i < (ssize_t) (p+q+closed_path); i++)
       {
         stroke_polygon[i]=polygon_primitive[0];
         stroke_polygon[i].point=path_q[p+q+closed_path-(i+1)];
@@ -6116,7 +6125,7 @@ static PrimitiveInfo *TraceStrokePolygon(const DrawInfo *draw_info,
       stroke_polygon[i].point=stroke_polygon[0].point;
       i++;
       stroke_polygon[i].primitive=UndefinedPrimitive;
-      stroke_polygon[0].coordinates=(unsigned long) (p+q+2*closed_path+1);
+      stroke_polygon[0].coordinates=(size_t) (p+q+2*closed_path+1);
     }
   path_p=(PointInfo *) RelinquishMagickMemory(path_p);
   path_q=(PointInfo *) RelinquishMagickMemory(path_q);