Mercurial > emacs
comparison src/xfns.c @ 31651:aef83f9e7dac
(lookup_image): Build mask before applying an algorithm.
Recognize algorithm `disabled'.
(cross_disabled_images): New variable.
(COLOR_INTENSITY): New macro.
(x_detect_edges): Use COLOR_INTENSITY.
(x_disable_image): New function.
(syms_of_xfns): DEFVAR_BOOL cross_disabled_images.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Fri, 15 Sep 2000 21:01:29 +0000 |
parents | c1f4bdbf8465 |
children | 577372d71de8 |
comparison
equal
deleted
inserted
replaced
31650:8b3846ae64fe | 31651:aef83f9e7dac |
---|---|
742 { | 742 { |
743 char *name; | 743 char *name; |
744 void (*setter) P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 744 void (*setter) P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
745 }; | 745 }; |
746 | 746 |
747 static void x_disable_image P_ ((struct frame *, struct image *)); | |
747 static void x_create_im P_ ((struct frame *)); | 748 static void x_create_im P_ ((struct frame *)); |
748 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 749 void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
749 static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 750 static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
750 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 751 void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
751 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); | 752 void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
5758 } | 5759 } |
5759 else | 5760 else |
5760 { | 5761 { |
5761 /* Handle image type independent image attributes | 5762 /* Handle image type independent image attributes |
5762 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF'. */ | 5763 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF'. */ |
5763 Lisp_Object ascent, margin, relief, algorithm; | 5764 Lisp_Object ascent, margin, relief; |
5764 Lisp_Object file; | 5765 Lisp_Object file; |
5765 | 5766 |
5766 ascent = image_spec_value (spec, QCascent, NULL); | 5767 ascent = image_spec_value (spec, QCascent, NULL); |
5767 if (INTEGERP (ascent)) | 5768 if (INTEGERP (ascent)) |
5768 img->ascent = XFASTINT (ascent); | 5769 img->ascent = XFASTINT (ascent); |
5776 relief = image_spec_value (spec, QCrelief, NULL); | 5777 relief = image_spec_value (spec, QCrelief, NULL); |
5777 if (INTEGERP (relief)) | 5778 if (INTEGERP (relief)) |
5778 { | 5779 { |
5779 img->relief = XINT (relief); | 5780 img->relief = XINT (relief); |
5780 img->margin += abs (img->relief); | 5781 img->margin += abs (img->relief); |
5781 } | |
5782 | |
5783 /* Should we apply an image transformation algorithm? */ | |
5784 algorithm = image_spec_value (spec, QCalgorithm, NULL); | |
5785 if (img->pixmap) | |
5786 { | |
5787 if (EQ (algorithm, Qlaplace)) | |
5788 x_laplace (f, img); | |
5789 else if (EQ (algorithm, Qemboss)) | |
5790 x_emboss (f, img); | |
5791 else if (CONSP (algorithm) | |
5792 && EQ (XCAR (algorithm), Qedge_detection)) | |
5793 { | |
5794 Lisp_Object tem; | |
5795 tem = XCDR (algorithm); | |
5796 if (CONSP (tem)) | |
5797 x_edge_detection (f, img, | |
5798 Fplist_get (tem, QCmatrix), | |
5799 Fplist_get (tem, QCcolor_adjustment)); | |
5800 } | |
5801 } | 5782 } |
5802 | 5783 |
5803 /* Manipulation of the image's mask. */ | 5784 /* Manipulation of the image's mask. */ |
5804 if (img->pixmap) | 5785 if (img->pixmap) |
5805 { | 5786 { |
5841 img->mask = 0; | 5822 img->mask = 0; |
5842 UNBLOCK_INPUT; | 5823 UNBLOCK_INPUT; |
5843 } | 5824 } |
5844 } | 5825 } |
5845 } | 5826 } |
5827 | |
5828 /* Should we apply an image transformation algorithm? */ | |
5829 if (img->pixmap) | |
5830 { | |
5831 Lisp_Object algorithm; | |
5832 | |
5833 algorithm = image_spec_value (spec, QCalgorithm, NULL); | |
5834 if (EQ (algorithm, Qdisabled)) | |
5835 x_disable_image (f, img); | |
5836 else if (EQ (algorithm, Qlaplace)) | |
5837 x_laplace (f, img); | |
5838 else if (EQ (algorithm, Qemboss)) | |
5839 x_emboss (f, img); | |
5840 else if (CONSP (algorithm) | |
5841 && EQ (XCAR (algorithm), Qedge_detection)) | |
5842 { | |
5843 Lisp_Object tem; | |
5844 tem = XCDR (algorithm); | |
5845 if (CONSP (tem)) | |
5846 x_edge_detection (f, img, | |
5847 Fplist_get (tem, QCmatrix), | |
5848 Fplist_get (tem, QCcolor_adjustment)); | |
5849 } | |
5850 } | |
5851 | |
5846 } | 5852 } |
5847 } | 5853 } |
5848 | 5854 |
5849 /* We're using IMG, so set its timestamp to `now'. */ | 5855 /* We're using IMG, so set its timestamp to `now'. */ |
5850 EMACS_GET_TIME (now); | 5856 EMACS_GET_TIME (now); |
7345 XColor *, int, XImage *, int)); | 7351 XColor *, int, XImage *, int)); |
7346 static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int)); | 7352 static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int)); |
7347 static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *)); | 7353 static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *)); |
7348 static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int)); | 7354 static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int)); |
7349 | 7355 |
7356 /* Non-zero means draw a cross on images having `:algorithm | |
7357 disabled'. */ | |
7358 | |
7359 int cross_disabled_images; | |
7360 | |
7350 /* Edge detection matrices for different edge-detection | 7361 /* Edge detection matrices for different edge-detection |
7351 strategies. */ | 7362 strategies. */ |
7352 | 7363 |
7353 static int emboss_matrix[9] = { | 7364 static int emboss_matrix[9] = { |
7354 /* x - 1 x x + 1 */ | 7365 /* x - 1 x x + 1 */ |
7361 /* x - 1 x x + 1 */ | 7372 /* x - 1 x x + 1 */ |
7362 1, 0, 0, /* y - 1 */ | 7373 1, 0, 0, /* y - 1 */ |
7363 0, 0, 0, /* y */ | 7374 0, 0, 0, /* y */ |
7364 0, 0, -1 /* y + 1 */ | 7375 0, 0, -1 /* y + 1 */ |
7365 }; | 7376 }; |
7377 | |
7378 /* Value is the intensity of the color whose red/green/blue values | |
7379 are R, G, and B. */ | |
7380 | |
7381 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6) | |
7366 | 7382 |
7367 | 7383 |
7368 /* On frame F, return an array of XColor structures describing image | 7384 /* On frame F, return an array of XColor structures describing image |
7369 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P | 7385 IMG->pixmap. Each XColor structure has its pixel color set. RGB_P |
7370 non-zero means also fill the red/green/blue members of the XColor | 7386 non-zero means also fill the red/green/blue members of the XColor |
7497 { | 7513 { |
7498 p = COLOR (new, 1, y); | 7514 p = COLOR (new, 1, y); |
7499 | 7515 |
7500 for (x = 1; x < img->width - 1; ++x, ++p) | 7516 for (x = 1; x < img->width - 1; ++x, ++p) |
7501 { | 7517 { |
7502 int r, g, b, intensity, y1, x1; | 7518 int r, g, b, y1, x1; |
7503 | 7519 |
7504 r = g = b = i = 0; | 7520 r = g = b = i = 0; |
7505 for (y1 = y - 1; y1 < y + 2; ++y1) | 7521 for (y1 = y - 1; y1 < y + 2; ++y1) |
7506 for (x1 = x - 1; x1 < x + 2; ++x1, ++i) | 7522 for (x1 = x - 1; x1 < x + 2; ++x1, ++i) |
7507 if (matrix[i]) | 7523 if (matrix[i]) |
7513 } | 7529 } |
7514 | 7530 |
7515 r = (r / sum + color_adjust) & 0xffff; | 7531 r = (r / sum + color_adjust) & 0xffff; |
7516 g = (g / sum + color_adjust) & 0xffff; | 7532 g = (g / sum + color_adjust) & 0xffff; |
7517 b = (b / sum + color_adjust) & 0xffff; | 7533 b = (b / sum + color_adjust) & 0xffff; |
7518 | 7534 p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b); |
7519 intensity = (2 * r + 3 * g + b) / 6; | |
7520 p->red = p->green = p->blue = intensity; | |
7521 } | 7535 } |
7522 } | 7536 } |
7523 | 7537 |
7524 xfree (colors); | 7538 xfree (colors); |
7525 x_from_xcolors (f, img, new); | 7539 x_from_xcolors (f, img, new); |
7588 if (NILP (color_adjust)) | 7602 if (NILP (color_adjust)) |
7589 color_adjust = make_number (0xffff / 2); | 7603 color_adjust = make_number (0xffff / 2); |
7590 | 7604 |
7591 if (i == 9 && NUMBERP (color_adjust)) | 7605 if (i == 9 && NUMBERP (color_adjust)) |
7592 x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust)); | 7606 x_detect_edges (f, img, trans, (int) XFLOATINT (color_adjust)); |
7607 } | |
7608 | |
7609 | |
7610 /* Transform image IMG on frame F so that it looks disabled. */ | |
7611 | |
7612 static void | |
7613 x_disable_image (f, img) | |
7614 struct frame *f; | |
7615 struct image *img; | |
7616 { | |
7617 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | |
7618 | |
7619 if (dpyinfo->n_planes >= 2) | |
7620 { | |
7621 /* Color (or grayscale). Convert to gray, and equalize. Just | |
7622 drawing such images with a stipple can look very odd, so | |
7623 we're using this method instead. */ | |
7624 XColor *colors = x_to_xcolors (f, img, 1); | |
7625 XColor *p, *end; | |
7626 const int h = 15000; | |
7627 const int l = 30000; | |
7628 | |
7629 for (p = colors, end = colors + img->width * img->height; | |
7630 p < end; | |
7631 ++p) | |
7632 { | |
7633 int i = COLOR_INTENSITY (p->red, p->green, p->blue); | |
7634 int i2 = (0xffff - h - l) * i / 0xffff + l; | |
7635 p->red = p->green = p->blue = i2; | |
7636 } | |
7637 | |
7638 x_from_xcolors (f, img, colors); | |
7639 } | |
7640 | |
7641 /* Draw a cross over the disabled image, if we must or if we | |
7642 should. */ | |
7643 if (dpyinfo->n_planes < 2 || cross_disabled_images) | |
7644 { | |
7645 Display *dpy = FRAME_X_DISPLAY (f); | |
7646 GC gc; | |
7647 | |
7648 BLOCK_INPUT; | |
7649 gc = XCreateGC (dpy, img->pixmap, 0, NULL); | |
7650 XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); | |
7651 XDrawLine (dpy, img->pixmap, gc, 0, 0, | |
7652 img->width - 1, img->height - 1); | |
7653 XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1, | |
7654 img->width - 1, 0); | |
7655 XFreeGC (dpy, gc); | |
7656 | |
7657 if (img->mask) | |
7658 { | |
7659 gc = XCreateGC (dpy, img->mask, 0, NULL); | |
7660 XSetForeground (dpy, gc, WHITE_PIX_DEFAULT (f)); | |
7661 XDrawLine (dpy, img->mask, gc, 0, 0, | |
7662 img->width - 1, img->height - 1); | |
7663 XDrawLine (dpy, img->mask, gc, 0, img->height - 1, | |
7664 img->width - 1, 0); | |
7665 XFreeGC (dpy, gc); | |
7666 } | |
7667 | |
7668 UNBLOCK_INPUT; | |
7669 } | |
7593 } | 7670 } |
7594 | 7671 |
7595 | 7672 |
7596 /* Build a mask for image IMG which is used on frame F. FILE is the | 7673 /* Build a mask for image IMG which is used on frame F. FILE is the |
7597 name of an image file, for error messages. HOW determines how to | 7674 name of an image file, for error messages. HOW determines how to |
10836 Fput (Qundefined_color, Qerror_message, | 10913 Fput (Qundefined_color, Qerror_message, |
10837 build_string ("Undefined color")); | 10914 build_string ("Undefined color")); |
10838 | 10915 |
10839 init_x_parm_symbols (); | 10916 init_x_parm_symbols (); |
10840 | 10917 |
10918 DEFVAR_BOOL ("cross-disabled-images", &cross_disabled_images, | |
10919 "Non-nil means always draw a cross over disabled images.\n\ | |
10920 Disabled images are those having an `:algorithm disabled' property.\n\ | |
10921 A cross is always drawn on black & white displays."); | |
10922 cross_disabled_images = 0; | |
10923 | |
10841 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, | 10924 DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, |
10842 "List of directories to search for bitmap files for X."); | 10925 "List of directories to search for bitmap files for X."); |
10843 Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); | 10926 Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); |
10844 | 10927 |
10845 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape, | 10928 DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape, |