aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2017-07-15 02:45:19 +0200
committerLars Ingebrigtsen2017-07-15 02:48:17 +0200
commitae56c9674b4668ded392c66d46aa22db902ddd71 (patch)
tree3472b1e2c5877ee37a0b4813f60bc2b2b5515d47
parent89c5d59280edaf89b959597a39d848b54c36975a (diff)
downloademacs-ae56c9674b4668ded392c66d46aa22db902ddd71.tar.gz
emacs-ae56c9674b4668ded392c66d46aa22db902ddd71.zip
Make combinations of :width/:max-height image specs work reliably
* doc/lispref/display.texi (ImageMagick Images): Document :width/:max-height combinations (etc) (bug #25583). * src/image.c (compute_image_size): Handle :width/:max-height (etc) combinations consistently (by letting "max" win and preserve ratio). * test/manual/image-size-tests.el (image-size-tests): Add tests for :width/:max-height (etc) combinations.
-rw-r--r--doc/lispref/display.texi11
-rw-r--r--etc/NEWS8
-rw-r--r--src/image.c97
-rw-r--r--test/manual/image-size-tests.el10
4 files changed, 72 insertions, 54 deletions
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 005d31af05a..98940cbc996 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5305,6 +5305,17 @@ and if @code{:height} is set it will have precedence over
5305wish. @code{:max-width} and @code{:max-height} will always preserve 5305wish. @code{:max-width} and @code{:max-height} will always preserve
5306the aspect ratio. 5306the aspect ratio.
5307 5307
5308If both @code{:width} and @code{:max-height} has been set (but
5309@code{:height} has not been set), then @code{:max-height} will have
5310precedence. The same is the case for the opposite combination: The
5311``max'' keyword has precedence. That is, if you have a 200x100 image
5312and specify that @code{:width} should be 400 and @code{:max-height}
5313should be 150, you'll end up with an image that is 300x150: Preserving
5314the aspect ratio and not exceeding the ``max'' setting. This
5315combination of parameters is a useful way of saying ``display this
5316image as large as possible, but no larger than the available display
5317area''.
5318
5308@item :scale @var{scale} 5319@item :scale @var{scale}
5309This should be a number, where values higher than 1 means to increase 5320This should be a number, where values higher than 1 means to increase
5310the size, and lower means to decrease the size. For instance, a value 5321the size, and lower means to decrease the size. For instance, a value
diff --git a/etc/NEWS b/etc/NEWS
index 0ab49587d79..edb71118efd 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -763,6 +763,14 @@ Ido mode is active.
763in question). 763in question).
764 764
765+++ 765+++
766*** It's now possible to specify aspect-ratio preserving combinations
767of :width/:max-height and :height/:max-width keywords. In either
768case, the "max" keywords win. (Previously some combinations would,
769depending on the aspect ratio of the image, just be ignored and in
770other instances this would lead to the aspect ratio not being
771preserved.)
772
773+++
766*** Images inserted with 'insert-image' and related functions get a 774*** Images inserted with 'insert-image' and related functions get a
767keymap put into the text properties (or overlays) that span the 775keymap put into the text properties (or overlays) that span the
768image. This keymap binds keystrokes for manipulating size and 776image. This keymap binds keystrokes for manipulating size and
diff --git a/src/image.c b/src/image.c
index 1426e309445..69a529e8c35 100644
--- a/src/image.c
+++ b/src/image.c
@@ -8086,83 +8086,76 @@ compute_image_size (size_t width, size_t height,
8086 int *d_width, int *d_height) 8086 int *d_width, int *d_height)
8087{ 8087{
8088 Lisp_Object value; 8088 Lisp_Object value;
8089 int desired_width, desired_height; 8089 int desired_width = -1, desired_height = -1, max_width = -1, max_height = -1;
8090 double scale = 1; 8090 double scale = 1;
8091 8091
8092 value = image_spec_value (spec, QCscale, NULL); 8092 value = image_spec_value (spec, QCscale, NULL);
8093 if (NUMBERP (value)) 8093 if (NUMBERP (value))
8094 scale = XFLOATINT (value); 8094 scale = XFLOATINT (value);
8095 8095
8096 value = image_spec_value (spec, QCmax_width, NULL);
8097 if (NATNUMP (value))
8098 max_width = min (XFASTINT (value), INT_MAX);
8099
8100 value = image_spec_value (spec, QCmax_height, NULL);
8101 if (NATNUMP (value))
8102 max_height = min (XFASTINT (value), INT_MAX);
8103
8096 /* If width and/or height is set in the display spec assume we want 8104 /* If width and/or height is set in the display spec assume we want
8097 to scale to those values. If either h or w is unspecified, the 8105 to scale to those values. If either h or w is unspecified, the
8098 unspecified should be calculated from the specified to preserve 8106 unspecified should be calculated from the specified to preserve
8099 aspect ratio. */ 8107 aspect ratio. */
8100 value = image_spec_value (spec, QCwidth, NULL); 8108 value = image_spec_value (spec, QCwidth, NULL);
8101 desired_width = NATNUMP (value) ? 8109 if (NATNUMP (value))
8102 min (XFASTINT (value) * scale, INT_MAX) : -1;
8103 value = image_spec_value (spec, QCheight, NULL);
8104 desired_height = NATNUMP (value) ?
8105 min (XFASTINT (value) * scale, INT_MAX) : -1;
8106
8107 width = width * scale;
8108 height = height * scale;
8109
8110 if (desired_width == -1)
8111 { 8110 {
8112 value = image_spec_value (spec, QCmax_width, NULL); 8111 desired_width = min (XFASTINT (value) * scale, INT_MAX);
8113 if (NATNUMP (value)) 8112 /* :width overrides :max-width. */
8114 { 8113 max_width = -1;
8115 int max_width = min (XFASTINT (value), INT_MAX);
8116 if (max_width < width)
8117 {
8118 /* The image is wider than :max-width. */
8119 desired_width = max_width;
8120 if (desired_height == -1)
8121 {
8122 desired_height = scale_image_size (desired_width,
8123 width, height);
8124 value = image_spec_value (spec, QCmax_height, NULL);
8125 if (NATNUMP (value))
8126 {
8127 int max_height = min (XFASTINT (value), INT_MAX);
8128 if (max_height < desired_height)
8129 {
8130 desired_height = max_height;
8131 desired_width = scale_image_size (desired_height,
8132 height, width);
8133 }
8134 }
8135 }
8136 }
8137 }
8138 } 8114 }
8139 8115
8140 if (desired_height == -1) 8116 value = image_spec_value (spec, QCheight, NULL);
8117 if (NATNUMP (value))
8141 { 8118 {
8142 value = image_spec_value (spec, QCmax_height, NULL); 8119 desired_height = min (XFASTINT (value) * scale, INT_MAX);
8143 if (NATNUMP (value)) 8120 /* :height overrides :max-height. */
8144 { 8121 max_height = -1;
8145 int max_height = min (XFASTINT (value), INT_MAX);
8146 if (max_height < height)
8147 desired_height = max_height;
8148 }
8149 } 8122 }
8150 8123
8124 /* If we have both width/height set explicitly, we skip past all the
8125 aspect ratio-preserving computations below. */
8126 if (desired_width != -1 && desired_height != -1)
8127 goto out;
8128
8129 width = width * scale;
8130 height = height * scale;
8131
8151 if (desired_width != -1 && desired_height == -1) 8132 if (desired_width != -1 && desired_height == -1)
8152 /* w known, calculate h. */ 8133 /* Width known, calculate height. */
8153 desired_height = scale_image_size (desired_width, width, height); 8134 desired_height = scale_image_size (desired_width, width, height);
8154 8135 else if (desired_width == -1 && desired_height != -1)
8155 if (desired_width == -1 && desired_height != -1) 8136 /* Height known, calculate width. */
8156 /* h known, calculate w. */
8157 desired_width = scale_image_size (desired_height, height, width); 8137 desired_width = scale_image_size (desired_height, height, width);
8158 8138 else
8159 /* We have no width/height settings, so just apply the scale. */
8160 if (desired_width == -1 && desired_height == -1)
8161 { 8139 {
8162 desired_width = width; 8140 desired_width = width;
8163 desired_height = height; 8141 desired_height = height;
8164 } 8142 }
8165 8143
8144 if (max_width != -1 && desired_width > max_width)
8145 {
8146 /* The image is wider than :max-width. */
8147 desired_width = max_width;
8148 desired_height = scale_image_size (desired_width, width, height);
8149 }
8150
8151 if (max_height != -1 && desired_height > max_height)
8152 {
8153 /* The image is higher than :max-height. */
8154 desired_height = max_height;
8155 desired_width = scale_image_size (desired_height, height, width);
8156 }
8157
8158 out:
8166 *d_width = desired_width; 8159 *d_width = desired_width;
8167 *d_height = desired_height; 8160 *d_height = desired_height;
8168} 8161}
diff --git a/test/manual/image-size-tests.el b/test/manual/image-size-tests.el
index 577c7658791..6721e348e12 100644
--- a/test/manual/image-size-tests.el
+++ b/test/manual/image-size-tests.el
@@ -25,8 +25,8 @@
25(defmacro im-should (image width height &rest props) 25(defmacro im-should (image width height &rest props)
26 `(let ((im (im-image ,image ,@props))) 26 `(let ((im (im-image ,image ,@props)))
27 (unless (im-compare im ,width ,height) 27 (unless (im-compare im ,width ,height)
28 (error "%s didn't succeed; size is %s" 28 (error "%s %s didn't succeed; size is %s"
29 ',props (image-size im t))))) 29 ',image ',props (image-size im t)))))
30 30
31(defun im-image (type &rest props) 31(defun im-image (type &rest props)
32 (let ((image-scaling-factor 1)) 32 (let ((image-scaling-factor 1))
@@ -67,6 +67,9 @@
67 ;; Both max-width/height. 67 ;; Both max-width/height.
68 (im-should :w 100 50 :max-width 100 :max-height 75) 68 (im-should :w 100 50 :max-width 100 :max-height 75)
69 (im-should :w 50 25 :max-width 100 :max-height 25) 69 (im-should :w 50 25 :max-width 100 :max-height 25)
70 ;; :width and :max-height (max-height wins).
71 (im-should :w 400 200 :width 400 :max-height 200)
72 (im-should :w 400 200 :width 500 :max-height 200)
70 73
71 ;; Test the image that's taller than it is wide. 74 ;; Test the image that's taller than it is wide.
72 (im-should :h 100 200) 75 (im-should :h 100 200)
@@ -87,6 +90,9 @@
87 ;; Both max-width/height. 90 ;; Both max-width/height.
88 (im-should :h 50 100 :max-width 75 :max-height 100) 91 (im-should :h 50 100 :max-width 75 :max-height 100)
89 (im-should :h 25 50 :max-width 25 :max-height 100) 92 (im-should :h 25 50 :max-width 25 :max-height 100)
93 ;; :hieght and :max-width (max-width wins).
94 (im-should :h 200 400 :height 400 :max-width 200)
95 (im-should :h 200 400 :height 500 :max-width 200)
90 ) 96 )
91 97
92;;; image-size-tests.el ends here 98;;; image-size-tests.el ends here