]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement :max-width/:max-height for (ImageMagic) images
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Sun, 23 Jun 2013 19:24:27 +0000 (21:24 +0200)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Sun, 23 Jun 2013 19:24:27 +0000 (21:24 +0200)
* doc/lispref/display.texi (ImageMagick Images): Mention :max-width and
:max-height.

* lisp/net/shr.el (shr-rescale-image): Use the new
:max-width/:max-height functionality.

* src/image.c (compute_image_size): New function to implement
:max-width and :max-height.
(imagemagick_load_image): Use it.

doc/lispref/ChangeLog
doc/lispref/display.texi
etc/NEWS
lisp/ChangeLog
lisp/net/shr.el
src/ChangeLog
src/image.c

index c00d3392908f784779924a8b593ba3885b895f62..e95010a11a93bab8f04ca17e00073ae5ed2ae323 100644 (file)
@@ -1,3 +1,8 @@
+2013-06-23  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * display.texi (ImageMagick Images): Mention :max-width and
+       :max-height.
+
 2013-06-20  Paul Eggert  <eggert@cs.ucla.edu>
 
        * numbers.texi (Math Functions): Remove obsolete function log10.
index 34eda6ecd6f451f116014943eee955007fcc741d..d82b9a4c5a2e56a8d837ff8b1646d4f529064ece 100644 (file)
@@ -4653,6 +4653,15 @@ image.  If only one of them is specified, the other one will be
 calculated so as to preserve the aspect ratio.  If both are specified,
 aspect ratio may not be preserved.
 
+@item :max-width, :max-height
+The @code{:max-width} and @code{:max-height} keywords are used for
+scaling if the size of the image of the image exceeds these values.
+If @code{:width} is set it will have presedence over @code{max-width},
+and if @code{:height} is set it will have presedence over
+@code{max-height}, but you can otherwise mix these keywords as you
+wish.  @code{:max-width} and @code{:max-height} will always preserve
+the aspec ratio.
+
 @item :rotation
 Specifies a rotation angle in degrees.
 
index 475b4b26fdbf793d8300c8a2c2d5048cf427291f..d7364542ce152f9744ff24fa8f0457dc4354597b 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -695,6 +695,9 @@ ImageMagick types are treated as images.  The function
 `imagemagick-filter-types' returns the list of types that will be
 treated as images.
 
+*** ImageMagick images now support the :max-width and :max-height
+keywords.
+
 ** Minibuffer
 
 *** In minibuffer filename prompts, `C-M-f' and `C-M-b' now move to the
index a3fc6bd172f860a11555b5896733da5abfc2b68c..ff41129b90632db7a3f8655279fc12c66d9d97ef 100644 (file)
@@ -1,3 +1,8 @@
+2013-06-23  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * net/shr.el (shr-rescale-image): Use the new
+       :max-width/:max-height functionality.
+
 2013-06-23  Ivan Kanis  <ivan@kanis.fr>
 
        * net/eww.el (eww-search-prefix): New variable.
index 868956d3e21e01527576f7ef8ea2b3a34bf6e1c2..979743f95882bc7d21eff1fd84edee29e9230813 100644 (file)
@@ -741,34 +741,18 @@ size, and full-buffer size."
 (defun shr-rescale-image (data &optional force)
   "Rescale DATA, if too big, to fit the current buffer.
 If FORCE, rescale the image anyway."
-  (let ((image (create-image data nil t :ascent 100)))
-    (if (or (not (fboundp 'imagemagick-types))
-           (not (get-buffer-window (current-buffer))))
-       image
-      (let* ((size (image-size image t))
-            (width (car size))
-            (height (cdr size))
-            (edges (window-inside-pixel-edges
-                    (get-buffer-window (current-buffer))))
-            (window-width (truncate (* shr-max-image-proportion
-                                       (- (nth 2 edges) (nth 0 edges)))))
-            (window-height (truncate (* shr-max-image-proportion
-                                        (- (nth 3 edges) (nth 1 edges)))))
-            scaled-image)
-       (when (or force
-                 (> height window-height))
-         (setq image (or (create-image data 'imagemagick t
-                                       :height window-height
-                                       :ascent 100)
-                         image))
-         (setq size (image-size image t)))
-       (when (> (car size) window-width)
-         (setq image (or
-                      (create-image data 'imagemagick t
-                                    :width window-width
-                                    :ascent 100)
-                      image)))
-       image))))
+  (if (or (not (fboundp 'imagemagick-types))
+         (not (get-buffer-window (current-buffer))))
+      (create-image data nil t :ascent 100)
+    (let ((edges (window-inside-pixel-edges
+                 (get-buffer-window (current-buffer)))))
+      (create-image
+       data 'imagemagick t
+       :ascent 100
+       :max-width (truncate (* shr-max-image-proportion
+                              (- (nth 2 edges) (nth 0 edges))))
+       :max-height (truncate (* shr-max-image-proportion
+                               (- (nth 3 edges) (nth 1 edges))))))))
 
 ;; url-cache-extract autoloads url-cache.
 (declare-function url-cache-create-filename "url-cache" (url))
index b2773ddbf5077156e19833ba9e37c290b08187c2..f9451711f321daaaff636b55a452436b4516b0c1 100644 (file)
@@ -1,3 +1,9 @@
+2013-06-23  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+       * image.c (compute_image_size): New function to implement
+       :max-width and :max-height.
+       (imagemagick_load_image): Use it.
+
 2013-06-23  Paul Eggert  <eggert@cs.ucla.edu>
 
        Try to avoid malloc SEGVs on Cygwin (Bug#14569).
index ffb3cd15e937a2c166eb00c00b9e6d19d84fff2e..b65ee7df7897fcb0d36cd933c1d55171bbe55de1 100644 (file)
@@ -132,6 +132,8 @@ static void free_color_table (void);
 static unsigned long *colors_in_color_table (int *n);
 #endif
 
+Lisp_Object QCmax_width, QCmax_height;
+
 /* Code to deal with bitmaps.  Bitmaps are referenced by their bitmap
    id, which is just an int that this section returns.  Bitmaps are
    reference counted so they can be shared among frames.
@@ -7489,6 +7491,76 @@ gif_load (struct frame *f, struct image *img)
 #endif /* HAVE_GIF */
 
 
+static void
+compute_image_size (size_t width, size_t height,
+                   Lisp_Object spec,
+                   int *d_width, int *d_height)
+{
+  Lisp_Object value;
+  int desired_width, desired_height;
+
+  /* If width and/or height is set in the display spec assume we want
+     to scale to those values.  If either h or w is unspecified, the
+     unspecified should be calculated from the specified to preserve
+     aspect ratio.  */
+  value = image_spec_value (spec, QCwidth, NULL);
+  desired_width = (INTEGERP (value)  ? XFASTINT (value) : -1);
+  value = image_spec_value (spec, QCheight, NULL);
+  desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
+
+  if (desired_width == -1)
+    {
+      value = image_spec_value (spec, QCmax_width, NULL);
+      if (INTEGERP (value) &&
+         width > XFASTINT (value))
+       {
+         /* The image is wider than :max-width. */
+         desired_width = XFASTINT (value);
+         if (desired_height == -1)
+           {
+             value = image_spec_value (spec, QCmax_height, NULL);
+             if (INTEGERP (value))
+               {
+                 /* We have no specified height, but we have a
+                    :max-height value, so check that we satisfy both
+                    conditions. */
+                 desired_height = (double) desired_width / width * height;
+                 if (desired_height > XFASTINT (value))
+                   {
+                     desired_height = XFASTINT (value);
+                     desired_width = (double) desired_height / height * width;
+                   }
+               }
+             else
+               {
+                 /* We have no specified height and no specified
+                    max-height, so just compute the height. */
+                 desired_height = (double) desired_width / width * height;
+               }
+           }
+       }
+    }
+
+  if (desired_height == -1)
+    {
+      value = image_spec_value (spec, QCmax_height, NULL);
+      if (INTEGERP (value) &&
+         height > XFASTINT (value))
+         desired_height = XFASTINT (value);
+    }
+
+  if (desired_width != -1 && desired_height == -1)
+    /* w known, calculate h.  */
+    desired_height = (double) desired_width / width * height;
+
+  if (desired_width == -1 && desired_height != -1)
+    /* h known, calculate w.  */
+    desired_width = (double) desired_height / height * width;
+
+  *d_width = desired_width;
+  *d_height = desired_height;
+}
+
 /***********************************************************************
                                 ImageMagick
 ***********************************************************************/
@@ -7516,6 +7588,8 @@ enum imagemagick_keyword_index
     IMAGEMAGICK_BACKGROUND,
     IMAGEMAGICK_HEIGHT,
     IMAGEMAGICK_WIDTH,
+    IMAGEMAGICK_MAX_HEIGHT,
+    IMAGEMAGICK_MAX_WIDTH,
     IMAGEMAGICK_ROTATION,
     IMAGEMAGICK_CROP,
     IMAGEMAGICK_LAST
@@ -7538,6 +7612,8 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
     {":background",    IMAGE_STRING_OR_NIL_VALUE,              0},
     {":height",                IMAGE_INTEGER_VALUE,                    0},
     {":width",         IMAGE_INTEGER_VALUE,                    0},
+    {":max-height",    IMAGE_INTEGER_VALUE,                    0},
+    {":max-width",     IMAGE_INTEGER_VALUE,                    0},
     {":rotation",      IMAGE_NUMBER_VALUE,                     0},
     {":crop",          IMAGE_DONT_CHECK_VALUE_TYPE,            0}
   };
@@ -7726,24 +7802,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
     PixelSetBlue  (bg_wand, (double) bgcolor.blue  / 65535);
   }
 
-  /* If width and/or height is set in the display spec assume we want
-     to scale to those values.  If either h or w is unspecified, the
-     unspecified should be calculated from the specified to preserve
-     aspect ratio.  */
-  value = image_spec_value (img->spec, QCwidth, NULL);
-  desired_width = (INTEGERP (value)  ? XFASTINT (value) : -1);
-  value = image_spec_value (img->spec, QCheight, NULL);
-  desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
-
-  height = MagickGetImageHeight (image_wand);
-  width = MagickGetImageWidth (image_wand);
+  compute_image_size (MagickGetImageWidth (image_wand),
+                     MagickGetImageHeight (image_wand),
+                     img->spec, &desired_width, &desired_height);
 
-  if (desired_width != -1 && desired_height == -1)
-    /* w known, calculate h.  */
-    desired_height = (double) desired_width / width * height;
-  if (desired_width == -1 && desired_height != -1)
-    /* h known, calculate w.  */
-    desired_width = (double) desired_height / height * width;
   if (desired_width != -1 && desired_height != -1)
     {
       status = MagickScaleImage (image_wand, desired_width, desired_height);
@@ -8895,6 +8957,8 @@ non-numeric, there is no explicit limit on the size of images.  */);
   DEFSYM (Qheuristic, "heuristic");
 
   DEFSYM (Qpostscript, "postscript");
+  DEFSYM (QCmax_width, ":max-width");
+  DEFSYM (QCmax_height, ":max-height");
 #ifdef HAVE_GHOSTSCRIPT
   ADD_IMAGE_TYPE (Qpostscript);
   DEFSYM (QCloader, ":loader");