]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/annotate.c
(no commit message)
[imagemagick] / MagickCore / annotate.c
index 89ae11b19b9854011efca97ef769c1ceadfc4fa1..ff2a032e570148ee2c3c3746f0454d21ef90a3b6 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2012 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  %
@@ -50,6 +50,7 @@
 #include "MagickCore/client.h"
 #include "MagickCore/color.h"
 #include "MagickCore/color-private.h"
+#include "MagickCore/colorspace-private.h"
 #include "MagickCore/composite.h"
 #include "MagickCore/composite-private.h"
 #include "MagickCore/constitute.h"
@@ -290,6 +291,8 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
     }
   if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
     return(MagickFalse);
+  if (IsGrayColorspace(image->colorspace) != MagickFalse)
+    (void) TransformImageColorspace(image,sRGBColorspace,exception);
   status=MagickTrue;
   for (i=0; textlist[i] != (char *) NULL; i++)
   {
@@ -356,7 +359,6 @@ MagickExport MagickBooleanType AnnotateImage(Image *image,
           (number_lines-1.0)*height)/2.0;
         break;
       }
-      case StaticGravity:
       case CenterGravity:
       {
         offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+
@@ -886,7 +888,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))
@@ -895,7 +897,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,
@@ -1144,7 +1146,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     {
       (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) &&
@@ -1229,7 +1231,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
   metrics->bounds.y2=metrics->ascent+metrics->descent;
   metrics->underline_position=face->underline_position/64.0;
   metrics->underline_thickness=face->underline_thickness/64.0;
-  if (*draw_info->text == '\0')
+  if ((draw_info->text == (char *) NULL) || (*draw_info->text == '\0'))
     {
       (void) FT_Done_Face(face);
       (void) FT_Done_FreeType(library);
@@ -1246,7 +1248,17 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       draw_info->encoding != (char *) NULL ? draw_info->encoding : "none",
       draw_info->pointsize);
   flags=FT_LOAD_NO_BITMAP;
-  value=GetImageProperty(image,"type:hinting");
+  if (draw_info->text_antialias == MagickFalse)
+     flags|=FT_LOAD_TARGET_MONO;
+  else
+    {
+#if defined(FT_LOAD_TARGET_LIGHT)
+      flags|=FT_LOAD_TARGET_LIGHT;
+#elif defined(FT_LOAD_TARGET_LCD)
+      flags|=FT_LOAD_TARGET_LCD;
+#endif
+    }
+  value=GetImageProperty(image,"type:hinting",exception);
   if ((value != (const char *) NULL) && (LocaleCompare(value,"off") == 0))
     flags|=FT_LOAD_NO_HINTING;
   glyph.id=0;
@@ -1302,7 +1314,7 @@ 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 (draw_info->kerning != 0.0)
+        if (fabs(draw_info->kerning) >= MagickEpsilon)
           origin.x+=(FT_Pos) (64.0*direction*draw_info->kerning);
         else
           if (FT_HAS_KERNING(face))
@@ -1328,13 +1340,13 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
     if (status != 0)
       continue;
     if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1))
-      metrics->bounds.x1=bounds.xMin;
+      metrics->bounds.x1=(double) bounds.xMin;
     if ((p == draw_info->text) || (bounds.yMin < metrics->bounds.y1))
-      metrics->bounds.y1=bounds.yMin;
+      metrics->bounds.y1=(double) bounds.yMin;
     if ((p == draw_info->text) || (bounds.xMax > metrics->bounds.x2))
-      metrics->bounds.x2=bounds.xMax;
+      metrics->bounds.x2=(double) bounds.xMax;
     if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2))
-      metrics->bounds.y2=bounds.yMax;
+      metrics->bounds.y2=(double) bounds.yMax;
     if (draw_info->render != MagickFalse)
       if ((draw_info->stroke.alpha != TransparentAlpha) ||
           (draw_info->stroke_pattern != (Image *) NULL))
@@ -1373,7 +1385,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
           Rasterize the glyph.
         */
         status=MagickTrue;
-        image_view=AcquireCacheView(image);
+        image_view=AcquireAuthenticCacheView(image,exception);
         p=bitmap->bitmap.buffer;
         for (y=0; y < (ssize_t) bitmap->bitmap.rows; y++)
         {
@@ -1384,7 +1396,7 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
           MagickRealType
             fill_opacity;
 
-          PixelPacket
+          PixelInfo
             fill_color;
 
           register Quantum
@@ -1438,7 +1450,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
                 q+=GetPixelChannels(image);
                 continue;
               }
-            (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color);
+            GetPixelInfo(image,&fill_color);
+            (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color,
+              exception);
             fill_opacity=fill_opacity*fill_color.alpha;
             CompositePixelOver(image,&fill_color,fill_opacity,q,
               GetPixelAlpha(image,q),q);
@@ -1458,14 +1472,14 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       }
     if ((bitmap->left+bitmap->bitmap.width) > metrics->width)
       metrics->width=bitmap->left+bitmap->bitmap.width;
-    if ((draw_info->interword_spacing != 0.0) &&
+    if ((fabs(draw_info->interword_spacing) >= MagickEpsilon) &&
         (IsUTFSpace(GetUTFCode(p)) != MagickFalse) &&
         (IsUTFSpace(code) == MagickFalse))
       origin.x+=(FT_Pos) (64.0*direction*draw_info->interword_spacing);
     else
       origin.x+=(FT_Pos) (direction*face->glyph->advance.x);
-    metrics->origin.x=origin.x;
-    metrics->origin.y=origin.y;
+    metrics->origin.x=(double) origin.x;
+    metrics->origin.y=(double) origin.y;
     if (last_glyph.id != 0)
       FT_Done_Glyph(last_glyph.image);
     last_glyph=glyph;
@@ -1501,8 +1515,8 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
       status=FT_Get_Glyph(face->glyph,&glyph.image);
       if (status == 0)
         {
-          status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->
-            outline,&bounds);
+          status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline,
+            &bounds);
           if (status == 0)
             {
               FT_Vector_Transform(&glyph.origin,&affine);
@@ -1537,9 +1551,9 @@ static MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info,
   TypeMetric *metrics,ExceptionInfo *exception)
 {
   (void) ThrowMagickException(exception,GetMagickModule(),
-    MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","`%s' (Freetype)",
+    MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","'%s' (Freetype)",
     draw_info->font != (char *) NULL ? draw_info->font : "none");
-  return(RenderPostscript(image,draw_info,offset,metrics));
+  return(RenderPostscript(image,draw_info,offset,metrics,exception));
 }
 #endif
 \f
@@ -1676,9 +1690,9 @@ static MagickBooleanType RenderPostscript(Image *image,
   /*
     Sample to compute bounding box.
   */
-  identity=(draw_info->affine.sx == draw_info->affine.sy) &&
-    (draw_info->affine.rx == 0.0) && (draw_info->affine.ry == 0.0) ?
-    MagickTrue : MagickFalse;
+  identity=(fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) &&
+    (fabs(draw_info->affine.rx) < MagickEpsilon) &&
+    (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++)
@@ -1747,7 +1761,7 @@ static MagickBooleanType RenderPostscript(Image *image,
         resolution.y=resolution.x;
     }
   if (identity == MagickFalse)
-    (void) TransformImage(&annotate_image,"0x0",(char *) NULL);
+    (void) TransformImage(&annotate_image,"0x0",(char *) NULL,exception);
   else
     {
       RectangleInfo
@@ -1761,7 +1775,7 @@ static MagickBooleanType RenderPostscript(Image *image,
       (void) FormatLocaleString(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);
+      (void) TransformImage(&annotate_image,geometry,(char *) NULL,exception);
     }
   metrics->pixels_per_em.x=(resolution.y/DefaultResolution)*
     ExpandAffine(&draw_info->affine)*draw_info->pointsize;
@@ -1785,15 +1799,15 @@ static MagickBooleanType RenderPostscript(Image *image,
     }
   if (draw_info->fill.alpha != TransparentAlpha)
     {
+      CacheView
+        *annotate_view;
+
       MagickBooleanType
         sync;
 
-      PixelPacket
+      PixelInfo
         fill_color;
 
-      CacheView
-        *annotate_view;
-
       /*
         Render fill color.
       */
@@ -1803,7 +1817,7 @@ static MagickBooleanType RenderPostscript(Image *image,
         (void) SetImageAlphaChannel(annotate_image,OpaqueAlphaChannel,
           exception);
       fill_color=draw_info->fill;
-      annotate_view=AcquireCacheView(annotate_image);
+      annotate_view=AcquireAuthenticCacheView(annotate_image,exception);
       for (y=0; y < (ssize_t) annotate_image->rows; y++)
       {
         register ssize_t
@@ -1818,7 +1832,7 @@ static MagickBooleanType RenderPostscript(Image *image,
           break;
         for (x=0; x < (ssize_t) annotate_image->columns; x++)
         {
-          (void) GetFillColor(draw_info,x,y,&fill_color);
+          (void) GetFillColor(draw_info,x,y,&fill_color,exception);
           SetPixelAlpha(annotate_image,ClampToQuantum((((MagickRealType)
             GetPixelIntensity(annotate_image,q)*fill_color.alpha)/
             QuantumRange)),q);
@@ -1832,9 +1846,9 @@ static MagickBooleanType RenderPostscript(Image *image,
           break;
       }
       annotate_view=DestroyCacheView(annotate_view);
-      (void) CompositeImage(image,OverCompositeOp,annotate_image,
+      (void) CompositeImage(image,annotate_image,OverCompositeOp,MagickTrue,
         (ssize_t) ceil(offset->x-0.5),(ssize_t) ceil(offset->y-(metrics->ascent+
-        metrics->descent)-0.5));
+        metrics->descent)-0.5),exception);
     }
   annotate_image=DestroyImage(annotate_image);
   return(MagickTrue);
@@ -1938,7 +1952,8 @@ static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
       image_info=AcquireImageInfo();
       client_name=GetClientName();
       resource_database=XGetResourceDatabase(display,client_name);
-      XGetResourceInfo(image_info,resource_database,client_name,&resource_info);
+      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);
@@ -2046,11 +2061,12 @@ static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
   */
   width=annotate_info.width;
   height=annotate_info.height;
-  if ((draw_info->affine.rx != 0.0) || (draw_info->affine.ry != 0.0))
+  if ((fabs(draw_info->affine.rx) >= MagickEpsilon) ||
+      (fabs(draw_info->affine.ry) >= MagickEpsilon))
     {
-      if (((draw_info->affine.sx-draw_info->affine.sy) == 0.0) &&
-          ((draw_info->affine.rx+draw_info->affine.ry) == 0.0))
-        annotate_info.degrees=(180.0/MagickPI)*
+      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,
@@ -2060,7 +2076,7 @@ static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
   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);
+  status=XAnnotateImage(display,&pixel,&annotate_info,image,exception);
   if (status == 0)
     {
       ThrowXWindowException(ResourceLimitError,"MemoryAllocationFailed",
@@ -2077,7 +2093,7 @@ static MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info,
   (void) offset;
   (void) metrics;
   (void) ThrowMagickException(exception,GetMagickModule(),
-    MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (X11)",
+    MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","'%s' (X11)",
     image->filename);
   return(MagickFalse);
 }