]> granicus.if.org Git - imagemagick/blobdiff - magick/annotate.c
(no commit message)
[imagemagick] / magick / annotate.c
index 2890ab995b3846b2be9f9c4a533439f7fbbc6d75..05af331f4eb91ca63d92db5087fa6be1675e9e8c 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2009 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  %
@@ -44,6 +44,7 @@
 */
 #include "magick/studio.h"
 #include "magick/annotate.h"
+#include "magick/attribute.h"
 #include "magick/cache-view.h"
 #include "magick/client.h"
 #include "magick/color.h"
@@ -164,9 +165,6 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
     primitive[MaxTextExtent],
     **textlist;
 
-  double
-    height;
-
   DrawInfo
     *annotate,
     *annotate_info;
@@ -183,7 +181,7 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
   RectangleInfo
     geometry;
 
-  register long
+  register ssize_t
     i;
 
   size_t
@@ -192,7 +190,8 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
   TypeMetric
     metrics;
 
-  unsigned long
+  size_t
+    height,
     number_lines;
 
   assert(image != (Image *) NULL);
@@ -212,7 +211,7 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
   for (i=1; textlist[i] != (char *) NULL; i++)
     if (strlen(textlist[i]) > length)
       length=strlen(textlist[i]);
-  number_lines=(unsigned long) i;
+  number_lines=(size_t) i;
   annotate=CloneDrawInfo((ImageInfo *) NULL,draw_info);
   annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info);
   SetGeometry(image,&geometry);
@@ -235,9 +234,8 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
     annotate_info->affine.ty=geometry_info.psi-image->page.y;
     (void) CloneString(&annotate->text,textlist[i]);
     (void) GetTypeMetrics(image,annotate,&metrics);
-    height=metrics.height;
-    if (draw_info->interline_spacing != 0.0)
-      height+=draw_info->interline_spacing;
+    height=(ssize_t) (metrics.ascent-metrics.descent+
+      draw_info->interline_spacing+0.5);
     switch (annotate->gravity)
     {
       case UndefinedGravity:
@@ -397,7 +395,7 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
         undercolor_info->affine.tx=offset.x-draw_info->affine.ry*metrics.ascent;
         undercolor_info->affine.ty=offset.y-draw_info->affine.sy*metrics.ascent;
         (void) FormatMagickString(primitive,MaxTextExtent,
-          "rectangle 0,0 %g,%g",metrics.origin.x,height);
+          "rectangle 0,0 %g,%.20g",metrics.origin.x,(double) height);
         (void) CloneString(&undercolor_info->primitive,primitive);
         (void) DrawImage(image,undercolor_info);
         (void) DestroyDrawInfo(undercolor_info);
@@ -462,22 +460,24 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
 %
 %  The format of the FormatMagickCaption method is:
 %
-%      long FormatMagickCaption(Image *image,DrawInfo *draw_info,
-%        TypeMetric *metrics,char **caption)
+%      ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info,
+%        const MagickBooleanType split,TypeMetric *metrics,char **caption)
 %
 %  A description of each parameter follows.
 %
 %    o image:  The image.
 %
-%    o caption: the caption.
-%
 %    o draw_info: the draw info.
 %
+%    o split: when no convenient line breaks-- insert newline.
+%
 %    o metrics: Return the font metrics in this structure.
 %
+%    o caption: the caption.
+%
 */
-MagickExport long FormatMagickCaption(Image *image,DrawInfo *draw_info,
-  TypeMetric *metrics,char **caption)
+MagickExport ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info,
+  const MagickBooleanType split,TypeMetric *metrics,char **caption)
 {
   MagickBooleanType
     status;
@@ -487,10 +487,10 @@ MagickExport long FormatMagickCaption(Image *image,DrawInfo *draw_info,
     *q,
     *s;
 
-  register long
+  register ssize_t
     i;
 
-  unsigned long
+  size_t
     width;
 
   q=draw_info->text;
@@ -499,13 +499,13 @@ MagickExport long FormatMagickCaption(Image *image,DrawInfo *draw_info,
   {
     if (IsUTFSpace(GetUTFCode(p)) != MagickFalse)
       s=p;
-    for (i=0; i < (long) GetUTFOctets(p); i++)
+    for (i=0; i < (ssize_t) GetUTFOctets(p); i++)
       *q++=(*(p+i));
     *q='\0';
     status=GetTypeMetrics(image,draw_info,metrics);
     if (status == MagickFalse)
       break;
-    width=(unsigned long) (metrics->width+0.5);
+    width=(size_t) floor(metrics->width+0.5);
     if (GetUTFCode(p) != '\n')
       if (width <= image->columns)
         continue;
@@ -522,25 +522,26 @@ MagickExport long FormatMagickCaption(Image *image,DrawInfo *draw_info,
         p=s;
       }
     else
-      {
-        char
-          *target;
+      if (split != MagickFalse)
+        {
+          char
+            *target;
 
-        long
-          n;
+          ssize_t
+            n;
 
-        /*
-          No convenient line breaks-- insert newline.
-        */
-        target=AcquireString(*caption);
-        n=p-(*caption);
-        CopyMagickString(target,*caption,n+1);
-        ConcatenateMagickString(target,"\n",strlen(*caption)+1);
-        ConcatenateMagickString(target,p,strlen(*caption)+2);
-        (void) DestroyString(*caption);
-        *caption=target;
-        p=(*caption)+n;
-      }
+          /*
+            No convenient line breaks-- insert newline.
+          */
+          target=AcquireString(*caption);
+          n=p-(*caption);
+          CopyMagickString(target,*caption,n+1);
+          ConcatenateMagickString(target,"\n",strlen(*caption)+1);
+          ConcatenateMagickString(target,p,strlen(*caption)+2);
+          (void) DestroyString(*caption);
+          *caption=target;
+          p=(*caption)+n;
+        }
     s=(char *) NULL;
     q=draw_info->text;
   }
@@ -610,15 +611,12 @@ MagickExport MagickBooleanType GetMultilineTypeMetrics(Image *image,
   MagickBooleanType
     status;
 
-  register long
+  register ssize_t
     i;
 
   TypeMetric
     extent;
 
-  unsigned long
-    number_lines;
-
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
@@ -652,9 +650,8 @@ MagickExport MagickBooleanType GetMultilineTypeMetrics(Image *image,
     if (extent.width > metrics->width)
       *metrics=extent;
   }
-  number_lines=(unsigned long) i;
-  metrics->height=(double) number_lines*(long) (metrics->ascent-
-    metrics->descent+0.5);
+  metrics->height=(double) (i*(size_t) (metrics->ascent-
+    metrics->descent+0.5)+(i-1)*draw_info->interline_spacing);
   /*
     Relinquish resources.
   */
@@ -823,14 +820,19 @@ static MagickBooleanType RenderType(Image *image,const DrawInfo *draw_info,
           TypeWarning,"UnableToReadFont","`%s'",draw_info->family);
     }
   if (type_info == (const TypeInfo *) NULL)
-    type_info=GetTypeInfoByFamily("arial",draw_info->style,
+    type_info=GetTypeInfoByFamily("Arial",draw_info->style,
+      draw_info->stretch,draw_info->weight,&image->exception);
+  if (type_info == (const TypeInfo *) NULL)
+    type_info=GetTypeInfoByFamily("Helvetica",draw_info->style,
       draw_info->stretch,draw_info->weight,&image->exception);
   if (type_info == (const TypeInfo *) NULL)
-    type_info=GetTypeInfoByFamily("helvetica",draw_info->style,
+    type_info=GetTypeInfoByFamily("Century Schoolbook",draw_info->style,
       draw_info->stretch,draw_info->weight,&image->exception);
   if (type_info == (const TypeInfo *) NULL)
     type_info=GetTypeInfoByFamily((const char *) NULL,draw_info->style,
       draw_info->stretch,draw_info->weight,&image->exception);
+  if (type_info == (const TypeInfo *) NULL)
+    type_info=GetTypeInfo("*",&image->exception);
   if (type_info == (const TypeInfo *) NULL)
     {
       status=RenderFreetype(image,draw_info,draw_info->encoding,offset,metrics);
@@ -881,6 +883,7 @@ static MagickBooleanType RenderType(Image *image,const DrawInfo *draw_info,
 */
 
 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
+
 static int TraceCubicBezier(FT_Vector *p,FT_Vector *q,FT_Vector *to,
   DrawInfo *draw_info)
 {
@@ -891,9 +894,10 @@ static int TraceCubicBezier(FT_Vector *p,FT_Vector *q,FT_Vector *to,
     path[MaxTextExtent];
 
   affine=draw_info->affine;
-  (void) FormatMagickString(path,MaxTextExtent,"C%g,%g %g,%g %g,%g",
-    affine.tx+p->x/64.0,affine.ty-p->y/64.0,affine.tx+q->x/64.0,
-    affine.ty-q->y/64.0,affine.tx+to->x/64.0,affine.ty-to->y/64.0);
+  (void) FormatMagickString(path,MaxTextExtent,
+    "C%g,%g %g,%g %g,%g",affine.tx+p->x/64.0,affine.ty-
+    p->y/64.0,affine.tx+q->x/64.0,affine.ty-q->y/64.0,affine.tx+to->x/64.0,
+    affine.ty-to->y/64.0);
   (void) ConcatenateString(&draw_info->primitive,path);
   return(0);
 }
@@ -907,8 +911,8 @@ static int TraceLineTo(FT_Vector *to,DrawInfo *draw_info)
     path[MaxTextExtent];
 
   affine=draw_info->affine;
-  (void) FormatMagickString(path,MaxTextExtent,"L%g,%g",affine.tx+to->x/64.0,
-    affine.ty-to->y/64.0);
+  (void) FormatMagickString(path,MaxTextExtent,"L%g,%g",affine.tx+
+    to->x/64.0,affine.ty-to->y/64.0);
   (void) ConcatenateString(&draw_info->primitive,path);
   return(0);
 }
@@ -922,8 +926,8 @@ static int TraceMoveTo(FT_Vector *to,DrawInfo *draw_info)
     path[MaxTextExtent];
 
   affine=draw_info->affine;
-  (void) FormatMagickString(path,MaxTextExtent,"M%g,%g",affine.tx+to->x/64.0,
-    affine.ty-to->y/64.0);
+  (void) FormatMagickString(path,MaxTextExtent,"M%g,%g",affine.tx+
+    to->x/64.0,affine.ty-to->y/64.0);
   (void) ConcatenateString(&draw_info->primitive,path);
   return(0);
 }
@@ -967,6 +971,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
   const char
     *value;
 
+  double
+    direction;
+
   DrawInfo
     *annotate_info;
 
@@ -1004,7 +1011,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     glyph,
     last_glyph;
 
-  long
+  ssize_t
     code,
     y;
 
@@ -1025,6 +1032,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       0, 0
     };
 
+  unsigned char
+    *utf8;
+
   /*
     Initialize Truetype library.
   */
@@ -1041,7 +1051,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     else
       args.pathname=ConstantString(draw_info->font+1);
   face=(FT_Face) NULL;
-  status=FT_Open_Face(library,&args,draw_info->face,&face);
+  status=FT_Open_Face(library,&args,(long) draw_info->face,&face);
   args.pathname=DestroyString(args.pathname);
   if (status != 0)
     {
@@ -1150,7 +1160,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       draw_info->pointsize);
   flags=FT_LOAD_NO_BITMAP;
   value=GetImageProperty(image,"type:hinting");
-  if (LocaleCompare(value,"off") == 0)
+  if ((value != (const char *) NULL) && (LocaleCompare(value,"off") == 0))
     flags|=FT_LOAD_NO_HINTING;
   glyph.id=0;
   glyph.image=NULL;
@@ -1178,18 +1188,35 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       if (image->matte == MagickFalse)
         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
     }
+  direction=1.0;
+  if (draw_info->direction == RightToLeftDirection)
+    direction=(-1.0);
   point.x=0.0;
   point.y=0.0;
-  code=0;
   for (p=draw_info->text; GetUTFCode(p) != 0; p+=GetUTFOctets(p))
+    if (GetUTFCode(p) < 0)
+      break;
+  utf8=(unsigned char *) NULL;
+  if (GetUTFCode(p) == 0)
+    p=draw_info->text;
+  else
+    {
+      utf8=ConvertLatin1ToUTF8((unsigned char *) draw_info->text);
+      if (utf8 != (unsigned char *) NULL)
+        p=(char *) utf8;
+    }
+  for (code=0; GetUTFCode(p) != 0; p+=GetUTFOctets(p))
   {
+    /*
+      Render UTF-8 sequence.
+    */
     glyph.id=FT_Get_Char_Index(face,GetUTFCode(p));
     if (glyph.id == 0)
       glyph.id=FT_Get_Char_Index(face,'?');
     if ((glyph.id != 0) && (last_glyph.id != 0))
       {
         if (draw_info->kerning != 0.0)
-          origin.x+=64.0*draw_info->kerning;
+          origin.x+=64.0*direction*draw_info->kerning;
         else
           if (FT_HAS_KERNING(face))
             {
@@ -1199,7 +1226,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
               status=FT_Get_Kerning(face,last_glyph.id,glyph.id,
                 ft_kerning_default,&kerning);
               if (status == 0)
-                origin.x+=kerning.x;
+                origin.x+=direction*kerning.x;
             }
         }
     glyph.origin=origin;
@@ -1230,8 +1257,8 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
           */
           annotate_info->affine.tx=glyph.origin.x/64.0;
           annotate_info->affine.ty=glyph.origin.y/64.0;
-          (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->outline,
-            &OutlineMethods,annotate_info);
+          (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->
+            outline,&OutlineMethods,annotate_info);
         }
     FT_Vector_Transform(&glyph.origin,&affine);
     (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin);
@@ -1259,12 +1286,8 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
         status=MagickTrue;
         exception=(&image->exception);
         image_view=AcquireCacheView(image);
-        for (y=0; y < (long) bitmap->bitmap.rows; y++)
+        for (y=0; y < (ssize_t) bitmap->bitmap.rows; y++)
         {
-          long
-            x_offset,
-            y_offset;
-
           MagickBooleanType
             active,
             sync;
@@ -1275,23 +1298,27 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
           PixelPacket
             fill_color;
 
-          register long
+          register ssize_t
             x;
 
           register PixelPacket
-            *__restrict q;
+            *restrict q;
 
           register unsigned char
             *p;
 
+          ssize_t
+            x_offset,
+            y_offset;
+
           if (status == MagickFalse)
             continue;
-          x_offset=(long) (point.x+0.5);
-          y_offset=(long) (point.y+y+0.5);
-          if ((y_offset < 0) || (y_offset >= (long) image->rows))
+          x_offset=(ssize_t) ceil(point.x-0.5);
+          y_offset=(ssize_t) ceil(point.y+y-0.5);
+          if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows))
             continue;
           q=(PixelPacket *) NULL;
-          if ((x_offset < 0) || (x_offset >= (long) image->columns))
+          if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns))
             active=MagickFalse;
           else
             {
@@ -1300,11 +1327,11 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
               active=q != (PixelPacket *) NULL ? MagickTrue : MagickFalse;
             }
           p=bitmap->bitmap.buffer+y*bitmap->bitmap.width;
-          for (x=0; x < (long) bitmap->bitmap.width; x++)
+          for (x=0; x < (ssize_t) bitmap->bitmap.width; x++)
           {
             x_offset++;
             if ((*p == 0) || (x_offset < 0) ||
-                (x_offset >= (long) image->columns))
+                (x_offset >= (ssize_t) image->columns))
               {
                 p++;
                 q++;
@@ -1346,9 +1373,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     if ((draw_info->interword_spacing != 0.0) &&
         (IsUTFSpace(GetUTFCode(p)) != MagickFalse) &&
         (IsUTFSpace(code) == MagickFalse))
-      origin.x+=64.0*draw_info->interword_spacing;
+      origin.x+=64.0*direction*draw_info->interword_spacing;
     else
-      origin.x+=face->glyph->advance.x;
+      origin.x+=direction*face->glyph->advance.x;
     metrics->origin.x=origin.x;
     metrics->origin.y=origin.y;
     if (last_glyph.id != 0)
@@ -1356,6 +1383,8 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     last_glyph=glyph;
     code=GetUTFCode(p);
   }
+  if (utf8 != (unsigned char *) NULL)
+    utf8=(unsigned char *) RelinquishMagickMemory(utf8);
   if (last_glyph.id != 0)
     FT_Done_Glyph(last_glyph.image);
   if ((draw_info->stroke.opacity != TransparentOpacity) ||
@@ -1473,7 +1502,7 @@ static char *EscapeParenthesis(const char *text)
   register char
     *p;
 
-  register long
+  register ssize_t
     i;
 
   size_t
@@ -1482,7 +1511,7 @@ static char *EscapeParenthesis(const char *text)
   escapes=0;
   buffer=AcquireString(text);
   p=buffer;
-  for (i=0; i < (long) MagickMin(strlen(text),MaxTextExtent-escapes-1); i++)
+  for (i=0; i < (ssize_t) MagickMin(strlen(text),MaxTextExtent-escapes-1); i++)
   {
     if ((text[i] == '(') || (text[i] == ')'))
       {
@@ -1515,7 +1544,7 @@ static MagickBooleanType RenderPostscript(Image *image,
   int
     unique_file;
 
-  long
+  ssize_t
     y;
 
   MagickBooleanType
@@ -1526,7 +1555,7 @@ static MagickBooleanType RenderPostscript(Image *image,
     point,
     resolution;
 
-  register long
+  register ssize_t
     i;
 
   /*
@@ -1563,7 +1592,7 @@ static MagickBooleanType RenderPostscript(Image *image,
     MagickTrue : MagickFalse;
   extent.x=0.0;
   extent.y=0.0;
-  for (i=0; i <= (long) (strlen(draw_info->text)+2); i++)
+  for (i=0; i <= (ssize_t) (strlen(draw_info->text)+2); i++)
   {
     point.x=fabs(draw_info->affine.sx*i*draw_info->pointsize+
       draw_info->affine.ry*2.0*draw_info->pointsize);
@@ -1585,8 +1614,9 @@ static MagickBooleanType RenderPostscript(Image *image,
   else
     (void) fprintf(file,"/%s-ISO dup /%s ReencodeType findfont setfont\n",
       draw_info->font,draw_info->font);
-  (void) fprintf(file,"[%g %g %g %g 0 0] concat\n",draw_info->affine.sx,
-    -draw_info->affine.rx,-draw_info->affine.ry,draw_info->affine.sy);
+  (void) fprintf(file,"[%g %g %g %g 0 0] concat\n",
+    draw_info->affine.sx,-draw_info->affine.rx,-draw_info->affine.ry,
+    draw_info->affine.sy);
   text=EscapeParenthesis(draw_info->text);
   if (identity == MagickFalse)
     (void) fprintf(file,"(%s) stringwidth pop -0.5 mul -0.5 rmoveto\n",text);
@@ -1594,8 +1624,8 @@ static MagickBooleanType RenderPostscript(Image *image,
   text=DestroyString(text);
   (void) fprintf(file,"showpage\n");
   (void) fclose(file);
-  (void) FormatMagickString(geometry,MaxTextExtent,"%ldx%ld+0+0!",(long)
-    (extent.x+0.5),(long) (extent.y+0.5));
+  (void) FormatMagickString(geometry,MaxTextExtent,"%.20gx%.20g+0+0!",
+    floor(extent.x+0.5),floor(extent.y+0.5));
   annotate_info=AcquireImageInfo();
   (void) FormatMagickString(annotate_info->filename,MaxTextExtent,"ps:%s",
     filename);
@@ -1633,11 +1663,13 @@ static MagickBooleanType RenderPostscript(Image *image,
         crop_info;
 
       crop_info=GetImageBoundingBox(annotate_image,&annotate_image->exception);
-      crop_info.height=(unsigned long) ((resolution.y/DefaultResolution)*
+      crop_info.height=(size_t) ((resolution.y/DefaultResolution)*
         ExpandAffine(&draw_info->affine)*draw_info->pointsize+0.5);
-      crop_info.y=(long) ((resolution.y/DefaultResolution)*extent.y/8.0+0.5);
-      (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
-        crop_info.width,crop_info.height,crop_info.x,crop_info.y);
+      crop_info.y=(ssize_t) ceil((resolution.y/DefaultResolution)*extent.y/8.0-
+        0.5);
+      (void) FormatMagickString(geometry,MaxTextExtent,
+        "%.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double)
+        crop_info.height,(double) crop_info.x,(double) crop_info.y);
       (void) TransformImage(&annotate_image,geometry,(char *) NULL);
     }
   metrics->pixels_per_em.x=(resolution.y/DefaultResolution)*
@@ -1684,22 +1716,22 @@ static MagickBooleanType RenderPostscript(Image *image,
       fill_color=draw_info->fill;
       exception=(&image->exception);
       annotate_view=AcquireCacheView(annotate_image);
-      for (y=0; y < (long) annotate_image->rows; y++)
+      for (y=0; y < (ssize_t) annotate_image->rows; y++)
       {
-        register long
+        register ssize_t
           x;
 
         register PixelPacket
-          *__restrict q;
+          *restrict q;
 
         q=GetCacheViewAuthenticPixels(annotate_view,0,y,annotate_image->columns,
           1,exception);
         if (q == (PixelPacket *) NULL)
           break;
-        for (x=0; x < (long) annotate_image->columns; x++)
+        for (x=0; x < (ssize_t) annotate_image->columns; x++)
         {
           (void) GetFillColor(draw_info,x,y,&fill_color);
-          q->opacity=RoundToQuantum(QuantumRange-(((QuantumRange-
+          q->opacity=ClampToQuantum(QuantumRange-(((QuantumRange-
             (MagickRealType) PixelIntensityToQuantum(q))*(QuantumRange-
             fill_color.opacity))/QuantumRange));
           q->red=fill_color.red;
@@ -1713,8 +1745,8 @@ static MagickBooleanType RenderPostscript(Image *image,
       }
       annotate_view=DestroyCacheView(annotate_view);
       (void) CompositeImage(image,OverCompositeOp,annotate_image,
-        (long) (offset->x+0.5),(long) (offset->y-(metrics->ascent+
-        metrics->descent)+0.5));
+        (ssize_t) ceil(offset->x-0.5),(ssize_t) ceil(offset->y-(metrics->ascent+
+        metrics->descent)-0.5));
     }
   annotate_image=DestroyImage(annotate_image);
   return(MagickTrue);
@@ -1784,12 +1816,15 @@ static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
   static XVisualInfo
     *visual_info;
 
-  unsigned long
+  size_t
     height,
     width;
 
   if (display == (Display *) NULL)
     {
+      const char
+        *client_name;
+
       ImageInfo
         *image_info;
 
@@ -1808,9 +1843,9 @@ static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
       */
       (void) XSetErrorHandler(XError);
       image_info=AcquireImageInfo();
-      resource_database=XGetResourceDatabase(display,GetClientName());
-      XGetResourceInfo(image_info,resource_database,GetClientName(),
-        &resource_info);
+      client_name=GetClientName();
+      resource_database=XGetResourceDatabase(display,client_name);
+      XGetResourceInfo(image_info,resource_database,client_name,&resource_info);
       resource_info.close_server=MagickFalse;
       resource_info.colormap=PrivateColormap;
       resource_info.font=AcquireString(draw_info->font);
@@ -1925,8 +1960,9 @@ static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
           atan2(draw_info->affine.rx,draw_info->affine.sx);
     }
   (void) FormatMagickString(annotate_info.geometry,MaxTextExtent,
-    "%lux%lu+%ld+%ld",width,height,(long) (offset->x+0.5),
-    (long) (offset->y-metrics->ascent-metrics->descent+0.5));
+    "%.20gx%.20g%+.20g%+.20g",(double) width,(double) height,
+    ceil(offset->x-0.5),ceil(offset->y-metrics->ascent-metrics->descent+
+    draw_info->interline_spacing-0.5));
   pixel.pen_color.red=ScaleQuantumToShort(draw_info->fill.red);
   pixel.pen_color.green=ScaleQuantumToShort(draw_info->fill.green);
   pixel.pen_color.blue=ScaleQuantumToShort(draw_info->fill.blue);