emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c237209: Allow use of em in image spec sizes


From: Alan Third
Subject: master c237209: Allow use of em in image spec sizes
Date: Thu, 15 Apr 2021 13:08:51 -0400 (EDT)

branch: master
commit c2372096433e6a7ab173e5f1993f0c65b85f353e
Author: Alan Third <alan@idiocy.org>
Commit: Alan Third <alan@idiocy.org>

    Allow use of em in image spec sizes
    
    * src/image.c (image_get_dimension): New function.
    (compute_image_size): Use image_get_dimension to set the sizes, and
    pass in the image struct instead of just the spec.
    (image_set_transform):
    (imagemagick_load_image):
    (svg_load_image): Use the image instead of the spec in compute_image_size.
    (syms_of_image): Add 'em' as a symbol.
---
 doc/lispref/display.texi | 10 +++++++++
 etc/NEWS                 |  7 ++++++
 src/image.c              | 58 ++++++++++++++++++++++++++++++++++--------------
 3 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 82684cd..39ec715 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5298,6 +5298,16 @@ where @var{props} is a property list of alternating 
keyword symbols
 and values, including at least the pair @code{:type @var{type}} that
 specifies the image type.
 
+  Image descriptors which define image dimensions, @code{:width},
+@code{:height}, @code{:max-width} and @code{:max-height}, may take
+either an integer, which represents the dimension in pixels, or a pair
+@code{(@var{value} . em)}, where @var{value} is the dimension's
+length in @dfn{ems}@footnote{In typography an em is a distance
+equivalent to the height of the type.  For example when using 12 point
+type 1 em is equal to 12 points.  Its use ensures distances and type
+remain proportional.}.  One em is equivalent to the height of the font
+and @var{value} may be an integer or a float.
+
   The following is a list of properties that are meaningful for all
 image types (there are also properties which are meaningful only for
 certain image types, as documented in the following subsections):
diff --git a/etc/NEWS b/etc/NEWS
index 6113aa6..e39aa7b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1559,6 +1559,13 @@ will match the font size in use where it is embedded.
 
 This feature relies on librsvg 2.48 or above being available.
 
++++
+*** Image properties support 'em' sizes.
+Size image properties, for example ':height', ':max-height', etc., can
+be given a cons of the form '(SIZE . em)', where SIZE is an integer or
+float which is multiplied by the font size to calculate the image
+size, and em is a symbol.
+
 ** EWW
 
 +++
diff --git a/src/image.c b/src/image.c
index 6fe0b23..1619886 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1987,46 +1987,68 @@ scale_image_size (int size, size_t divisor, size_t 
multiplier)
   return INT_MAX;
 }
 
+/* Return a size, in pixels, from the value specified by SYMBOL, which
+   may be an integer or a pair of the form (VALUE . 'em) where VALUE
+   is a float that is multiplied by the font size to get the final
+   dimension.
+
+   If the value doesn't exist in the image spec, or is invalid, return
+   -1.
+*/
+static int
+image_get_dimension (struct image *img, Lisp_Object symbol)
+{
+  Lisp_Object value = image_spec_value (img->spec, symbol, NULL);
+
+  if (FIXNATP (value))
+    return min (XFIXNAT (value), INT_MAX);
+  if (CONSP (value) && NUMBERP (CAR (value)) && EQ (Qem, CDR (value)))
+    return min (img->face_font_size * XFLOATINT (CAR (value)), INT_MAX);
+
+  return -1;
+}
+
 /* Compute the desired size of an image with native size WIDTH x HEIGHT.
    Use SPEC 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 (size_t width, size_t height,
-                   Lisp_Object spec,
+                   struct image *img,
                    int *d_width, int *d_height)
 {
   Lisp_Object value;
+  int int_value;
   int desired_width = -1, desired_height = -1, max_width = -1, max_height = -1;
   double scale = 1;
 
-  value = image_spec_value (spec, QCscale, NULL);
+  value = image_spec_value (img->spec, QCscale, NULL);
   if (NUMBERP (value))
     scale = XFLOATINT (value);
 
-  value = image_spec_value (spec, QCmax_width, NULL);
-  if (FIXNATP (value))
-    max_width = min (XFIXNAT (value), INT_MAX);
+  int_value = image_get_dimension (img, QCmax_width);
+  if (int_value >= 0)
+    max_width = int_value;
 
-  value = image_spec_value (spec, QCmax_height, NULL);
-  if (FIXNATP (value))
-    max_height = min (XFIXNAT (value), INT_MAX);
+  int_value = image_get_dimension (img, QCmax_height);
+  if (int_value >= 0)
+    max_height = int_value;
 
   /* 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);
-  if (FIXNATP (value))
+  int_value = image_get_dimension (img, QCwidth);
+  if (int_value >= 0)
     {
-      desired_width = min (XFIXNAT (value) * scale, INT_MAX);
+      desired_width = int_value;
       /* :width overrides :max-width. */
       max_width = -1;
     }
 
-  value = image_spec_value (spec, QCheight, NULL);
-  if (FIXNATP (value))
+  int_value = image_get_dimension (img, QCheight);
+  if (int_value >= 0)
     {
-      desired_height = min (XFIXNAT (value) * scale, INT_MAX);
+      desired_height = int_value;
       /* :height overrides :max-height. */
       max_height = -1;
     }
@@ -2216,7 +2238,7 @@ image_set_transform (struct frame *f, struct image *img)
     }
   else
 #endif
-    compute_image_size (img->width, img->height, img->spec, &width, &height);
+    compute_image_size (img->width, img->height, img, &width, &height);
 
   /* Determine rotation.  */
   double rotation = 0.0;
@@ -9210,7 +9232,7 @@ imagemagick_load_image (struct frame *f, struct image 
*img,
 
   compute_image_size (MagickGetImageWidth (image_wand),
                      MagickGetImageHeight (image_wand),
-                     img->spec, &desired_width, &desired_height);
+                     img, &desired_width, &desired_height);
 
   if (desired_width != -1 && desired_height != -1)
     {
@@ -10068,7 +10090,7 @@ svg_load_image (struct frame *f, struct image *img, 
char *contents,
     viewbox_height = dimension_data.height;
   }
 
-  compute_image_size (viewbox_width, viewbox_height, img->spec,
+  compute_image_size (viewbox_width, viewbox_height, img,
                       &width, &height);
 
   width *= FRAME_SCALE_FACTOR (f);
@@ -10777,6 +10799,8 @@ non-numeric, there is no explicit limit on the size of 
images.  */);
   DEFSYM (QCmax_width, ":max-width");
   DEFSYM (QCmax_height, ":max-height");
 
+  DEFSYM (Qem, "em");
+
 #ifdef HAVE_NATIVE_TRANSFORMS
   DEFSYM (Qscale, "scale");
   DEFSYM (Qrotate, "rotate");



reply via email to

[Prev in Thread] Current Thread [Next in Thread]