Allow using :width/:height as normal with xbm images

* doc/lispref/display.texi (XBM Images): Adjust the documentation.
* src/image.c (enum xbm_keyword_index): Add :data-width and
:data-height.
(xbm_format): Ditto.
(xbm_image_p): Allow passing in :width/:height for display.
(xbm_load): Use :data-width/:data-height.
This commit is contained in:
Lars Ingebrigtsen 2022-06-20 11:18:31 +02:00
parent 1172c7303d
commit bd0b96d252
4 changed files with 42 additions and 43 deletions

View file

@ -5930,13 +5930,10 @@ There are three formats you can use for @var{data}:
@itemize @bullet
@item
A vector of strings or bool-vectors, each specifying one line of the
image. Do specify @code{:height} and @code{:width}.
image. Do specify @code{:data-height} and @code{:data-width}.
@item
A string containing the same byte sequence as an XBM file would contain.
You must not specify @code{:height} and @code{:width} in this case,
because omitting them is what indicates the data has the format of an
XBM file. The file contents specify the height and width of the image.
@item
A string or a bool-vector containing the bits of the image (plus
@ -5944,26 +5941,11 @@ perhaps some extra bits at the end that will not be used). It should
contain at least @w{@code{@var{stride} * @var{height}}} bits, where
@var{stride} is the smallest multiple of 8 greater than or equal to
the width of the image. In this case, you should specify
@code{:height}, @code{:width} and @code{:stride}, both to indicate
that the string contains just the bits rather than a whole XBM file,
and to specify the size of the image.
@code{:data-height}, @code{:data-width} and @code{:stride}, both to
indicate that the string contains just the bits rather than a whole
XBM file, and to specify the size of the image.
@end itemize
@item :width @var{width}
The value, @var{width}, specifies the width of the image, in pixels.
@item :height @var{height}
The value, @var{height}, specifies the height of the image, in pixels.
Note that @code{:width} and @code{:height} can only be used if passing
in data that doesn't specify the width and height (e.g., a string or a
vector containing the bits of the image). @acronym{XBM} files usually
specify this themselves, and it's an error to use these two properties
on these files. Also note that @code{:width} and @code{:height} are
used by most other image formats to specify what the displayed image
is supposed to be, which usually means performing some sort of
scaling. This isn't supported for @acronym{XBM} images.
@item :stride @var{stride}
The number of bool vector entries stored for each row; the smallest
multiple of 8 greater than or equal to @var{width}.

View file

@ -1880,6 +1880,18 @@ Emacs buffers, like indentation and the like. The new ert function
* Incompatible Lisp Changes in Emacs 29.1
+++
** Changes to "raw" in-memory xbm images are specified.
Some years back Emacs gained the ability to scale images, and you
could then specify :width and :height when using 'create-image' on all
image types -- except xbm images, because this format already used the
:width and :height arguments to specify the width/height of the "raw"
in-memory format. This meant that if you used these specifications
on, for instance, xbm files, Emacs would refuse to display them. This
has been changed, and :width/:height now works as with all other image
formats, and the way to specify the width/height of the "raw"
in-memory format is now by using :data-width and :data-height.
+++
** loaddefs.el generation has been reimplemented.
The various loaddefs.el files in the Emacs tree (which contain

View file

@ -3723,6 +3723,8 @@ enum xbm_keyword_index
XBM_ALGORITHM,
XBM_HEURISTIC_MASK,
XBM_MASK,
XBM_DATA_WIDTH,
XBM_DATA_HEIGHT,
XBM_LAST
};
@ -3744,7 +3746,9 @@ static const struct image_keyword xbm_format[XBM_LAST] =
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
{":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":data-width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
{":data-height", IMAGE_POSITIVE_INTEGER_VALUE, 0}
};
/* Tokens returned from xbm_scan. */
@ -3766,8 +3770,8 @@ enum xbm_token
an entry `:file FILENAME' where FILENAME is a string.
If the specification is for a bitmap loaded from memory it must
contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
WIDTH and HEIGHT are integers > 0. DATA may be:
contain `:data-width WIDTH', `:data-height HEIGHT', and `:data DATA',
where WIDTH and HEIGHT are integers > 0. DATA may be:
1. a string large enough to hold the bitmap data, i.e. it must
have a size >= (WIDTH + 7) / 8 * HEIGHT
@ -3777,9 +3781,7 @@ enum xbm_token
3. a vector of strings or bool-vectors, one for each line of the
bitmap.
4. a string containing an in-memory XBM file. WIDTH and HEIGHT
may not be specified in this case because they are defined in the
XBM file.
4. a string containing an in-memory XBM file.
Both the file and data forms may contain the additional entries
`:background COLOR' and `:foreground COLOR'. If not present,
@ -3799,13 +3801,13 @@ xbm_image_p (Lisp_Object object)
if (kw[XBM_FILE].count)
{
if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
if (kw[XBM_DATA].count)
return 0;
}
else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
{
/* In-memory XBM file. */
if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
if (kw[XBM_FILE].count)
return 0;
}
else
@ -3814,14 +3816,14 @@ xbm_image_p (Lisp_Object object)
int width, height, stride;
/* Entries for `:width', `:height' and `:data' must be present. */
if (!kw[XBM_WIDTH].count
|| !kw[XBM_HEIGHT].count
if (!kw[XBM_DATA_WIDTH].count
|| !kw[XBM_DATA_HEIGHT].count
|| !kw[XBM_DATA].count)
return 0;
data = kw[XBM_DATA].value;
width = XFIXNAT (kw[XBM_WIDTH].value);
height = XFIXNAT (kw[XBM_HEIGHT].value);
width = XFIXNAT (kw[XBM_DATA_WIDTH].value);
height = XFIXNAT (kw[XBM_DATA_HEIGHT].value);
if (!kw[XBM_STRIDE].count)
stride = width;
@ -4445,8 +4447,8 @@ xbm_load (struct frame *f, struct image *img)
/* Get specified width, and height. */
if (!in_memory_file_p)
{
img->width = XFIXNAT (fmt[XBM_WIDTH].value);
img->height = XFIXNAT (fmt[XBM_HEIGHT].value);
img->width = XFIXNAT (fmt[XBM_DATA_WIDTH].value);
img->height = XFIXNAT (fmt[XBM_DATA_HEIGHT].value);
eassert (img->width > 0 && img->height > 0);
if (!check_image_size (f, img->width, img->height))
{

View file

@ -29,22 +29,25 @@
(ert-deftest image-test-duplicate-keywords ()
"Test that duplicate keywords in an image spec lead to rejection."
(should-error (image-size `(image :type xbm :type xbm :width 1 :height 1
(should-error (image-size `(image :type xbm :type xbm
:data-width 1 :data-height 1
:data ,(bool-vector t))
t)))
(ert-deftest image-test-circular-plist ()
"Test that a circular image spec is rejected."
(should-error
(let ((l `(image :type xbm :width 1 :height 1 :data ,(bool-vector t))))
(let ((l `(image :type xbm :data-width 1 :data-height 1
:data ,(bool-vector t))))
(setcdr (last l) '#1=(:invalid . #1#))
(image-size l t))))
(ert-deftest image-test-:type-property-value ()
"Test that :type is allowed as a property value in an image spec."
(should (equal (image-size `(image :dummy :type :type xbm :width 1 :height 1
:data ,(bool-vector t))
t)
(should (equal (image-size `(image :dummy :type :type xbm
:data-width 1 :data-height 1
:data ,(bool-vector t))
t)
(cons 1 1))))
(ert-deftest image-test-circular-specs ()
@ -52,9 +55,9 @@
(should
(let* ((circ1 (cons :dummy nil))
(circ2 (cons :dummy nil))
(spec1 `(image :type xbm :width 1 :height 1
(spec1 `(image :type xbm :data-width 1 :data-height 1
:data ,(bool-vector 1) :ignored ,circ1))
(spec2 `(image :type xbm :width 1 :height 1
(spec2 `(image :type xbm :data-width 1 :data-height 1
:data ,(bool-vector 1) :ignored ,circ2)))
(setcdr circ1 circ1)
(setcdr circ2 circ2)