diff options
| author | Lars Magne Ingebrigtsen | 2013-06-23 21:24:27 +0200 |
|---|---|---|
| committer | Lars Magne Ingebrigtsen | 2013-06-23 21:24:27 +0200 |
| commit | f3f9606c7acb4b3248dbe6f9fe16db6d5e46c3af (patch) | |
| tree | c96757e2023bc5b30e6ba77f58478cefcabd9ac7 | |
| parent | e854cfc719363ccee23beaa7d0f79aab65d82a98 (diff) | |
| download | emacs-f3f9606c7acb4b3248dbe6f9fe16db6d5e46c3af.tar.gz emacs-f3f9606c7acb4b3248dbe6f9fe16db6d5e46c3af.zip | |
Implement :max-width/:max-height for (ImageMagic) images
* 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.
| -rw-r--r-- | doc/lispref/ChangeLog | 5 | ||||
| -rw-r--r-- | doc/lispref/display.texi | 9 | ||||
| -rw-r--r-- | etc/NEWS | 3 | ||||
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/net/shr.el | 40 | ||||
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/image.c | 98 |
7 files changed, 121 insertions, 45 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index c00d3392908..e95010a11a9 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2013-06-23 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * display.texi (ImageMagick Images): Mention :max-width and | ||
| 4 | :max-height. | ||
| 5 | |||
| 1 | 2013-06-20 Paul Eggert <eggert@cs.ucla.edu> | 6 | 2013-06-20 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 7 | ||
| 3 | * numbers.texi (Math Functions): Remove obsolete function log10. | 8 | * numbers.texi (Math Functions): Remove obsolete function log10. |
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 34eda6ecd6f..d82b9a4c5a2 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi | |||
| @@ -4653,6 +4653,15 @@ image. If only one of them is specified, the other one will be | |||
| 4653 | calculated so as to preserve the aspect ratio. If both are specified, | 4653 | calculated so as to preserve the aspect ratio. If both are specified, |
| 4654 | aspect ratio may not be preserved. | 4654 | aspect ratio may not be preserved. |
| 4655 | 4655 | ||
| 4656 | @item :max-width, :max-height | ||
| 4657 | The @code{:max-width} and @code{:max-height} keywords are used for | ||
| 4658 | scaling if the size of the image of the image exceeds these values. | ||
| 4659 | If @code{:width} is set it will have presedence over @code{max-width}, | ||
| 4660 | and if @code{:height} is set it will have presedence over | ||
| 4661 | @code{max-height}, but you can otherwise mix these keywords as you | ||
| 4662 | wish. @code{:max-width} and @code{:max-height} will always preserve | ||
| 4663 | the aspec ratio. | ||
| 4664 | |||
| 4656 | @item :rotation | 4665 | @item :rotation |
| 4657 | Specifies a rotation angle in degrees. | 4666 | Specifies a rotation angle in degrees. |
| 4658 | 4667 | ||
| @@ -695,6 +695,9 @@ ImageMagick types are treated as images. The function | |||
| 695 | `imagemagick-filter-types' returns the list of types that will be | 695 | `imagemagick-filter-types' returns the list of types that will be |
| 696 | treated as images. | 696 | treated as images. |
| 697 | 697 | ||
| 698 | *** ImageMagick images now support the :max-width and :max-height | ||
| 699 | keywords. | ||
| 700 | |||
| 698 | ** Minibuffer | 701 | ** Minibuffer |
| 699 | 702 | ||
| 700 | *** In minibuffer filename prompts, `C-M-f' and `C-M-b' now move to the | 703 | *** In minibuffer filename prompts, `C-M-f' and `C-M-b' now move to the |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a3fc6bd172f..ff41129b906 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2013-06-23 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * net/shr.el (shr-rescale-image): Use the new | ||
| 4 | :max-width/:max-height functionality. | ||
| 5 | |||
| 1 | 2013-06-23 Ivan Kanis <ivan@kanis.fr> | 6 | 2013-06-23 Ivan Kanis <ivan@kanis.fr> |
| 2 | 7 | ||
| 3 | * net/eww.el (eww-search-prefix): New variable. | 8 | * net/eww.el (eww-search-prefix): New variable. |
diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 868956d3e21..979743f9588 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el | |||
| @@ -741,34 +741,18 @@ size, and full-buffer size." | |||
| 741 | (defun shr-rescale-image (data &optional force) | 741 | (defun shr-rescale-image (data &optional force) |
| 742 | "Rescale DATA, if too big, to fit the current buffer. | 742 | "Rescale DATA, if too big, to fit the current buffer. |
| 743 | If FORCE, rescale the image anyway." | 743 | If FORCE, rescale the image anyway." |
| 744 | (let ((image (create-image data nil t :ascent 100))) | 744 | (if (or (not (fboundp 'imagemagick-types)) |
| 745 | (if (or (not (fboundp 'imagemagick-types)) | 745 | (not (get-buffer-window (current-buffer)))) |
| 746 | (not (get-buffer-window (current-buffer)))) | 746 | (create-image data nil t :ascent 100) |
| 747 | image | 747 | (let ((edges (window-inside-pixel-edges |
| 748 | (let* ((size (image-size image t)) | 748 | (get-buffer-window (current-buffer))))) |
| 749 | (width (car size)) | 749 | (create-image |
| 750 | (height (cdr size)) | 750 | data 'imagemagick t |
| 751 | (edges (window-inside-pixel-edges | 751 | :ascent 100 |
| 752 | (get-buffer-window (current-buffer)))) | 752 | :max-width (truncate (* shr-max-image-proportion |
| 753 | (window-width (truncate (* shr-max-image-proportion | 753 | (- (nth 2 edges) (nth 0 edges)))) |
| 754 | (- (nth 2 edges) (nth 0 edges))))) | 754 | :max-height (truncate (* shr-max-image-proportion |
| 755 | (window-height (truncate (* shr-max-image-proportion | 755 | (- (nth 3 edges) (nth 1 edges)))))))) |
| 756 | (- (nth 3 edges) (nth 1 edges))))) | ||
| 757 | scaled-image) | ||
| 758 | (when (or force | ||
| 759 | (> height window-height)) | ||
| 760 | (setq image (or (create-image data 'imagemagick t | ||
| 761 | :height window-height | ||
| 762 | :ascent 100) | ||
| 763 | image)) | ||
| 764 | (setq size (image-size image t))) | ||
| 765 | (when (> (car size) window-width) | ||
| 766 | (setq image (or | ||
| 767 | (create-image data 'imagemagick t | ||
| 768 | :width window-width | ||
| 769 | :ascent 100) | ||
| 770 | image))) | ||
| 771 | image)))) | ||
| 772 | 756 | ||
| 773 | ;; url-cache-extract autoloads url-cache. | 757 | ;; url-cache-extract autoloads url-cache. |
| 774 | (declare-function url-cache-create-filename "url-cache" (url)) | 758 | (declare-function url-cache-create-filename "url-cache" (url)) |
diff --git a/src/ChangeLog b/src/ChangeLog index b2773ddbf50..f9451711f32 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2013-06-23 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 2 | |||
| 3 | * image.c (compute_image_size): New function to implement | ||
| 4 | :max-width and :max-height. | ||
| 5 | (imagemagick_load_image): Use it. | ||
| 6 | |||
| 1 | 2013-06-23 Paul Eggert <eggert@cs.ucla.edu> | 7 | 2013-06-23 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 8 | ||
| 3 | Try to avoid malloc SEGVs on Cygwin (Bug#14569). | 9 | Try to avoid malloc SEGVs on Cygwin (Bug#14569). |
diff --git a/src/image.c b/src/image.c index ffb3cd15e93..b65ee7df789 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -132,6 +132,8 @@ static void free_color_table (void); | |||
| 132 | static unsigned long *colors_in_color_table (int *n); | 132 | static unsigned long *colors_in_color_table (int *n); |
| 133 | #endif | 133 | #endif |
| 134 | 134 | ||
| 135 | Lisp_Object QCmax_width, QCmax_height; | ||
| 136 | |||
| 135 | /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap | 137 | /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap |
| 136 | id, which is just an int that this section returns. Bitmaps are | 138 | id, which is just an int that this section returns. Bitmaps are |
| 137 | reference counted so they can be shared among frames. | 139 | reference counted so they can be shared among frames. |
| @@ -7489,6 +7491,76 @@ gif_load (struct frame *f, struct image *img) | |||
| 7489 | #endif /* HAVE_GIF */ | 7491 | #endif /* HAVE_GIF */ |
| 7490 | 7492 | ||
| 7491 | 7493 | ||
| 7494 | static void | ||
| 7495 | compute_image_size (size_t width, size_t height, | ||
| 7496 | Lisp_Object spec, | ||
| 7497 | int *d_width, int *d_height) | ||
| 7498 | { | ||
| 7499 | Lisp_Object value; | ||
| 7500 | int desired_width, desired_height; | ||
| 7501 | |||
| 7502 | /* If width and/or height is set in the display spec assume we want | ||
| 7503 | to scale to those values. If either h or w is unspecified, the | ||
| 7504 | unspecified should be calculated from the specified to preserve | ||
| 7505 | aspect ratio. */ | ||
| 7506 | value = image_spec_value (spec, QCwidth, NULL); | ||
| 7507 | desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7508 | value = image_spec_value (spec, QCheight, NULL); | ||
| 7509 | desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7510 | |||
| 7511 | if (desired_width == -1) | ||
| 7512 | { | ||
| 7513 | value = image_spec_value (spec, QCmax_width, NULL); | ||
| 7514 | if (INTEGERP (value) && | ||
| 7515 | width > XFASTINT (value)) | ||
| 7516 | { | ||
| 7517 | /* The image is wider than :max-width. */ | ||
| 7518 | desired_width = XFASTINT (value); | ||
| 7519 | if (desired_height == -1) | ||
| 7520 | { | ||
| 7521 | value = image_spec_value (spec, QCmax_height, NULL); | ||
| 7522 | if (INTEGERP (value)) | ||
| 7523 | { | ||
| 7524 | /* We have no specified height, but we have a | ||
| 7525 | :max-height value, so check that we satisfy both | ||
| 7526 | conditions. */ | ||
| 7527 | desired_height = (double) desired_width / width * height; | ||
| 7528 | if (desired_height > XFASTINT (value)) | ||
| 7529 | { | ||
| 7530 | desired_height = XFASTINT (value); | ||
| 7531 | desired_width = (double) desired_height / height * width; | ||
| 7532 | } | ||
| 7533 | } | ||
| 7534 | else | ||
| 7535 | { | ||
| 7536 | /* We have no specified height and no specified | ||
| 7537 | max-height, so just compute the height. */ | ||
| 7538 | desired_height = (double) desired_width / width * height; | ||
| 7539 | } | ||
| 7540 | } | ||
| 7541 | } | ||
| 7542 | } | ||
| 7543 | |||
| 7544 | if (desired_height == -1) | ||
| 7545 | { | ||
| 7546 | value = image_spec_value (spec, QCmax_height, NULL); | ||
| 7547 | if (INTEGERP (value) && | ||
| 7548 | height > XFASTINT (value)) | ||
| 7549 | desired_height = XFASTINT (value); | ||
| 7550 | } | ||
| 7551 | |||
| 7552 | if (desired_width != -1 && desired_height == -1) | ||
| 7553 | /* w known, calculate h. */ | ||
| 7554 | desired_height = (double) desired_width / width * height; | ||
| 7555 | |||
| 7556 | if (desired_width == -1 && desired_height != -1) | ||
| 7557 | /* h known, calculate w. */ | ||
| 7558 | desired_width = (double) desired_height / height * width; | ||
| 7559 | |||
| 7560 | *d_width = desired_width; | ||
| 7561 | *d_height = desired_height; | ||
| 7562 | } | ||
| 7563 | |||
| 7492 | /*********************************************************************** | 7564 | /*********************************************************************** |
| 7493 | ImageMagick | 7565 | ImageMagick |
| 7494 | ***********************************************************************/ | 7566 | ***********************************************************************/ |
| @@ -7516,6 +7588,8 @@ enum imagemagick_keyword_index | |||
| 7516 | IMAGEMAGICK_BACKGROUND, | 7588 | IMAGEMAGICK_BACKGROUND, |
| 7517 | IMAGEMAGICK_HEIGHT, | 7589 | IMAGEMAGICK_HEIGHT, |
| 7518 | IMAGEMAGICK_WIDTH, | 7590 | IMAGEMAGICK_WIDTH, |
| 7591 | IMAGEMAGICK_MAX_HEIGHT, | ||
| 7592 | IMAGEMAGICK_MAX_WIDTH, | ||
| 7519 | IMAGEMAGICK_ROTATION, | 7593 | IMAGEMAGICK_ROTATION, |
| 7520 | IMAGEMAGICK_CROP, | 7594 | IMAGEMAGICK_CROP, |
| 7521 | IMAGEMAGICK_LAST | 7595 | IMAGEMAGICK_LAST |
| @@ -7538,6 +7612,8 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = | |||
| 7538 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, | 7612 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, |
| 7539 | {":height", IMAGE_INTEGER_VALUE, 0}, | 7613 | {":height", IMAGE_INTEGER_VALUE, 0}, |
| 7540 | {":width", IMAGE_INTEGER_VALUE, 0}, | 7614 | {":width", IMAGE_INTEGER_VALUE, 0}, |
| 7615 | {":max-height", IMAGE_INTEGER_VALUE, 0}, | ||
| 7616 | {":max-width", IMAGE_INTEGER_VALUE, 0}, | ||
| 7541 | {":rotation", IMAGE_NUMBER_VALUE, 0}, | 7617 | {":rotation", IMAGE_NUMBER_VALUE, 0}, |
| 7542 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} | 7618 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} |
| 7543 | }; | 7619 | }; |
| @@ -7726,24 +7802,10 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7726 | PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535); | 7802 | PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535); |
| 7727 | } | 7803 | } |
| 7728 | 7804 | ||
| 7729 | /* If width and/or height is set in the display spec assume we want | 7805 | compute_image_size (MagickGetImageWidth (image_wand), |
| 7730 | to scale to those values. If either h or w is unspecified, the | 7806 | MagickGetImageHeight (image_wand), |
| 7731 | unspecified should be calculated from the specified to preserve | 7807 | img->spec, &desired_width, &desired_height); |
| 7732 | aspect ratio. */ | ||
| 7733 | value = image_spec_value (img->spec, QCwidth, NULL); | ||
| 7734 | desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7735 | value = image_spec_value (img->spec, QCheight, NULL); | ||
| 7736 | desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); | ||
| 7737 | |||
| 7738 | height = MagickGetImageHeight (image_wand); | ||
| 7739 | width = MagickGetImageWidth (image_wand); | ||
| 7740 | 7808 | ||
| 7741 | if (desired_width != -1 && desired_height == -1) | ||
| 7742 | /* w known, calculate h. */ | ||
| 7743 | desired_height = (double) desired_width / width * height; | ||
| 7744 | if (desired_width == -1 && desired_height != -1) | ||
| 7745 | /* h known, calculate w. */ | ||
| 7746 | desired_width = (double) desired_height / height * width; | ||
| 7747 | if (desired_width != -1 && desired_height != -1) | 7809 | if (desired_width != -1 && desired_height != -1) |
| 7748 | { | 7810 | { |
| 7749 | status = MagickScaleImage (image_wand, desired_width, desired_height); | 7811 | status = MagickScaleImage (image_wand, desired_width, desired_height); |
| @@ -8895,6 +8957,8 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 8895 | DEFSYM (Qheuristic, "heuristic"); | 8957 | DEFSYM (Qheuristic, "heuristic"); |
| 8896 | 8958 | ||
| 8897 | DEFSYM (Qpostscript, "postscript"); | 8959 | DEFSYM (Qpostscript, "postscript"); |
| 8960 | DEFSYM (QCmax_width, ":max-width"); | ||
| 8961 | DEFSYM (QCmax_height, ":max-height"); | ||
| 8898 | #ifdef HAVE_GHOSTSCRIPT | 8962 | #ifdef HAVE_GHOSTSCRIPT |
| 8899 | ADD_IMAGE_TYPE (Qpostscript); | 8963 | ADD_IMAGE_TYPE (Qpostscript); |
| 8900 | DEFSYM (QCloader, ":loader"); | 8964 | DEFSYM (QCloader, ":loader"); |