]> granicus.if.org Git - imagemagick/blobdiff - coders/pango.c
Allow older versions of SVG library
[imagemagick] / coders / pango.c
index cea5f5697047bebddc8b9d0d2111a573f90a6ad5..e4e1cb237c7241ef7d52dc8fb389d198ef65cbd2 100644 (file)
@@ -17,7 +17,7 @@
 %                                 March 2012                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2013 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  %
@@ -111,7 +111,7 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
     *property;
 
   cairo_t
-    *cairo_info;
+    *cairo_image;
 
   const char
     *option;
@@ -149,12 +149,12 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
   RectangleInfo
     page;
 
-  register Quantum
-    *q;
-
   register unsigned char
     *p;
 
+  size_t
+    stride;
+
   ssize_t
     y;
 
@@ -193,7 +193,7 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
   */
   fontmap=pango_cairo_font_map_new();
   pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap),
-    image->resolution.x);
+    image->resolution.x == 0.0 ? 90.0 : image->resolution.x);
   font_options=cairo_font_options_create();
   option=GetImageOption(image_info,"pango:hinting");
   if (option != (const char *) NULL)
@@ -205,6 +205,7 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
     }
   context=pango_font_map_create_context(fontmap);
   pango_cairo_context_set_font_options(context,font_options);
+  cairo_font_options_destroy(font_options);
   option=GetImageOption(image_info,"pango:language");
   if (option != (const char *) NULL)
     pango_context_set_language(context,pango_language_from_string(option));
@@ -213,11 +214,35 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
     RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
   switch (draw_info->gravity)
   {
-    case NorthGravity: gravity=PANGO_GRAVITY_NORTH; break;
-    case WestGravity: gravity=PANGO_GRAVITY_WEST; break;
-    case EastGravity: gravity=PANGO_GRAVITY_EAST; break;
-    case SouthGravity: gravity=PANGO_GRAVITY_SOUTH; break;
-    default: gravity=PANGO_GRAVITY_AUTO; break;
+    case NorthGravity:
+    {
+      gravity=PANGO_GRAVITY_NORTH;
+      break;
+    }
+    case NorthWestGravity:
+    case WestGravity:
+    case SouthWestGravity:
+    {
+      gravity=PANGO_GRAVITY_WEST;
+      break;
+    }
+    case NorthEastGravity:
+    case EastGravity:
+    case SouthEastGravity:
+    {
+      gravity=PANGO_GRAVITY_EAST;
+      break;
+    }
+    case SouthGravity:
+    {
+      gravity=PANGO_GRAVITY_SOUTH;
+      break;
+    }
+    default:
+    {
+      gravity=PANGO_GRAVITY_AUTO;
+      break;
+    }
   }
   pango_context_set_base_gravity(context,gravity);
   option=GetImageOption(image_info,"pango:gravity-hint");
@@ -250,10 +275,10 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
         pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START);
     }
   option=GetImageOption(image_info,"pango:justify");
-  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
+  if (IfMagickTrue(IsStringTrue(option)))
     pango_layout_set_justify(layout,1);
   option=GetImageOption(image_info,"pango:single-paragraph");
-  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
+  if (IfMagickTrue(IsStringTrue(option)))
     pango_layout_set_single_paragraph_mode(layout,1);
   option=GetImageOption(image_info,"pango:wrap");
   if (option != (const char *) NULL)
@@ -268,7 +293,8 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
   option=GetImageOption(image_info,"pango:indent");
   if (option != (const char *) NULL)
     pango_layout_set_indent(layout,(int) ((StringToLong(option)*
-      image->resolution.x*PANGO_SCALE+36)/72.0+0.5));
+      (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)*PANGO_SCALE+36)/
+      90.0+0.5));
   switch (draw_info->align)
   {
     case CenterAlign: align=PANGO_ALIGN_CENTER; break;
@@ -304,7 +330,7 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
       pango_font_description_free(description);
     }
   option=GetImageOption(image_info,"pango:markup");
-  if ((option != (const char *) NULL) && (IsMagickTrue(option) == MagickFalse))
+  if ((option != (const char *) NULL) && (IsStringTrue(option) == MagickFalse))
     pango_layout_set_text(layout,caption,-1);
   else
     {
@@ -324,80 +350,88 @@ static Image *ReadPANGOImage(const ImageInfo *image_info,
     (void) ParseAbsoluteGeometry(image_info->page,&page);
   if (image->columns == 0)
     {
-      pango_layout_get_pixel_extents(layout,NULL,&extent);
-      image->columns=extent.x+extent.width;
+      pango_layout_get_extents(layout,NULL,&extent);
+      image->columns=(extent.x+extent.width+PANGO_SCALE/2)/PANGO_SCALE+2*page.x;
     }
   else
     {
       image->columns-=2*page.x;
       pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns*
-        image->resolution.x+36.0)/72.0+0.5));
+        (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)+45.0)/90.0+
+        0.5));
     }
   if (image->rows == 0)
     {
-      pango_layout_get_pixel_extents(layout,NULL,&extent);
-      image->rows=extent.y+extent.height;
+      pango_layout_get_extents(layout,NULL,&extent);
+      image->rows=(extent.y+extent.height+PANGO_SCALE/2)/PANGO_SCALE+2*page.y;
     }
   else
     {
       image->rows-=2*page.y;
       pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows*
-        image->resolution.y+36.0)/72.0+0.5));
+        (image->resolution.y == 0.0 ? 90.0 : image->resolution.y)+45.0)/90.0+
+        0.5));
     }
   /*
-    Create canvas.
+    Render markup.
   */
-  pixels=(unsigned char *) AcquireQuantumMemory(image->columns,4*
-    image->rows*sizeof(*pixels));
+  stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
+    image->columns);
+  pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride*
+    sizeof(*pixels));
   if (pixels == (unsigned char *) NULL)
-    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+    {
+      draw_info=DestroyDrawInfo(draw_info);
+      caption=DestroyString(caption);
+      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+    }
   surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32,
-    image->columns,image->rows,4*image->columns);
-  cairo_info=cairo_create(surface);
-  cairo_set_operator(cairo_info,CAIRO_OPERATOR_CLEAR);
-  cairo_paint(cairo_info);
-  cairo_set_operator(cairo_info,CAIRO_OPERATOR_OVER);
-  if (draw_info->fill.matte == MagickFalse)
-    cairo_set_source_rgb(cairo_info,QuantumScale*draw_info->fill.red,
-      QuantumScale*draw_info->fill.green,QuantumScale*draw_info->fill.blue);
-  else
-    cairo_set_source_rgba(cairo_info,QuantumScale*draw_info->fill.red,
-      QuantumScale*draw_info->fill.green,QuantumScale*draw_info->fill.blue,
-      QuantumScale*draw_info->fill.alpha);
-  pango_cairo_show_layout(cairo_info,layout);
-  cairo_destroy(cairo_info);
+    image->columns,image->rows,stride);
+  cairo_image=cairo_create(surface);
+  cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR);
+  cairo_paint(cairo_image);
+  cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER);
+  cairo_translate(cairo_image,page.x,page.y);
+  pango_cairo_show_layout(cairo_image,layout);
+  cairo_destroy(cairo_image);
   cairo_surface_destroy(surface);
+  g_object_unref(layout);
   g_object_unref(fontmap);
   /*
-    Convert caption to image.
+    Convert surface to image.
   */
   (void) SetImageBackgroundColor(image,exception);
   p=pixels;
   GetPixelInfo(image,&fill_color);
   for (y=0; y < (ssize_t) image->rows; y++)
   {
-    register ssize_t x;
+    register Quantum
+      *q;
+
+    register ssize_t
+      x;
 
     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
     if (q == (Quantum *) NULL)
       break;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      fill_color.blue=ScaleCharToQuantum(*p++);
-      fill_color.green=ScaleCharToQuantum(*p++);
-      fill_color.red=ScaleCharToQuantum(*p++);
-      fill_color.alpha=ScaleCharToQuantum(*p++);
-      {
-        double
-          gamma;
-    
-        gamma=1.0-QuantumScale*fill_color.alpha;
-        gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
-        fill_color.blue*=gamma;
-        fill_color.green*=gamma;
-        fill_color.red*=gamma;
-      }
-      CompositePixelOver(image,&fill_color,fill_color.alpha,q,(MagickRealType)
+      double
+        gamma;
+
+      fill_color.blue=(double) ScaleCharToQuantum(*p++);
+      fill_color.green=(double) ScaleCharToQuantum(*p++);
+      fill_color.red=(double) ScaleCharToQuantum(*p++);
+      fill_color.alpha=(double) ScaleCharToQuantum(*p++);
+      /*
+        Disassociate alpha.
+      */
+      gamma=1.0-QuantumScale*fill_color.alpha;
+      gamma=PerceptibleReciprocal(gamma);
+      fill_color.blue*=gamma;
+      fill_color.green*=gamma;
+      fill_color.red*=gamma;
+      CompositePixelOver(image,&fill_color,fill_color.alpha,q,(double)
         GetPixelAlpha(image,q),q);
       q+=GetPixelChannels(image);
     }