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.
This commit is contained in:
parent
e854cfc719
commit
f3f9606c7a
7 changed files with 121 additions and 45 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
3
etc/NEWS
3
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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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).
|
||||
|
|
98
src/image.c
98
src/image.c
|
@ -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);
|
||||
compute_image_size (MagickGetImageWidth (image_wand),
|
||||
MagickGetImageHeight (image_wand),
|
||||
img->spec, &desired_width, &desired_height);
|
||||
|
||||
height = MagickGetImageHeight (image_wand);
|
||||
width = MagickGetImageWidth (image_wand);
|
||||
|
||||
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");
|
||||
|
|
Loading…
Add table
Reference in a new issue