diff options
| author | Gerd Moellmann | 2000-09-15 21:01:29 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-09-15 21:01:29 +0000 |
| commit | 14819cb379da2ae6438322f3a4c646faca7c088e (patch) | |
| tree | 2171fdcd05fc1e93bc091d58545b4c996e3de14b /src | |
| parent | 37e4e4828628dad925a28d4f6eba50f95487649d (diff) | |
| download | emacs-14819cb379da2ae6438322f3a4c646faca7c088e.tar.gz emacs-14819cb379da2ae6438322f3a4c646faca7c088e.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 133 |
1 files changed, 108 insertions, 25 deletions
diff --git a/src/xfns.c b/src/xfns.c index c91e49549a4..e57d223ea62 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -744,6 +744,7 @@ struct x_frame_parm_table | |||
| 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)); |
| @@ -5760,7 +5761,7 @@ lookup_image (f, spec) | |||
| 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); |
| @@ -5780,26 +5781,6 @@ lookup_image (f, spec) | |||
| 5780 | img->margin += abs (img->relief); | 5781 | img->margin += abs (img->relief); |
| 5781 | } | 5782 | } |
| 5782 | 5783 | ||
| 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 | } | ||
| 5802 | |||
| 5803 | /* Manipulation of the image's mask. */ | 5784 | /* Manipulation of the image's mask. */ |
| 5804 | if (img->pixmap) | 5785 | if (img->pixmap) |
| 5805 | { | 5786 | { |
| @@ -5843,6 +5824,31 @@ lookup_image (f, spec) | |||
| 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 | ||
| @@ -7347,6 +7353,11 @@ 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 | ||
| @@ -7364,6 +7375,11 @@ static int laplace_matrix[9] = { | |||
| 7364 | 0, 0, -1 /* y + 1 */ | 7375 | 0, 0, -1 /* y + 1 */ |
| 7365 | }; | 7376 | }; |
| 7366 | 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) | ||
| 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 |
| @@ -7499,7 +7515,7 @@ x_detect_edges (f, img, matrix, color_adjust) | |||
| 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) |
| @@ -7515,9 +7531,7 @@ x_detect_edges (f, img, matrix, color_adjust) | |||
| 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 | ||
| @@ -7593,6 +7607,69 @@ x_edge_detection (f, img, matrix, color_adjust) | |||
| 7593 | } | 7607 | } |
| 7594 | 7608 | ||
| 7595 | 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 | } | ||
| 7670 | } | ||
| 7671 | |||
| 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 |
| 7598 | determine the background color of IMG. If it is a list '(R G B)', | 7675 | determine the background color of IMG. If it is a list '(R G B)', |
| @@ -10838,6 +10915,12 @@ syms_of_xfns () | |||
| 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); |