aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/image.c79
-rw-r--r--src/xdisp.c20
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 @@
12013-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
102013-08-15 Lars Magne Ingebrigtsen <larsi@gnus.org>
11
12 * image.c (imagemagick_compute_animated_image): Implement animated
13 images (bug#14700).
14
12013-08-15 Dmitry Antipov <dmantipov@yandex.ru> 152013-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
7874static MagickWand *
7875imagemagick_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. */