]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/annotate.c
(no commit message)
[imagemagick] / MagickCore / annotate.c
index ff2a032e570148ee2c3c3746f0454d21ef90a3b6..378b994d1ac2b06b294804606677982da0f52952 100644 (file)
 %                   MagickCore Image Annotation Methods                       %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -47,6 +47,7 @@
 #include "MagickCore/annotate-private.h"
 #include "MagickCore/attribute.h"
 #include "MagickCore/cache-view.h"
+#include "MagickCore/channel.h"
 #include "MagickCore/client.h"
 #include "MagickCore/color.h"
 #include "MagickCore/color-private.h"
@@ -56,6 +57,7 @@
 #include "MagickCore/constitute.h"
 #include "MagickCore/draw.h"
 #include "MagickCore/draw-private.h"
+#include "MagickCore/enhance.h"
 #include "MagickCore/exception.h"
 #include "MagickCore/exception-private.h"
 #include "MagickCore/gem.h"
 #include "MagickCore/xwindow.h"
 #include "MagickCore/xwindow-private.h"
 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
-#if defined(__MINGW32__)
+#if defined(__MINGW32__) || defined(__MINGW64__)
 #  undef interface
 #endif
-#if defined(MAGICKCORE_HAVE_FT2BUILD_H)
-#  include <ft2build.h>
-#endif
+#include <ft2build.h>
 #if defined(FT_FREETYPE_H)
 #  include FT_FREETYPE_H
 #else
@@ -145,7 +145,8 @@ static MagickBooleanType
 */
 MagickPrivate MagickBooleanType AnnotateComponentGenesis(void)
 {
-  AcquireSemaphoreInfo(&annotate_semaphore);
+  if (annotate_semaphore == (SemaphoreInfo *) NULL)
+    annotate_semaphore=AcquireSemaphoreInfo();
   return(MagickTrue);
 }
 \f
@@ -170,8 +171,8 @@ MagickPrivate MagickBooleanType AnnotateComponentGenesis(void)
 MagickPrivate void AnnotateComponentTerminus(void)
 {
   if (annotate_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&annotate_semaphore);
-  DestroySemaphoreInfo(&annotate_semaphore);
+    ActivateSemaphoreInfo(&annotate_semaphore);
+  RelinquishSemaphoreInfo(&annotate_semaphore);
 }
 \f
 /*
@@ -189,27 +190,53 @@ MagickPrivate void AnnotateComponentTerminus(void)
 %  any of the following bits of information about the image by embedding
 %  the appropriate special characters:
 %
-%    %b   file size in bytes.
-%    %c   comment.
-%    %d   directory in which the image resides.
-%    %e   extension of the image file.
-%    %f   original filename of the image.
-%    %h   height of image.
-%    %i   filename of the image.
-%    %k   number of unique colors.
-%    %l   image label.
-%    %m   image file format.
-%    %n   number of images in a image sequence.
-%    %o   output image filename.
-%    %p   page number of the image.
-%    %q   image depth (8 or 16).
-%    %q   image depth (8 or 16).
-%    %s   image scene number.
-%    %t   image filename without any extension.
-%    %u   a unique temporary filename.
-%    %w   image width.
-%    %x   x resolution of the image.
-%    %y   y resolution of the image.
+%    \n   newline
+%    \r   carriage return
+%    <    less-than character.
+%    >    greater-than character.
+%    &    ampersand character.
+%    %%   a percent sign
+%    %b   file size of image read in
+%    %c   comment meta-data property
+%    %d   directory component of path
+%    %e   filename extension or suffix
+%    %f   filename (including suffix)
+%    %g   layer canvas page geometry   (equivalent to "%Wx%H%X%Y")
+%    %h   current image height in pixels
+%    %i   image filename (note: becomes output filename for "info:")
+%    %k   CALCULATED: number of unique colors
+%    %l   label meta-data property
+%    %m   image file format (file magic)
+%    %n   number of images in current image sequence
+%    %o   output filename  (used for delegates)
+%    %p   index of image in current image list
+%    %q   quantum depth (compile-time constant)
+%    %r   image class and colorspace
+%    %s   scene number (from input unless re-assigned)
+%    %t   filename without directory or extension (suffix)
+%    %u   unique temporary filename (used for delegates)
+%    %w   current width in pixels
+%    %x   x resolution (density)
+%    %y   y resolution (density)
+%    %z   image depth (as read in unless modified, image save depth)
+%    %A   image transparency channel enabled (true/false)
+%    %C   image compression type
+%    %D   image GIF dispose method
+%    %G   original image size (%wx%h; before any resizes)
+%    %H   page (canvas) height
+%    %M   Magick filename (original file exactly as given,  including read mods)
+%    %O   page (canvas) offset ( = %X%Y )
+%    %P   page (canvas) size ( = %Wx%H )
+%    %Q   image compression quality ( 0 = default )
+%    %S   ?? scenes ??
+%    %T   image time delay (in centi-seconds)
+%    %U   image resolution units
+%    %W   page (canvas) width
+%    %X   page (canvas) x offset (including sign)
+%    %Y   page (canvas) y offset (including sign)
+%    %Z   unique filename (used for delegates)
+%    %@   CALCULATED: trim bounding box (without actually trimming)
+%    %#   CALCULATED: 'signature' hash of image values
 %
 %  The format of the AnnotateImage method is:
 %
@@ -292,7 +319,7 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
   if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
     return(MagickFalse);
   if (IsGrayColorspace(image->colorspace) != MagickFalse)
-    (void) TransformImageColorspace(image,sRGBColorspace,exception);
+    (void) SetImageColorspace(image,sRGBColorspace,exception);
   status=MagickTrue;
   for (i=0; textlist[i] != (char *) NULL; i++)
   {
@@ -463,7 +490,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) FormatLocaleString(primitive,MaxTextExtent,
-          "rectangle 0,0 %g,%.20g",metrics.origin.x,(double) height);
+          "rectangle -0.5,-0.5 %g,%.20g",metrics.origin.x,(double) height);
         (void) CloneString(&undercolor_info->primitive,primitive);
         (void) DrawImage(image,undercolor_info,exception);
         (void) DestroyDrawInfo(undercolor_info);
@@ -586,7 +613,7 @@ MagickExport ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info,
     status=GetTypeMetrics(image,draw_info,metrics,exception);
     if (status == MagickFalse)
       break;
-    width=(size_t) floor(metrics->width+0.5);
+    width=(size_t) floor(metrics->width+draw_info->stroke_width+0.5);
     if ((width <= image->columns) || (strcmp(text,draw_info->text) == 0))
       continue;
     (void) strcpy(text,draw_info->text);
@@ -888,7 +915,7 @@ static MagickBooleanType RenderType(Image *image,const DrawInfo *draw_info,
       type_info=GetTypeInfo(draw_info->font,exception);
       if (type_info == (const TypeInfo *) NULL)
         (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning,
-          "UnableToReadFont","'%s'",draw_info->font);
+          "UnableToReadFont","`%s'",draw_info->font);
     }
   if ((type_info == (const TypeInfo *) NULL) &&
       (draw_info->family != (const char *) NULL))
@@ -897,7 +924,7 @@ static MagickBooleanType RenderType(Image *image,const DrawInfo *draw_info,
         draw_info->stretch,draw_info->weight,exception);
       if (type_info == (const TypeInfo *) NULL)
         (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning,
-          "UnableToReadFont","'%s'",draw_info->family);
+          "UnableToReadFont","`%s'",draw_info->family);
     }
   if (type_info == (const TypeInfo *) NULL)
     type_info=GetTypeInfoByFamily("Arial",draw_info->style,
@@ -1076,7 +1103,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     encoding_type;
 
   FT_Error
-    status;
+    ft_status;
 
   FT_Face
     face;
@@ -1100,6 +1127,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     glyph,
     last_glyph;
 
+  MagickBooleanType
+    status;
+
   PointInfo
     point,
     resolution;
@@ -1127,8 +1157,8 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
   /*
     Initialize Truetype library.
   */
-  status=FT_Init_FreeType(&library);
-  if (status != 0)
+  ft_status=FT_Init_FreeType(&library);
+  if (ft_status != 0)
     ThrowBinaryException(TypeError,"UnableToInitializeFreetypeLibrary",
       image->filename);
   args.flags=FT_OPEN_PATHNAME;
@@ -1140,22 +1170,22 @@ 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,(long) draw_info->face,&face);
+  ft_status=FT_Open_Face(library,&args,(long) draw_info->face,&face);
   args.pathname=DestroyString(args.pathname);
-  if (status != 0)
+  if (ft_status != 0)
     {
       (void) FT_Done_FreeType(library);
       (void) ThrowMagickException(exception,GetMagickModule(),TypeError,
-        "UnableToReadFont","'%s'",draw_info->font);
+        "UnableToReadFont","`%s'",draw_info->font);
       return(RenderPostscript(image,draw_info,offset,metrics,exception));
     }
   if ((draw_info->metrics != (char *) NULL) &&
       (IsPathAccessible(draw_info->metrics) != MagickFalse))
     (void) FT_Attach_File(face,draw_info->metrics);
   encoding_type=ft_encoding_unicode;
-  status=FT_Select_Charmap(face,encoding_type);
-  if ((status != 0) && (face->num_charmaps != 0))
-    status=FT_Set_Charmap(face,face->charmaps[0]);
+  ft_status=FT_Select_Charmap(face,encoding_type);
+  if ((ft_status != 0) && (face->num_charmaps != 0))
+    ft_status=FT_Set_Charmap(face,face->charmaps[0]);
   if (encoding != (const char *) NULL)
     {
       if (LocaleCompare(encoding,"AdobeCustom") == 0)
@@ -1188,9 +1218,13 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
         encoding_type=ft_encoding_unicode;
       if (LocaleCompare(encoding,"Wansung") == 0)
         encoding_type=ft_encoding_wansung;
-      status=FT_Select_Charmap(face,encoding_type);
-      if (status != 0)
-        ThrowBinaryException(TypeError,"UnrecognizedFontEncoding",encoding);
+      ft_status=FT_Select_Charmap(face,encoding_type);
+      if (ft_status != 0)
+        {
+          (void) FT_Done_Face(face);
+          (void) FT_Done_FreeType(library);
+          ThrowBinaryException(TypeError,"UnrecognizedFontEncoding",encoding);
+        }
     }
   /*
     Set text size.
@@ -1211,7 +1245,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       if ((flags & SigmaValue) == 0)
         resolution.y=resolution.x;
     }
-  status=FT_Set_Char_Size(face,(FT_F26Dot6) (64.0*draw_info->pointsize),
+  ft_status=FT_Set_Char_Size(face,(FT_F26Dot6) (64.0*draw_info->pointsize),
     (FT_F26Dot6) (64.0*draw_info->pointsize),(FT_UInt) resolution.x,
     (FT_UInt) resolution.y);
   metrics->pixels_per_em.x=face->size->metrics.x_ppem;
@@ -1249,7 +1283,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       draw_info->pointsize);
   flags=FT_LOAD_NO_BITMAP;
   if (draw_info->text_antialias == MagickFalse)
-     flags|=FT_LOAD_TARGET_MONO;
+    flags|=FT_LOAD_TARGET_MONO;
   else
     {
 #if defined(FT_LOAD_TARGET_LIGHT)
@@ -1284,7 +1318,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     {
       if (image->storage_class != DirectClass)
         (void) SetImageStorageClass(image,DirectClass,exception);
-      if (image->matte == MagickFalse)
+      if (image->alpha_trait == UndefinedPixelTrait)
         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
     }
   direction=1.0;
@@ -1304,6 +1338,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       if (utf8 != (unsigned char *) NULL)
         p=(char *) utf8;
     }
+  status=MagickTrue;
   for (code=0; GetUTFCode(p) != 0; p+=GetUTFOctets(p))
   {
     /*
@@ -1314,30 +1349,28 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       glyph.id=FT_Get_Char_Index(face,'?');
     if ((glyph.id != 0) && (last_glyph.id != 0))
       {
-        if (fabs(draw_info->kerning) >= MagickEpsilon)
-          origin.x+=(FT_Pos) (64.0*direction*draw_info->kerning);
-        else
-          if (FT_HAS_KERNING(face))
-            {
-              FT_Vector
-                kerning;
+        if (FT_HAS_KERNING(face))
+          {
+            FT_Vector
+              kerning;
 
-              status=FT_Get_Kerning(face,last_glyph.id,glyph.id,
-                ft_kerning_default,&kerning);
-              if (status == 0)
-                origin.x+=(FT_Pos) (direction*kerning.x);
-            }
-        }
+            ft_status=FT_Get_Kerning(face,last_glyph.id,glyph.id,
+              ft_kerning_default,&kerning);
+            if (ft_status == 0)
+              origin.x+=(FT_Pos) (direction*kerning.x);
+          }
+        origin.x+=(FT_Pos) (64.0*direction*draw_info->kerning);
+      }
     glyph.origin=origin;
-    status=FT_Load_Glyph(face,glyph.id,flags);
-    if (status != 0)
+    ft_status=FT_Load_Glyph(face,glyph.id,flags);
+    if (ft_status != 0)
       continue;
-    status=FT_Get_Glyph(face->glyph,&glyph.image);
-    if (status != 0)
+    ft_status=FT_Get_Glyph(face->glyph,&glyph.image);
+    if (ft_status != 0)
       continue;
-    status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
+    ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
       &bounds);
-    if (status != 0)
+    if (ft_status != 0)
       continue;
     if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1))
       metrics->bounds.x1=(double) bounds.xMin;
@@ -1347,23 +1380,25 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       metrics->bounds.x2=(double) bounds.xMax;
     if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2))
       metrics->bounds.y2=(double) bounds.yMax;
-    if (draw_info->render != MagickFalse)
-      if ((draw_info->stroke.alpha != TransparentAlpha) ||
-          (draw_info->stroke_pattern != (Image *) NULL))
-        {
-          /*
-            Trace the glyph.
-          */
-          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);
+    if ((draw_info->stroke.alpha != TransparentAlpha) ||
+        (draw_info->stroke_pattern != (Image *) NULL))
+      {
+        if ((status != MagickFalse) && (draw_info->render != MagickFalse))
+          {
+            /*
+              Trace the glyph.
+            */
+            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);
+          }
         }
     FT_Vector_Transform(&glyph.origin,&affine);
     (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin);
-    status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
+    ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
       (FT_Vector *) NULL,MagickTrue);
-    if (status != 0)
+    if (ft_status != 0)
       continue;
     bitmap=(FT_BitmapGlyph) glyph.image;
     point.x=offset->x+bitmap->left;
@@ -1375,16 +1410,12 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
         CacheView
           *image_view;
 
-        MagickBooleanType
-          status;
-
         register unsigned char
           *p;
 
         /*
           Rasterize the glyph.
         */
-        status=MagickTrue;
         image_view=AcquireAuthenticCacheView(image,exception);
         p=bitmap->bitmap.buffer;
         for (y=0; y < (ssize_t) bitmap->bitmap.rows; y++)
@@ -1393,7 +1424,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
             active,
             sync;
 
-          MagickRealType
+          double
             fill_opacity;
 
           PixelInfo
@@ -1436,7 +1467,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
                 continue;
               }
             if (bitmap->bitmap.pixel_mode != ft_pixel_mode_mono)
-              fill_opacity=(MagickRealType) (p[n])/(bitmap->bitmap.num_grays-1);
+              fill_opacity=(double) (p[n])/(bitmap->bitmap.num_grays-1);
             else
               fill_opacity=((p[(x >> 3)+y*bitmap->bitmap.pitch] &
                 (1 << (~x & 0x07)))) == 0 ? 0.0 : 1.0;
@@ -1446,10 +1477,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
               q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,1,1,
                 exception);
             if (q == (Quantum *) NULL)
-              {
-                q+=GetPixelChannels(image);
-                continue;
-              }
+              continue;
             GetPixelInfo(image,&fill_color);
             (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color,
               exception);
@@ -1492,7 +1520,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
   if ((draw_info->stroke.alpha != TransparentAlpha) ||
       (draw_info->stroke_pattern != (Image *) NULL))
     {
-      if (draw_info->render != MagickFalse)
+      if ((status != MagickFalse) && (draw_info->render != MagickFalse))
         {
           /*
             Draw text stroke.
@@ -1509,19 +1537,19 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
   */
   glyph.id=FT_Get_Char_Index(face,'_');
   glyph.origin=origin;
-  status=FT_Load_Glyph(face,glyph.id,flags);
-  if (status == 0)
+  ft_status=FT_Load_Glyph(face,glyph.id,flags);
+  if (ft_status == 0)
     {
-      status=FT_Get_Glyph(face->glyph,&glyph.image);
-      if (status == 0)
+      ft_status=FT_Get_Glyph(face->glyph,&glyph.image);
+      if (ft_status == 0)
         {
-          status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
-            &bounds);
-          if (status == 0)
+          ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->
+            outline,&bounds);
+          if (ft_status == 0)
             {
               FT_Vector_Transform(&glyph.origin,&affine);
               (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin);
-              status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
+              ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal,
                 (FT_Vector *) NULL,MagickTrue);
               bitmap=(FT_BitmapGlyph) glyph.image;
               if (bitmap->left > metrics->width)
@@ -1531,6 +1559,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       FT_Done_Glyph(glyph.image);
     }
   metrics->width-=metrics->bounds.x1/64.0;
+  metrics->width+=annotate_info->stroke_width;
   metrics->bounds.x1/=64.0;
   metrics->bounds.y1/=64.0;
   metrics->bounds.x2/=64.0;
@@ -1543,7 +1572,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
   annotate_info=DestroyDrawInfo(annotate_info);
   (void) FT_Done_Face(face);
   (void) FT_Done_FreeType(library);
-  return(MagickTrue);
+  return(status);
 }
 #else
 static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
@@ -1659,6 +1688,9 @@ static MagickBooleanType RenderPostscript(Image *image,
   register ssize_t
     i;
 
+  size_t
+    length;
+
   ssize_t
     y;
 
@@ -1695,7 +1727,8 @@ static MagickBooleanType RenderPostscript(Image *image,
     (fabs(draw_info->affine.ry) < MagickEpsilon) ? MagickTrue : MagickFalse;
   extent.x=0.0;
   extent.y=0.0;
-  for (i=0; i <= (ssize_t) (strlen(draw_info->text)+2); i++)
+  length=strlen(draw_info->text);
+  for (i=0; i <= (ssize_t) (length+2); i++)
   {
     point.x=fabs(draw_info->affine.sx*i*draw_info->pointsize+
       draw_info->affine.ry*2.0*draw_info->pointsize);
@@ -1744,6 +1777,7 @@ static MagickBooleanType RenderPostscript(Image *image,
   (void) RelinquishUniqueFileResource(filename);
   if (annotate_image == (Image *) NULL)
     return(MagickFalse);
+  (void) NegateImage(annotate_image,MagickFalse,exception);
   resolution.x=DefaultResolution;
   resolution.y=DefaultResolution;
   if (draw_info->density != (char *) NULL)
@@ -1811,9 +1845,9 @@ static MagickBooleanType RenderPostscript(Image *image,
       /*
         Render fill color.
       */
-      if (image->matte == MagickFalse)
+      if (image->alpha_trait == UndefinedPixelTrait)
         (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
-      if (annotate_image->matte == MagickFalse)
+      if (annotate_image->alpha_trait == UndefinedPixelTrait)
         (void) SetImageAlphaChannel(annotate_image,OpaqueAlphaChannel,
           exception);
       fill_color=draw_info->fill;
@@ -1833,9 +1867,8 @@ static MagickBooleanType RenderPostscript(Image *image,
         for (x=0; x < (ssize_t) annotate_image->columns; x++)
         {
           (void) GetFillColor(draw_info,x,y,&fill_color,exception);
-          SetPixelAlpha(annotate_image,ClampToQuantum((((MagickRealType)
-            GetPixelIntensity(annotate_image,q)*fill_color.alpha)/
-            QuantumRange)),q);
+          SetPixelAlpha(annotate_image,ClampToQuantum((((double) QuantumScale*
+            GetPixelIntensity(annotate_image,q)*fill_color.alpha))),q);
           SetPixelRed(annotate_image,fill_color.red,q);
           SetPixelGreen(annotate_image,fill_color.green,q);
           SetPixelBlue(annotate_image,fill_color.blue,q);
@@ -1886,215 +1919,16 @@ static MagickBooleanType RenderPostscript(Image *image,
 %    o exception: return any errors or warnings in this structure.
 %
 */
-#if defined(MAGICKCORE_X11_DELEGATE)
 static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
   const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception)
 {
   MagickBooleanType
     status;
 
-  static DrawInfo
-    cache_info;
-
-  static Display
-    *display = (Display *) NULL;
-
-  static XAnnotateInfo
-    annotate_info;
-
-  static XFontStruct
-    *font_info;
-
-  static XPixelInfo
-    pixel;
-
-  static XResourceInfo
-    resource_info;
-
-  static XrmDatabase
-    resource_database;
-
-  static XStandardColormap
-    *map_info;
-
-  static XVisualInfo
-    *visual_info;
-
-  size_t
-    height,
-    width;
-
   if (annotate_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&annotate_semaphore);
+    ActivateSemaphoreInfo(&annotate_semaphore);
   LockSemaphoreInfo(annotate_semaphore);
-  if (display == (Display *) NULL)
-    {
-      const char
-        *client_name;
-
-      ImageInfo
-        *image_info;
-
-      /*
-        Open X server connection.
-      */
-      display=XOpenDisplay(draw_info->server_name);
-      if (display == (Display *) NULL)
-        {
-          ThrowXWindowException(XServerError,"UnableToOpenXServer",
-            draw_info->server_name);
-          return(MagickFalse);
-        }
-      /*
-        Get user defaults from X resource database.
-      */
-      (void) XSetErrorHandler(XError);
-      image_info=AcquireImageInfo();
-      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);
-      resource_info.background_color=AcquireString("#ffffffffffff");
-      resource_info.foreground_color=AcquireString("#000000000000");
-      map_info=XAllocStandardColormap();
-      if (map_info == (XStandardColormap *) NULL)
-        {
-          ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
-            image->filename);
-          return(MagickFalse);
-        }
-      /*
-        Initialize visual info.
-      */
-      visual_info=XBestVisualInfo(display,map_info,&resource_info);
-      if (visual_info == (XVisualInfo *) NULL)
-        {
-          ThrowXWindowException(XServerError,"UnableToGetVisual",
-            image->filename);
-          return(MagickFalse);
-        }
-      map_info->colormap=(Colormap) NULL;
-      pixel.pixels=(unsigned long *) NULL;
-      /*
-        Initialize Standard Colormap info.
-      */
-      XGetMapInfo(visual_info,XDefaultColormap(display,visual_info->screen),
-        map_info);
-      XGetPixelInfo(display,visual_info,map_info,&resource_info,(Image *) NULL,
-        &pixel);
-      pixel.annotate_context=XDefaultGC(display,visual_info->screen);
-      /*
-        Initialize font info.
-      */
-      font_info=XBestFont(display,&resource_info,MagickFalse);
-      if (font_info == (XFontStruct *) NULL)
-        {
-          ThrowXWindowException(XServerError,"UnableToLoadFont",
-            draw_info->font);
-          return(MagickFalse);
-        }
-      if ((map_info == (XStandardColormap *) NULL) ||
-          (visual_info == (XVisualInfo *) NULL) ||
-          (font_info == (XFontStruct *) NULL))
-        {
-          XFreeResources(display,visual_info,map_info,&pixel,font_info,
-            &resource_info,(XWindowInfo *) NULL);
-          ThrowXWindowException(XServerError,"UnableToLoadFont",
-            image->filename);
-          return(MagickFalse);
-        }
-      cache_info=(*draw_info);
-    }
+  status=XRenderImage(image,draw_info,offset,metrics,exception);
   UnlockSemaphoreInfo(annotate_semaphore);
-  /*
-    Initialize annotate info.
-  */
-  XGetAnnotateInfo(&annotate_info);
-  annotate_info.stencil=ForegroundStencil;
-  if (cache_info.font != draw_info->font)
-    {
-      /*
-        Type name has changed.
-      */
-      (void) XFreeFont(display,font_info);
-      (void) CloneString(&resource_info.font,draw_info->font);
-      font_info=XBestFont(display,&resource_info,MagickFalse);
-      if (font_info == (XFontStruct *) NULL)
-        {
-          ThrowXWindowException(XServerError,"UnableToLoadFont",
-            draw_info->font);
-          return(MagickFalse);
-        }
-    }
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),
-      "Font %s; pointsize %g",draw_info->font != (char *) NULL ?
-      draw_info->font : "none",draw_info->pointsize);
-  cache_info=(*draw_info);
-  annotate_info.font_info=font_info;
-  annotate_info.text=(char *) draw_info->text;
-  annotate_info.width=(unsigned int) XTextWidth(font_info,draw_info->text,
-    (int) strlen(draw_info->text));
-  annotate_info.height=(unsigned int) font_info->ascent+font_info->descent;
-  metrics->pixels_per_em.x=(double) font_info->max_bounds.width;
-  metrics->pixels_per_em.y=(double) font_info->ascent+font_info->descent;
-  metrics->ascent=(double) font_info->ascent+4;
-  metrics->descent=(double) (-font_info->descent);
-  metrics->width=annotate_info.width/ExpandAffine(&draw_info->affine);
-  metrics->height=font_info->ascent+font_info->descent;
-  metrics->max_advance=(double) font_info->max_bounds.width;
-  metrics->bounds.x1=0.0;
-  metrics->bounds.y1=metrics->descent;
-  metrics->bounds.x2=metrics->ascent+metrics->descent;
-  metrics->bounds.y2=metrics->ascent+metrics->descent;
-  metrics->underline_position=(-2.0);
-  metrics->underline_thickness=1.0;
-  if (draw_info->render == MagickFalse)
-    return(MagickTrue);
-  if (draw_info->fill.alpha == TransparentAlpha)
-    return(MagickTrue);
-  /*
-    Render fill color.
-  */
-  width=annotate_info.width;
-  height=annotate_info.height;
-  if ((fabs(draw_info->affine.rx) >= MagickEpsilon) ||
-      (fabs(draw_info->affine.ry) >= MagickEpsilon))
-    {
-      if ((fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) &&
-          (fabs(draw_info->affine.rx+draw_info->affine.ry) < MagickEpsilon))
-        annotate_info.degrees=(double) (180.0/MagickPI)*
-          atan2(draw_info->affine.rx,draw_info->affine.sx);
-    }
-  (void) FormatLocaleString(annotate_info.geometry,MaxTextExtent,
-    "%.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);
-  status=XAnnotateImage(display,&pixel,&annotate_info,image,exception);
-  if (status == 0)
-    {
-      ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
-        image->filename);
-      return(MagickFalse);
-    }
-  return(MagickTrue);
-}
-#else
-static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
-  const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception)
-{
-  (void) draw_info;
-  (void) offset;
-  (void) metrics;
-  (void) ThrowMagickException(exception,GetMagickModule(),
-    MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","'%s' (X11)",
-    image->filename);
-  return(MagickFalse);
+  return(status);
 }
-#endif