]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow use of em in image spec sizes
authorAlan Third <alan@idiocy.org>
Mon, 12 Apr 2021 19:30:12 +0000 (20:30 +0100)
committerAlan Third <alan@idiocy.org>
Thu, 15 Apr 2021 16:56:23 +0000 (17:56 +0100)
* 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
etc/NEWS
src/image.c

index 82684cd2720f89c142435cccdec9fccb5677b29d..39ec715b4ccd53af22897c664b43c7275e49f75f 100644 (file)
@@ -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):
index 6113aa6fb22b244153b8d58b3772b0205d17d750..e39aa7b4378379fb802ceabb6db31cb325d69826 100644 (file)
--- 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
 
 +++
index 6fe0b23f7304535034cc69089f7565de37b96213..1619886f5a1210443b612b72339f34ed046f65fd 100644 (file)
@@ -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");