diff options
| author | Joakim Verona | 2013-08-15 17:21:47 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-08-15 17:21:47 +0200 |
| commit | 98f2993e4d15fc5b57cdbe212634527c630b919d (patch) | |
| tree | bd3af0388b64218d9a0618b802d27658bd6aaf87 /src | |
| parent | e4b4bda83d2adf59dd7e9530c6f03bce9d45ccf1 (diff) | |
| parent | d39a3da6f3df4ff3c08e5b68fe629e10d1b8f3ea (diff) | |
| download | emacs-98f2993e4d15fc5b57cdbe212634527c630b919d.tar.gz emacs-98f2993e4d15fc5b57cdbe212634527c630b919d.zip | |
merge from trunk
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/image.c | 79 | ||||
| -rw-r--r-- | src/xdisp.c | 20 |
3 files changed, 108 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 1ad3e1cff24..1a83531ad10 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2013-08-15 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (compute_window_start_on_continuation_line): When | ||
| 4 | WORD_WRAP is in effect, use move_it_to instead of move_it_by_lines | ||
| 5 | to make sure we end up setting the window start at the leftmost | ||
| 6 | visible character of the display line. This avoids funky | ||
| 7 | horizontal shifting because the window start is not kept on the | ||
| 8 | same position. (Bug#15090) | ||
| 9 | |||
| 10 | 2013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 11 | |||
| 12 | * image.c (imagemagick_compute_animated_image): Implement animated | ||
| 13 | images (bug#14700). | ||
| 14 | |||
| 1 | 2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> | 15 | 2013-08-15 Dmitry Antipov <dmantipov@yandex.ru> |
| 2 | 16 | ||
| 3 | * lisp.h (FOR_EACH_ALIST_VALUE): New macro | 17 | * lisp.h (FOR_EACH_ALIST_VALUE): New macro |
diff --git a/src/image.c b/src/image.c index 8d969a6f9c6..c534f181e5c 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -7864,6 +7864,75 @@ imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent]) | |||
| 7864 | return hint_buffer; | 7864 | return hint_buffer; |
| 7865 | } | 7865 | } |
| 7866 | 7866 | ||
| 7867 | /* Animated images (e.g., GIF89a) are composed from one "master image" | ||
| 7868 | (which is the first one, and then there's a number of images that | ||
| 7869 | follow. If following images have non-transparent colors, these are | ||
| 7870 | composed "on top" of the master image. So, in general, one has to | ||
| 7871 | compute ann the preceding images to be able to display a particular | ||
| 7872 | sub-image. */ | ||
| 7873 | |||
| 7874 | static MagickWand * | ||
| 7875 | imagemagick_compute_animated_image (MagickWand *super_wand, int ino) | ||
| 7876 | { | ||
| 7877 | MagickWand *composite_wand; | ||
| 7878 | |||
| 7879 | MagickSetIteratorIndex (super_wand, 0); | ||
| 7880 | composite_wand = MagickGetImage (super_wand); | ||
| 7881 | |||
| 7882 | for (int i = 1; i <= ino; i++) { | ||
| 7883 | MagickWand *sub_wand; | ||
| 7884 | PixelIterator *source_iterator, *dest_iterator; | ||
| 7885 | PixelWand **source, **dest; | ||
| 7886 | long source_width, dest_width; | ||
| 7887 | MagickPixelPacket pixel; | ||
| 7888 | |||
| 7889 | MagickSetIteratorIndex (super_wand, i); | ||
| 7890 | sub_wand = MagickGetImage (super_wand); | ||
| 7891 | |||
| 7892 | source_iterator = NewPixelIterator (sub_wand); | ||
| 7893 | if (! source_iterator) | ||
| 7894 | { | ||
| 7895 | DestroyMagickWand (composite_wand); | ||
| 7896 | DestroyMagickWand (sub_wand); | ||
| 7897 | image_error ("Imagemagick pixel iterator creation failed", | ||
| 7898 | Qnil, Qnil); | ||
| 7899 | return NULL; | ||
| 7900 | } | ||
| 7901 | |||
| 7902 | dest_iterator = NewPixelIterator (composite_wand); | ||
| 7903 | if (! dest_iterator) | ||
| 7904 | { | ||
| 7905 | DestroyMagickWand (composite_wand); | ||
| 7906 | DestroyMagickWand (sub_wand); | ||
| 7907 | DestroyPixelIterator (source_iterator); | ||
| 7908 | image_error ("Imagemagick pixel iterator creation failed", | ||
| 7909 | Qnil, Qnil); | ||
| 7910 | return NULL; | ||
| 7911 | } | ||
| 7912 | |||
| 7913 | while (source = PixelGetNextIteratorRow (source_iterator, &source_width)) { | ||
| 7914 | dest = PixelGetNextIteratorRow (dest_iterator, &dest_width); | ||
| 7915 | for (int x = 0; x < source_width; x++) | ||
| 7916 | { | ||
| 7917 | /* Copy over non-transparent pixels. */ | ||
| 7918 | if (PixelGetAlpha (source[x])) | ||
| 7919 | { | ||
| 7920 | PixelGetMagickColor (source[x], &pixel); | ||
| 7921 | PixelSetMagickColor (dest[x], &pixel); | ||
| 7922 | } | ||
| 7923 | } | ||
| 7924 | PixelSyncIterator(dest_iterator); | ||
| 7925 | } | ||
| 7926 | |||
| 7927 | DestroyPixelIterator (source_iterator); | ||
| 7928 | DestroyPixelIterator (dest_iterator); | ||
| 7929 | DestroyMagickWand (sub_wand); | ||
| 7930 | } | ||
| 7931 | |||
| 7932 | return composite_wand; | ||
| 7933 | } | ||
| 7934 | |||
| 7935 | |||
| 7867 | /* Helper function for imagemagick_load, which does the actual loading | 7936 | /* Helper function for imagemagick_load, which does the actual loading |
| 7868 | given contents and size, apart from frame and image structures, | 7937 | given contents and size, apart from frame and image structures, |
| 7869 | passed from imagemagick_load. Uses librimagemagick to do most of | 7938 | passed from imagemagick_load. Uses librimagemagick to do most of |
| @@ -7965,12 +8034,14 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7965 | 8034 | ||
| 7966 | /* If we have an animated image, get the new wand based on the | 8035 | /* If we have an animated image, get the new wand based on the |
| 7967 | "super-wand". */ | 8036 | "super-wand". */ |
| 7968 | if (ino > 0) | 8037 | if (MagickGetNumberImages (image_wand) > 1) |
| 7969 | { | 8038 | { |
| 7970 | MagickWand *super_wand = image_wand; | 8039 | MagickWand *super_wand = image_wand; |
| 7971 | MagickSetIteratorIndex (super_wand, ino); | 8040 | image_wand = imagemagick_compute_animated_image (super_wand, ino); |
| 7972 | image_wand = MagickGetImage (super_wand); | 8041 | if (! image_wand) |
| 7973 | DestroyMagickWand (super_wand); | 8042 | image_wand = super_wand; |
| 8043 | else | ||
| 8044 | DestroyMagickWand (super_wand); | ||
| 7974 | } | 8045 | } |
| 7975 | 8046 | ||
| 7976 | /* Retrieve the frame's background color, for use later. */ | 8047 | /* Retrieve the frame's background color, for use later. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 7a0c1009d83..4e1ddb36baa 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -14975,7 +14975,25 @@ compute_window_start_on_continuation_line (struct window *w) | |||
| 14975 | { | 14975 | { |
| 14976 | min_distance = distance; | 14976 | min_distance = distance; |
| 14977 | pos = it.current.pos; | 14977 | pos = it.current.pos; |
| 14978 | move_it_by_lines (&it, 1); | 14978 | if (it.line_wrap == WORD_WRAP) |
| 14979 | { | ||
| 14980 | /* Under WORD_WRAP, move_it_by_lines is likely to | ||
| 14981 | overshoot and stop not at the first, but the | ||
| 14982 | second character from the left margin. So in | ||
| 14983 | that case, we need a more tight control on the X | ||
| 14984 | coordinate of the iterator than move_it_by_lines | ||
| 14985 | promises in its contract. The method is to first | ||
| 14986 | go to the last (rightmost) visible character of a | ||
| 14987 | line, then move to the leftmost character on the | ||
| 14988 | next line in a separate call. */ | ||
| 14989 | move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1, | ||
| 14990 | MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); | ||
| 14991 | move_it_to (&it, ZV, 0, | ||
| 14992 | it.current_y + it.max_ascent + it.max_descent, -1, | ||
| 14993 | MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); | ||
| 14994 | } | ||
| 14995 | else | ||
| 14996 | move_it_by_lines (&it, 1); | ||
| 14979 | } | 14997 | } |
| 14980 | 14998 | ||
| 14981 | /* Set the window start there. */ | 14999 | /* Set the window start there. */ |