Maintain relationship between tool bar image and default font width

* doc/lispref/display.texi (Image Descriptors): Document new
value of QCscale.

* lisp/cus-start.el (standard) <image-scaling-factor>: New
definition.

* lisp/image.el (image-scaling-factor): Move to C.
(create-image): Provide `default' as the default scaling factor.
(image--default-smoothing): Accept non-integer scaling factors.
(image-compute-scaling-factor): Document that this function
is no longer invoked by Emacs.

* lisp/tool-bar.el (tool-bar--image-expression): Disable
transform smoothing for tool-bar icons.

* src/dispextern.h (clear_image_cache): New definition.

* src/frame.c (gui_set_font): Clear such image cache entries as
derive their scales from the default font width.

* src/image.c (clear_image_cache): Export function.
(compute_image_size): Implement `default' by reading
Vimage_scaling_factor and/or computing a scale factor from the
frame's column width, as the case may be.
New argument F.  All callers changed.
(syms_of_image) <Vimage_scaling_factor>: Move from image.el.
This commit is contained in:
Po Lu 2024-06-03 16:34:51 +08:00
parent 760b54de08
commit 5637658513
7 changed files with 82 additions and 27 deletions

View file

@ -5943,6 +5943,16 @@ values. If both @code{:scale} and @code{:height}/@code{:width} are
specified, the height/width will be adjusted by the specified scaling
factor.
@vindex image-scaling-factor
Alternatively, the symbol @code{default} may be specified, indicating
that the image should be scaled according as the value of the
@code{image-scaling-factor} variable, which by default scales the image
in proportion to the average widths (@pxref{Low-Level Font}) of the
default faces of frames on which it happens to be displayed, if such
widths should exceed @code{10} pixels. If no other value is provided,
@code{create-image} will specify this value in image specifications it
creates.
@item :rotation @var{angle}
Specifies a rotation angle in degrees. Only multiples of 90 degrees
are supported, unless the image type is @code{imagemagick}. Positive

View file

@ -361,6 +361,10 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
;; fringe.c
(overflow-newline-into-fringe fringe boolean)
;; image.c
(image-scaling-factor image
(choice number
(const :tag "Automatically compute" auto))
"26.1")
(imagemagick-render-type image integer "24.1")
;; indent.c
(indent-tabs-mode indent boolean)

View file

@ -136,18 +136,6 @@ Subdirectories are not automatically included in the search."
:type '(repeat (choice directory variable))
:initialize #'custom-initialize-delay)
(defcustom image-scaling-factor 'auto
"When displaying images, apply this scaling factor before displaying.
This is not supported for all image types, and is mostly useful
when you have a high-resolution monitor.
The value is either a floating point number (where numbers higher
than 1 means to increase the size and lower means to shrink the
size), or the symbol `auto', which will compute a scaling factor
based on the font pixel size."
:type '(choice number
(const :tag "Automatically compute" auto))
:version "26.1")
(defcustom image-transform-smoothing #'image--default-smoothing
"Whether to do smoothing when applying transforms to images.
Common transforms are rescaling and rotation.
@ -548,9 +536,7 @@ Images should not be larger than specified by `max-image-size'."
file-or-data)
(and (not (plist-get props :scale))
;; Add default scaling.
(list :scale
(image-compute-scaling-factor
image-scaling-factor)))
(list :scale 'default))
props)))
;; Add default smoothing.
(unless (plist-member props :transform-smoothing)
@ -579,7 +565,7 @@ Images should not be larger than specified by `max-image-size'."
(rotation (plist-get props :rotation)))
(cond
;; We always smooth when scaling down and small upwards scaling.
((and scaling (< scaling 2))
((and scaling (numberp scaling) (< scaling 2))
t)
;; Smooth when doing non-90-degree rotation
((and rotation
@ -619,7 +605,11 @@ properties specific to certain image types."
(defun image-compute-scaling-factor (&optional scaling)
"Compute the scaling factor based on SCALING.
If a number, use that. If it's `auto', compute the factor.
If nil, use the `image-scaling-factor' variable."
If nil, use the `image-scaling-factor' variable.
This function is provided for the benefit of Lisp code that
must compute this factor; it does not affect Emacs's scaling
of images."
(unless scaling
(setq scaling image-scaling-factor))
(cond

View file

@ -220,7 +220,8 @@ To define items in any other map, use `tool-bar-local-item'."
(let* ((fg (face-attribute 'tool-bar :foreground))
(bg (face-attribute 'tool-bar :background))
(colors (nconc (if (eq fg 'unspecified) nil (list :foreground fg))
(if (eq bg 'unspecified) nil (list :background bg))))
(if (eq bg 'unspecified) nil (list :background bg))
'(:transform-smoothing nil)))
(xpm-spec (list :type 'xpm :file (concat icon ".xpm")))
(xpm-lo-spec (list :type 'xpm :file
(concat "low-color/" icon ".xpm")))

View file

@ -3621,6 +3621,7 @@ extern void update_redisplay_ticks (int, struct window *);
#ifdef HAVE_WINDOW_SYSTEM
extern void clear_image_cache (struct frame *, Lisp_Object);
extern ptrdiff_t image_bitmap_pixmap (struct frame *, ptrdiff_t);
extern void image_reference_bitmap (struct frame *, ptrdiff_t);
extern ptrdiff_t image_create_bitmap_from_data (struct frame *, char *,

View file

@ -4811,6 +4811,10 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
/* Recalculate toolbar height. */
f->n_tool_bar_rows = 0;
/* Clean F's image cache of images whose values derive from the font
width. */
clear_image_cache (f, Qauto);
/* Ensure we redraw it. */
clear_current_matrices (f);

View file

@ -2327,7 +2327,7 @@ free_image_cache (struct frame *f)
If image-cache-eviction-delay is non-nil, this frees images in the cache
which weren't displayed for at least that many seconds. */
static void
void
clear_image_cache (struct frame *f, Lisp_Object filter)
{
struct image_cache *c = FRAME_IMAGE_CACHE (f);
@ -2670,17 +2670,49 @@ image_get_dimension (struct image *img, Lisp_Object symbol)
return -1;
}
/* Compute the desired size of an image with native size WIDTH x HEIGHT.
Use IMG to deduce the size. Store the desired size into
*D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
/* Compute the desired size of an image with native size WIDTH x HEIGHT,
which is to be displayed on F. Use IMG to deduce the size. Store
the desired size into *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the
native size is OK. */
static void
compute_image_size (double width, double height,
compute_image_size (struct frame *f, double width, double height,
struct image *img,
int *d_width, int *d_height)
{
double scale = 1;
Lisp_Object value = image_spec_value (img->spec, QCscale, NULL);
if (NUMBERP (value))
if (EQ (value, Qdefault))
{
Lisp_Object sval = Vimage_scaling_factor;
/* Compute the scale from factors specified by the value of
Vimage_scaling_factor. */
invalid_value:
if (EQ (sval, Qauto))
{
/* This is a tag with which callers of `clear_image_cache' can
refer to this image and its likenesses. */
img->dependencies = Fcons (Qauto, img->dependencies);
scale = (FRAME_COLUMN_WIDTH (f) > 10
? (FRAME_COLUMN_WIDTH (f) / 10.0f) : 1);
}
else if (NUMBERP (sval))
scale = XFLOATINT (sval);
else
{
image_error ("Invalid `image-scaling-factor': %s",
Vimage_scaling_factor);
/* If Vimage_scaling_factor is set to an invalid value, treat
it as though it were the default. */
sval = Qauto;
goto invalid_value;
}
}
else if (NUMBERP (value))
{
double dval = XFLOATINT (value);
if (0 <= dval)
@ -3009,7 +3041,8 @@ image_set_transform (struct frame *f, struct image *img)
}
else
#endif
compute_image_size (img->width, img->height, img, &width, &height);
compute_image_size (f, img->width, img->height, img, &width,
&height);
/* Determine rotation. */
double rotation = 0.0;
@ -11161,7 +11194,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
}
#ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
compute_image_size (MagickGetImageWidth (image_wand),
compute_image_size (f, MagickGetImageWidth (image_wand),
MagickGetImageHeight (image_wand),
img, &desired_width, &desired_height);
#else
@ -12134,7 +12167,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
#endif
#ifdef HAVE_NATIVE_TRANSFORMS
compute_image_size (viewbox_width, viewbox_height, img,
compute_image_size (f, viewbox_width, viewbox_height, img,
&width, &height);
width = scale_image_size (width, 1, FRAME_SCALE_FACTOR (f));
@ -12877,6 +12910,7 @@ non-numeric, there is no explicit limit on the size of images. */);
DEFSYM (Qcount, "count");
DEFSYM (Qextension_data, "extension-data");
DEFSYM (Qdelay, "delay");
DEFSYM (Qauto, "auto");
/* Keywords. */
DEFSYM (QCascent, ":ascent");
@ -13089,6 +13123,17 @@ The value can also be nil, meaning the cache is never cleared.
The function `clear-image-cache' disregards this variable. */);
Vimage_cache_eviction_delay = make_fixnum (300);
DEFVAR_LISP ("image-scaling-factor", Vimage_scaling_factor,
doc: /* When displaying images, apply this scaling factor before displaying.
This is not supported for all image types, and is mostly useful
when you have a high-resolution monitor.
The value is either a floating point number (where numbers higher
than 1 means to increase the size and lower means to shrink the
size), or the symbol `auto', which will compute a scaling factor
based on the font pixel size. */);
Vimage_scaling_factor = Qauto;
#ifdef HAVE_IMAGEMAGICK
DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type,
doc: /* Integer indicating which ImageMagick rendering method to use.