]> code.delx.au - gnu-emacs/blobdiff - src/image.c
Fix bug #9475 with alignment in *Completions* buffer.
[gnu-emacs] / src / image.c
index d2a71637fed10b1f2d41a64e9a8119f70a24d41a..db201d5a831ab0b147d705579be59542be955c49 100644 (file)
@@ -56,7 +56,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define COLOR_TABLE_SUPPORT 1
 
 typedef struct x_bitmap_record Bitmap_Record;
-#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
+#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
 #define NO_PIXMAP None
 
 #define RGB_PIXEL_COLOR unsigned long
@@ -74,7 +74,7 @@ typedef struct x_bitmap_record Bitmap_Record;
 #undef COLOR_TABLE_SUPPORT
 
 typedef struct w32_bitmap_record Bitmap_Record;
-#define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
+#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
 #define NO_PIXMAP 0
 
 #define RGB_PIXEL_COLOR COLORREF
@@ -106,7 +106,7 @@ Lisp_Object Qlibpng_version;
 
 typedef struct ns_bitmap_record Bitmap_Record;
 
-#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
+#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
 #define NO_PIXMAP 0
 
 #define RGB_PIXEL_COLOR unsigned long
@@ -115,7 +115,7 @@ typedef struct ns_bitmap_record Bitmap_Record;
 #define PIX_MASK_RETAIN        0
 #define PIX_MASK_DRAW  1
 
-#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO(f)->visual
+#define FRAME_X_VISUAL FRAME_NS_DISPLAY_INFO (f)->visual
 #define x_defined_color(f, name, color_def, alloc) \
   ns_defined_color (f, name, color_def, alloc, 0)
 #define FRAME_X_SCREEN(f) 0
@@ -196,7 +196,8 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
 int
 x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
 {
-  return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
+  /* HAVE_NTGUI needs the explicit cast here.  */
+  return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
 }
 #endif
 
@@ -216,15 +217,6 @@ x_allocate_bitmap_record (FRAME_PTR f)
   Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   ptrdiff_t i;
 
-  if (dpyinfo->bitmaps == NULL)
-    {
-      dpyinfo->bitmaps
-       = (Bitmap_Record *) xmalloc (10 * sizeof (Bitmap_Record));
-      dpyinfo->bitmaps_size = 10;
-      dpyinfo->bitmaps_last = 1;
-      return 1;
-    }
-
   if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
     return ++dpyinfo->bitmaps_last;
 
@@ -232,14 +224,9 @@ x_allocate_bitmap_record (FRAME_PTR f)
     if (dpyinfo->bitmaps[i].refcount == 0)
       return i + 1;
 
-  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2
-      < dpyinfo->bitmaps_size)
-    memory_full (SIZE_MAX);
-  dpyinfo->bitmaps
-    = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps,
-                                 (dpyinfo->bitmaps_size
-                                  * (2 * sizeof (Bitmap_Record))));
-  dpyinfo->bitmaps_size *= 2;
+  dpyinfo->bitmaps =
+    xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
+            10, -1, sizeof *dpyinfo->bitmaps);
   return ++dpyinfo->bitmaps_last;
 }
 
@@ -705,7 +692,7 @@ enum image_value_type
   IMAGE_STRING_OR_NIL_VALUE,
   IMAGE_SYMBOL_VALUE,
   IMAGE_POSITIVE_INTEGER_VALUE,
-  IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,
+  IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
   IMAGE_NON_NEGATIVE_INTEGER_VALUE,
   IMAGE_ASCENT_VALUE,
   IMAGE_INTEGER_VALUE,
@@ -812,12 +799,12 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
            return 0;
          break;
 
-       case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR:
-         if (RANGED_INTEGERP (1, value, INT_MAX))
+       case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
+         if (RANGED_INTEGERP (0, value, INT_MAX))
            break;
          if (CONSP (value)
-             && RANGED_INTEGERP (1, XCAR (value), INT_MAX)
-             && RANGED_INTEGERP (1, XCDR (value), INT_MAX))
+             && RANGED_INTEGERP (0, XCAR (value), INT_MAX)
+             && RANGED_INTEGERP (0, XCDR (value), INT_MAX))
            break;
          return 0;
 
@@ -1055,9 +1042,13 @@ check_image_size (struct frame *f, int width, int height)
            && height <= XINT (Vmax_image_size));
   else if (FLOATP (Vmax_image_size))
     {
-      xassert (f);
-      w = FRAME_PIXEL_WIDTH (f);
-      h = FRAME_PIXEL_HEIGHT (f);
+      if (f != NULL)
+       {
+         w = FRAME_PIXEL_WIDTH (f);
+         h = FRAME_PIXEL_HEIGHT (f);
+       }
+      else
+       w = h = 1024;  /* Arbitrary size for unknown frame. */
       return (width <= XFLOAT_DATA (Vmax_image_size) * w
              && height <= XFLOAT_DATA (Vmax_image_size) * h);
     }
@@ -1115,8 +1106,8 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
             because a typical font is `top-heavy' (due to the presence
             uppercase letters), so the image placement should err towards
             being top-heavy too.  It also just generally looks better.  */
-         ascent = (height + FONT_BASE(face->font)
-                    - FONT_DESCENT(face->font) + 1) / 2;
+         ascent = (height + FONT_BASE (face->font)
+                    - FONT_DESCENT (face->font) + 1) / 2;
 #endif /* HAVE_NTGUI */
        }
       else
@@ -1832,14 +1823,7 @@ cache_image (struct frame *f, struct image *img)
 
   /* If no free slot found, maybe enlarge c->images.  */
   if (i == c->used && c->used == c->size)
-    {
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size)
-       memory_full (SIZE_MAX);
-      c->images =
-       (struct image **) xrealloc (c->images,
-                                   c->size * (2 * sizeof *c->images));
-      c->size *= 2;
-    }
+    c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
 
   /* Add IMG to c->images, and assign IMG an id.  */
   c->images[i] = img;
@@ -2273,7 +2257,7 @@ static const struct image_keyword xbm_format[XBM_LAST] =
   {":foreground",      IMAGE_STRING_OR_NIL_VALUE,              0},
   {":background",      IMAGE_STRING_OR_NIL_VALUE,              0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -3068,7 +3052,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -3586,11 +3570,7 @@ xpm_load (struct frame *f, struct image *img)
 #endif /* HAVE_NTGUI */
 
       /* Remember allocated colors.  */
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors
-         < attrs.nalloc_pixels)
-       memory_full (SIZE_MAX);
-      img->colors = (unsigned long *) xmalloc (img->ncolors
-                                              * sizeof *img->colors);
+      img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
       img->ncolors = attrs.nalloc_pixels;
       for (i = 0; i < attrs.nalloc_pixels; ++i)
        {
@@ -5001,7 +4981,7 @@ static const struct image_keyword pbm_format[PBM_LAST] =
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -5416,7 +5396,7 @@ static const struct image_keyword png_format[PNG_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -5565,7 +5545,7 @@ init_png_functions (Lisp_Object libraries)
 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908)  */
 #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1))
 #define PNG_JMPBUF(ptr) \
-  (*fn_png_set_longjmp_fn((ptr), longjmp, sizeof (jmp_buf)))
+  (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf)))
 #endif
 
 /* Error and warning handlers installed when the PNG library
@@ -5986,9 +5966,9 @@ png_load (struct frame *f, struct image *img)
 static int
 png_load (struct frame *f, struct image *img)
 {
-  return ns_load_image(f, img,
-                       image_spec_value (img->spec, QCfile, NULL),
-                       image_spec_value (img->spec, QCdata, NULL));
+  return ns_load_image (f, img,
+                        image_spec_value (img->spec, QCfile, NULL),
+                        image_spec_value (img->spec, QCdata, NULL));
 }
 #endif  /* HAVE_NS */
 
@@ -6036,7 +6016,7 @@ static const struct image_keyword jpeg_format[JPEG_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversions",     IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -6135,7 +6115,7 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
 
 #else
 
-#define fn_jpeg_CreateDecompress(a,b,c)        jpeg_create_decompress(a)
+#define fn_jpeg_CreateDecompress(a,b,c)        jpeg_create_decompress (a)
 #define fn_jpeg_start_decompress       jpeg_start_decompress
 #define fn_jpeg_finish_decompress      jpeg_finish_decompress
 #define fn_jpeg_destroy_decompress     jpeg_destroy_decompress
@@ -6586,7 +6566,7 @@ static const struct image_keyword tiff_format[TIFF_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversions",     IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -7023,7 +7003,7 @@ static const struct image_keyword gif_format[GIF_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -7168,7 +7148,6 @@ gif_load (struct frame *f, struct image *img)
   ColorMapObject *gif_color_map;
   unsigned long pixel_colors[256];
   GifFileType *gif;
-  int image_height, image_width;
   gif_memory_source memsrc;
   Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
   Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -7245,19 +7224,15 @@ gif_load (struct frame *f, struct image *img)
       }
   }
 
-  img->corners[TOP_CORNER] = gif->SavedImages[idx].ImageDesc.Top;
-  img->corners[LEFT_CORNER] = gif->SavedImages[idx].ImageDesc.Left;
-  image_height = gif->SavedImages[idx].ImageDesc.Height;
-  img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
-  image_width = gif->SavedImages[idx].ImageDesc.Width;
-  img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
+  width = img->width = gif->SWidth;
+  height = img->height = gif->SHeight;
 
-  width = img->width = max (gif->SWidth,
-                           max (gif->Image.Left + gif->Image.Width,
-                                img->corners[RIGHT_CORNER]));
-  height = img->height = max (gif->SHeight,
-                             max (gif->Image.Top + gif->Image.Height,
-                                  img->corners[BOT_CORNER]));
+  img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
+  img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
+  img->corners[BOT_CORNER]
+    = img->corners[TOP_CORNER] + gif->SavedImages[0].ImageDesc.Height;
+  img->corners[RIGHT_CORNER]
+    = img->corners[LEFT_CORNER] + gif->SavedImages[0].ImageDesc.Width;
 
   if (!check_image_size (f, width, height))
     {
@@ -7312,6 +7287,10 @@ gif_load (struct frame *f, struct image *img)
       unsigned char *raster = (unsigned char *) subimage->RasterBits;
       int transparency_color_index = -1;
       int disposal = 0;
+      int subimg_width = subimage->ImageDesc.Width;
+      int subimg_height = subimage->ImageDesc.Height;
+      int subimg_top = subimage->ImageDesc.Top;
+      int subimg_left = subimage->ImageDesc.Left;
 
       /* Find the Graphic Control Extension block for this sub-image.
         Extract the disposal method and transparency color.  */
@@ -7335,6 +7314,13 @@ gif_load (struct frame *f, struct image *img)
       if (j == 0)
        disposal = 2;
 
+      /* For disposal == 0, the spec says "No disposal specified. The
+        decoder is not required to take any action."  In practice, it
+        seems we need to treat this like "keep in place", see e.g.
+        http://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
+      if (disposal == 0)
+       disposal = 1;
+
       /* Allocate subimage colors.  */
       memset (pixel_colors, 0, sizeof pixel_colors);
       gif_color_map = subimage->ImageDesc.ColorMap;
@@ -7362,34 +7348,34 @@ gif_load (struct frame *f, struct image *img)
          int row, pass;
 
          for (y = 0, row = interlace_start[0], pass = 0;
-              y < image_height;
+              y < subimg_height;
               y++, row += interlace_increment[pass])
            {
-             if (row >= image_height)
+             if (row >= subimg_height)
                {
                  row = interlace_start[++pass];
-                 while (row >= image_height)
+                 while (row >= subimg_height)
                    row = interlace_start[++pass];
                }
 
-             for (x = 0; x < image_width; x++)
+             for (x = 0; x < subimg_width; x++)
                {
-                 int c = raster[y * image_width + x];
+                 int c = raster[y * subimg_width + x];
                  if (transparency_color_index != c || disposal != 1)
-                   XPutPixel (ximg, x + img->corners[LEFT_CORNER],
-                              row + img->corners[TOP_CORNER], pixel_colors[c]);
+                   XPutPixel (ximg, x + subimg_left, row + subimg_top,
+                              pixel_colors[c]);
                }
            }
        }
       else
        {
-         for (y = 0; y < image_height; ++y)
-           for (x = 0; x < image_width; ++x)
+         for (y = 0; y < subimg_height; ++y)
+           for (x = 0; x < subimg_width; ++x)
              {
-               int c = raster[y * image_width + x];
+               int c = raster[y * subimg_width + x];
                if (transparency_color_index != c || disposal != 1)
-                 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
-                            y + img->corners[TOP_CORNER], pixel_colors[c]);
+                 XPutPixel (ximg, x + subimg_left, y + subimg_top,
+                            pixel_colors[c]);
              }
        }
     }
@@ -7504,7 +7490,7 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
     {":data",          IMAGE_STRING_VALUE,                     0},
     {":file",          IMAGE_STRING_VALUE,                     0},
     {":ascent",                IMAGE_ASCENT_VALUE,                     0},
-    {":margin",                IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+    {":margin",                IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
     {":relief",                IMAGE_INTEGER_VALUE,                    0},
     {":conversion",    IMAGE_DONT_CHECK_VALUE_TYPE,            0},
     {":heuristic-mask",        IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -7639,7 +7625,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
       return 0;
     }
 
-  if (MagickGetNumberImages(ping_wand) > 1)
+  if (MagickGetNumberImages (ping_wand) > 1)
     img->lisp_data =
       Fcons (Qcount,
              Fcons (make_number (MagickGetNumberImages (ping_wand)),
@@ -7664,7 +7650,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
       if (im_image == NULL)
        goto imagemagick_no_wand;
       image_wand = NewMagickWandFromImage (im_image);
-      DestroyImage(im_image);
+      DestroyImage (im_image);
     }
   else
     {
@@ -7785,7 +7771,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
 #ifdef COLOR_TABLE_SUPPORT
          free_color_table ();
 #endif
-          image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+          image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
           goto imagemagick_error;
         }
 
@@ -7839,7 +7825,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
 #ifdef COLOR_TABLE_SUPPORT
          free_color_table ();
 #endif
-         image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+         image_error ("Imagemagick X bitmap allocation failure", Qnil, Qnil);
          goto imagemagick_error;
        }
 
@@ -8027,7 +8013,7 @@ static const struct image_keyword svg_format[SVG_LAST] =
   {":data",            IMAGE_STRING_VALUE,                     0},
   {":file",            IMAGE_STRING_VALUE,                     0},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},
@@ -8422,7 +8408,7 @@ static const struct image_keyword gs_format[GS_LAST] =
   {":loader",          IMAGE_FUNCTION_VALUE,                   0},
   {":bounding-box",    IMAGE_DONT_CHECK_VALUE_TYPE,            1},
   {":ascent",          IMAGE_ASCENT_VALUE,                     0},
-  {":margin",          IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR,   0},
+  {":margin",          IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
   {":relief",          IMAGE_INTEGER_VALUE,                    0},
   {":conversion",      IMAGE_DONT_CHECK_VALUE_TYPE,            0},
   {":heuristic-mask",  IMAGE_DONT_CHECK_VALUE_TYPE,            0},