aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim F. Storm2006-04-21 14:07:05 +0000
committerKim F. Storm2006-04-21 14:07:05 +0000
commit6ac3c7bb025ec4b37ca61c632c05d479cbfb6eb2 (patch)
treefd108f706bda4ac088465a4de7f1b32da19a236b
parent7b48cc1354a2efff9fb528c1b3c78f47d001178e (diff)
downloademacs-6ac3c7bb025ec4b37ca61c632c05d479cbfb6eb2.tar.gz
emacs-6ac3c7bb025ec4b37ca61c632c05d479cbfb6eb2.zip
(four_corners_best): New arg CORNERS specifies what pixels
to look at in case image has margin. (x_create_bitmap_mask): Pass NULL for CORNERS to four_corners_best. (image_background, image_background_transparent) (x_build_heuristic_mask): Pass img->corners to four_corners_best. (gif_load): Set img->corners according to image's margin spec. Use img->corners values directly where applicable. Save image extension data in img->data.lisp_val. (gif_clear_image): New function to free img->data.lisp_val. (gif_type): Use it instead of generic x_clear_image. (Fimage_extension_data): New defun. (syms_of_image): Defsubr it.
-rw-r--r--src/image.c132
1 files changed, 101 insertions, 31 deletions
diff --git a/src/image.c b/src/image.c
index e1962d87b0f..688ff200055 100644
--- a/src/image.c
+++ b/src/image.c
@@ -603,7 +603,9 @@ x_destroy_all_bitmaps (dpyinfo)
603/* Useful functions defined in the section 603/* Useful functions defined in the section
604 `Image type independent image structures' below. */ 604 `Image type independent image structures' below. */
605 605
606static unsigned long four_corners_best P_ ((XImagePtr ximg, unsigned long width, 606static unsigned long four_corners_best P_ ((XImagePtr ximg,
607 int *corners,
608 unsigned long width,
607 unsigned long height)); 609 unsigned long height));
608 610
609static int x_create_x_image_and_pixmap P_ ((struct frame *f, int width, int height, 611static int x_create_x_image_and_pixmap P_ ((struct frame *f, int width, int height,
@@ -657,7 +659,7 @@ x_create_bitmap_mask (f, id)
657 return -1; 659 return -1;
658 } 660 }
659 661
660 bg = four_corners_best (ximg, width, height); 662 bg = four_corners_best (ximg, NULL, width, height);
661 663
662 for (y = 0; y < ximg->height; ++y) 664 for (y = 0; y < ximg->height; ++y)
663 { 665 {
@@ -732,7 +734,7 @@ Lisp_Object Qxbm;
732/* Keywords. */ 734/* Keywords. */
733 735
734extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile; 736extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
735extern Lisp_Object QCdata, QCtype; 737extern Lisp_Object QCdata, QCtype, Qcount;
736extern Lisp_Object Qcenter; 738extern Lisp_Object Qcenter;
737Lisp_Object QCascent, QCmargin, QCrelief; 739Lisp_Object QCascent, QCmargin, QCrelief;
738Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; 740Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
@@ -1141,6 +1143,27 @@ or omitted means use the selected frame. */)
1141 return mask; 1143 return mask;
1142} 1144}
1143 1145
1146DEFUN ("image-extension-data", Fimage_extension_data, Simage_extension_data, 1, 2, 0,
1147 doc: /* Return extension data for image SPEC.
1148FRAME is the frame on which the image will be displayed. FRAME nil
1149or omitted means use the selected frame. */)
1150 (spec, frame)
1151 Lisp_Object spec, frame;
1152{
1153 Lisp_Object ext;
1154
1155 ext = Qnil;
1156 if (valid_image_p (spec))
1157 {
1158 struct frame *f = check_x_frame (frame);
1159 int id = lookup_image (f, spec);
1160 struct image *img = IMAGE_FROM_ID (f, id);
1161 ext = img->data.lisp_val;
1162 }
1163
1164 return ext;
1165}
1166
1144 1167
1145/*********************************************************************** 1168/***********************************************************************
1146 Image type independent image structures 1169 Image type independent image structures
@@ -1171,6 +1194,7 @@ make_image (spec, hash)
1171 img->data.lisp_val = Qnil; 1194 img->data.lisp_val = Qnil;
1172 img->ascent = DEFAULT_IMAGE_ASCENT; 1195 img->ascent = DEFAULT_IMAGE_ASCENT;
1173 img->hash = hash; 1196 img->hash = hash;
1197 img->corners[BOT_CORNER] = -1; /* Full image */
1174 return img; 1198 return img;
1175} 1199}
1176 1200
@@ -1322,30 +1346,41 @@ image_ascent (img, face, slice)
1322 On W32, XIMG is assumed to a device context with the bitmap selected. */ 1346 On W32, XIMG is assumed to a device context with the bitmap selected. */
1323 1347
1324static RGB_PIXEL_COLOR 1348static RGB_PIXEL_COLOR
1325four_corners_best (ximg, width, height) 1349four_corners_best (ximg, corners, width, height)
1326 XImagePtr_or_DC ximg; 1350 XImagePtr_or_DC ximg;
1351 int *corners;
1327 unsigned long width, height; 1352 unsigned long width, height;
1328{ 1353{
1329 RGB_PIXEL_COLOR corners[4], best; 1354 RGB_PIXEL_COLOR corner_pixels[4], best;
1330 int i, best_count; 1355 int i, best_count;
1331 1356
1332 /* Get the colors at the corners of ximg. */ 1357 if (corners && corners[BOT_CORNER] >= 0)
1333 corners[0] = GET_PIXEL (ximg, 0, 0); 1358 {
1334 corners[1] = GET_PIXEL (ximg, width - 1, 0); 1359 /* Get the colors at the corner_pixels of ximg. */
1335 corners[2] = GET_PIXEL (ximg, width - 1, height - 1); 1360 corner_pixels[0] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[TOP_CORNER]);
1336 corners[3] = GET_PIXEL (ximg, 0, height - 1); 1361 corner_pixels[1] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
1337 1362 corner_pixels[2] = GET_PIXEL (ximg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
1363 corner_pixels[3] = GET_PIXEL (ximg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
1364 }
1365 else
1366 {
1367 /* Get the colors at the corner_pixels of ximg. */
1368 corner_pixels[0] = GET_PIXEL (ximg, 0, 0);
1369 corner_pixels[1] = GET_PIXEL (ximg, width - 1, 0);
1370 corner_pixels[2] = GET_PIXEL (ximg, width - 1, height - 1);
1371 corner_pixels[3] = GET_PIXEL (ximg, 0, height - 1);
1372 }
1338 /* Choose the most frequently found color as background. */ 1373 /* Choose the most frequently found color as background. */
1339 for (i = best_count = 0; i < 4; ++i) 1374 for (i = best_count = 0; i < 4; ++i)
1340 { 1375 {
1341 int j, n; 1376 int j, n;
1342 1377
1343 for (j = n = 0; j < 4; ++j) 1378 for (j = n = 0; j < 4; ++j)
1344 if (corners[i] == corners[j]) 1379 if (corner_pixels[i] == corner_pixels[j])
1345 ++n; 1380 ++n;
1346 1381
1347 if (n > best_count) 1382 if (n > best_count)
1348 best = corners[i], best_count = n; 1383 best = corner_pixels[i], best_count = n;
1349 } 1384 }
1350 1385
1351 return best; 1386 return best;
@@ -1404,7 +1439,7 @@ image_background (img, f, ximg)
1404#endif /* !HAVE_NTGUI */ 1439#endif /* !HAVE_NTGUI */
1405 } 1440 }
1406 1441
1407 img->background = four_corners_best (ximg, img->width, img->height); 1442 img->background = four_corners_best (ximg, img->corners, img->width, img->height);
1408 1443
1409 if (free_ximg) 1444 if (free_ximg)
1410 Destroy_Image (ximg, prev); 1445 Destroy_Image (ximg, prev);
@@ -1449,7 +1484,7 @@ image_background_transparent (img, f, mask)
1449 } 1484 }
1450 1485
1451 img->background_transparent 1486 img->background_transparent
1452 = (four_corners_best (mask, img->width, img->height) == PIX_MASK_RETAIN); 1487 = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN);
1453 1488
1454 if (free_mask) 1489 if (free_mask)
1455 Destroy_Image (mask, prev); 1490 Destroy_Image (mask, prev);
@@ -5358,7 +5393,7 @@ x_build_heuristic_mask (f, img, how)
5358 } 5393 }
5359 5394
5360 if (use_img_background) 5395 if (use_img_background)
5361 bg = four_corners_best (ximg, img->width, img->height); 5396 bg = four_corners_best (ximg, img->corners, img->width, img->height);
5362 5397
5363 /* Set all bits in mask_img to 1 whose color in ximg is different 5398 /* Set all bits in mask_img to 1 whose color in ximg is different
5364 from the background color bg. */ 5399 from the background color bg. */
@@ -7451,6 +7486,7 @@ tiff_load (f, img)
7451 7486
7452static int gif_image_p P_ ((Lisp_Object object)); 7487static int gif_image_p P_ ((Lisp_Object object));
7453static int gif_load P_ ((struct frame *f, struct image *img)); 7488static int gif_load P_ ((struct frame *f, struct image *img));
7489static void gif_clear_image P_ ((struct frame *f, struct image *img));
7454 7490
7455/* The symbol `gif' identifying images of this type. */ 7491/* The symbol `gif' identifying images of this type. */
7456 7492
@@ -7499,10 +7535,22 @@ static struct image_type gif_type =
7499 &Qgif, 7535 &Qgif,
7500 gif_image_p, 7536 gif_image_p,
7501 gif_load, 7537 gif_load,
7502 x_clear_image, 7538 gif_clear_image,
7503 NULL 7539 NULL
7504}; 7540};
7505 7541
7542/* Free X resources of GIF image IMG which is used on frame F. */
7543
7544static void
7545gif_clear_image (f, img)
7546 struct frame *f;
7547 struct image *img;
7548{
7549 /* IMG->data.ptr_val may contain extension data. */
7550 img->data.lisp_val = Qnil;
7551 x_clear_image (f, img);
7552}
7553
7506/* Return non-zero if OBJECT is a valid GIF image specification. */ 7554/* Return non-zero if OBJECT is a valid GIF image specification. */
7507 7555
7508static int 7556static int
@@ -7623,7 +7671,7 @@ gif_load (f, img)
7623 GifFileType *gif; 7671 GifFileType *gif;
7624 struct gcpro gcpro1; 7672 struct gcpro gcpro1;
7625 Lisp_Object image; 7673 Lisp_Object image;
7626 int ino, image_left, image_top, image_width, image_height; 7674 int ino, image_height, image_width;
7627 gif_memory_source memsrc; 7675 gif_memory_source memsrc;
7628 unsigned char *raster; 7676 unsigned char *raster;
7629 7677
@@ -7700,17 +7748,19 @@ gif_load (f, img)
7700 return 0; 7748 return 0;
7701 } 7749 }
7702 7750
7703 image_top = gif->SavedImages[ino].ImageDesc.Top; 7751 img->corners[TOP_CORNER] = gif->SavedImages[ino].ImageDesc.Top;
7704 image_left = gif->SavedImages[ino].ImageDesc.Left; 7752 img->corners[LEFT_CORNER] = gif->SavedImages[ino].ImageDesc.Left;
7705 image_width = gif->SavedImages[ino].ImageDesc.Width;
7706 image_height = gif->SavedImages[ino].ImageDesc.Height; 7753 image_height = gif->SavedImages[ino].ImageDesc.Height;
7754 img->corners[BOT_CORNER] = img->corners[TOP_CORNER] + image_height;
7755 image_width = gif->SavedImages[ino].ImageDesc.Width;
7756 img->corners[RIGHT_CORNER] = img->corners[LEFT_CORNER] + image_width;
7707 7757
7708 width = img->width = max (gif->SWidth, 7758 width = img->width = max (gif->SWidth,
7709 max (gif->Image.Left + gif->Image.Width, 7759 max (gif->Image.Left + gif->Image.Width,
7710 image_left + image_width)); 7760 img->corners[RIGHT_CORNER]));
7711 height = img->height = max (gif->SHeight, 7761 height = img->height = max (gif->SHeight,
7712 max (gif->Image.Top + gif->Image.Height, 7762 max (gif->Image.Top + gif->Image.Height,
7713 image_top + image_height)); 7763 img->corners[BOT_CORNER]));
7714 7764
7715 if (!check_image_size (f, width, height)) 7765 if (!check_image_size (f, width, height))
7716 { 7766 {
@@ -7753,19 +7803,19 @@ gif_load (f, img)
7753 requires more than can be done here (see the gif89 spec, 7803 requires more than can be done here (see the gif89 spec,
7754 disposal methods). Let's simply assume that the part 7804 disposal methods). Let's simply assume that the part
7755 not covered by a sub-image is in the frame's background color. */ 7805 not covered by a sub-image is in the frame's background color. */
7756 for (y = 0; y < image_top; ++y) 7806 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
7757 for (x = 0; x < width; ++x) 7807 for (x = 0; x < width; ++x)
7758 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7808 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7759 7809
7760 for (y = image_top + image_height; y < height; ++y) 7810 for (y = img->corners[BOT_CORNER]; y < height; ++y)
7761 for (x = 0; x < width; ++x) 7811 for (x = 0; x < width; ++x)
7762 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7812 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7763 7813
7764 for (y = image_top; y < image_top + image_height; ++y) 7814 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
7765 { 7815 {
7766 for (x = 0; x < image_left; ++x) 7816 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
7767 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7817 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7768 for (x = image_left + image_width; x < width; ++x) 7818 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7769 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7819 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7770 } 7820 }
7771 7821
@@ -7795,8 +7845,8 @@ gif_load (f, img)
7795 for (x = 0; x < image_width; x++) 7845 for (x = 0; x < image_width; x++)
7796 { 7846 {
7797 int i = raster[(y * image_width) + x]; 7847 int i = raster[(y * image_width) + x];
7798 XPutPixel (ximg, x + image_left, row + image_top, 7848 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7799 pixel_colors[i]); 7849 row + img->corners[TOP_CORNER], pixel_colors[i]);
7800 } 7850 }
7801 7851
7802 row += interlace_increment[pass]; 7852 row += interlace_increment[pass];
@@ -7808,10 +7858,29 @@ gif_load (f, img)
7808 for (x = 0; x < image_width; ++x) 7858 for (x = 0; x < image_width; ++x)
7809 { 7859 {
7810 int i = raster[y * image_width + x]; 7860 int i = raster[y * image_width + x];
7811 XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]); 7861 XPutPixel (ximg, x + img->corners[LEFT_CORNER],
7862 y + img->corners[TOP_CORNER], pixel_colors[i]);
7812 } 7863 }
7813 } 7864 }
7814 7865
7866 /* Save GIF image extension data for `image-extension-data'.
7867 Format is (count IMAGES FUNCTION "BYTES" ...). */
7868 img->data.lisp_val = Qnil;
7869 if (gif->SavedImages[ino].ExtensionBlockCount > 0)
7870 {
7871 ExtensionBlock *ext = gif->SavedImages[ino].ExtensionBlocks;
7872 for (i = 0; i < gif->SavedImages[ino].ExtensionBlockCount; i++, ext++)
7873 /* Append (... FUNCTION "BYTES") */
7874 img->data.lisp_val = Fcons (make_unibyte_string (ext->Bytes, ext->ByteCount),
7875 Fcons (make_number (ext->Function),
7876 img->data.lisp_val));
7877 img->data.lisp_val = Fnreverse (img->data.lisp_val);
7878 }
7879 if (gif->ImageCount > 1)
7880 img->data.lisp_val = Fcons (Qcount,
7881 Fcons (make_number (gif->ImageCount),
7882 img->data.lisp_val));
7883
7815 fn_DGifCloseFile (gif); 7884 fn_DGifCloseFile (gif);
7816 7885
7817 /* Maybe fill in the background field while we have ximg handy. */ 7886 /* Maybe fill in the background field while we have ximg handy. */
@@ -8557,6 +8626,7 @@ non-numeric, there is no explicit limit on the size of images. */);
8557 defsubr (&Sclear_image_cache); 8626 defsubr (&Sclear_image_cache);
8558 defsubr (&Simage_size); 8627 defsubr (&Simage_size);
8559 defsubr (&Simage_mask_p); 8628 defsubr (&Simage_mask_p);
8629 defsubr (&Simage_extension_data);
8560 8630
8561#if GLYPH_DEBUG 8631#if GLYPH_DEBUG
8562 defsubr (&Simagep); 8632 defsubr (&Simagep);