[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 6fbea946bf: Add support for image flipping
From: |
Lars Ingebrigtsen |
Subject: |
master 6fbea946bf: Add support for image flipping |
Date: |
Fri, 24 Jun 2022 08:45:46 -0400 (EDT) |
branch: master
commit 6fbea946bfd0119cf517211d058ea277c9209a87
Author: Timo Taipalus <timo@taipalus.cc>
Commit: Lars Ingebrigtsen <larsi@gnus.org>
Add support for image flipping
* lisp/image.el (image-map): Keybindings for flipping functions.
(image-flip-horizontally): New function that toggles image flipping
property.
(image-flip-vertically): New function that toggles image flipping
property and rotates image 180 degrees.
* src/image.c (syms_of_image): Add property.
(image_set_transform): Modify image rotation code to also horizontally
flip the image when the property is set.
* etc/NEWS: Add description.
* doc/lispref/display.texi (Image Descriptors): Document :flip
(bug#47095).
---
doc/lispref/display.texi | 6 ++++++
etc/NEWS | 4 ++++
lisp/image.el | 18 ++++++++++++++++++
src/image.c | 31 +++++++++++++++++++++++++++----
4 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 3d1d9e24dd..e85d492bbb 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5717,6 +5717,12 @@ are supported, unless the image type is
@code{imagemagick}. Positive
values rotate clockwise, negative values counter-clockwise. Rotation
is performed after scaling and cropping.
+@item :flip @var{flip}
+If this is @code{t}, the image will be horizontally flipped.
+Currently it has no effect if the image type is @code{imagemagick}.
+Vertical flipping can be achieved by rotating the image 180 degrees
+and toggling this value.
+
@item :transform-smoothing @var{smooth}
If this is @code{t}, any image transform will have smoothing applied;
if @code{nil}, no smoothing will be applied. The exact algorithm used
diff --git a/etc/NEWS b/etc/NEWS
index 552c8d1d49..cb9e7417b6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1545,6 +1545,10 @@ This controls whether or not to show a message when
opening certain
image formats saying how to edit it as text. The default is to show
this message for SVG and XPM.
++++
+*** New commands: 'image-flip-horizontally' and 'image-flip-vertically'.
+These commands horizontally and vertically flip the image under point.
+
** Image-Dired
+++
diff --git a/lisp/image.el b/lisp/image.el
index 8c5cfa7c0b..e90cccaa09 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -177,6 +177,8 @@ or \"ffmpeg\") is installed."
"+" #'image-increase-size
"r" #'image-rotate
"o" #'image-save
+ "h" #'image-flip-horizontally
+ "v" #'image-flip-vertically
"C-<wheel-down>" #'image-mouse-decrease-size
"C-<mouse-5>" #'image-mouse-decrease-size
"C-<wheel-up>" #'image-mouse-increase-size
@@ -1288,6 +1290,22 @@ changing the displayed image size does not affect the
saved image."
(write-region (point-min) (point-max)
(read-file-name "Write image to file: ")))))
+(defun image-flip-horizontally ()
+ "Horizontally flip the image under point."
+ (interactive)
+ (let ((image (image--get-image)))
+ (image-flush image)
+ (setf (image-property image :flip)
+ (not (image-property image :flip)))))
+
+(defun image-flip-vertically ()
+ "Vertically flip the image under point."
+ (interactive)
+ (let ((image (image--get-image)))
+ (image-rotate 180)
+ (setf (image-property image :flip)
+ (not (image-property image :flip)))))
+
(provide 'image)
;;; image.el ends here
diff --git a/src/image.c b/src/image.c
index 2e2f8fe364..0e4b2e0f62 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2587,6 +2587,11 @@ image_set_transform (struct frame *f, struct image *img)
double rotation = 0.0;
compute_image_rotation (img, &rotation);
+ /* Determine flipping. */
+ bool flip;
+ Lisp_Object m = image_spec_value (img->spec, QCflip, NULL);
+ flip = !NILP (m);
+
#ifndef HAVE_HAIKU
# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS
/* We want scale up operations to use a nearest neighbor filter to
@@ -2626,14 +2631,25 @@ image_set_transform (struct frame *f, struct image *img)
/* Perform rotation transformation. */
int rotate_flag = -1;
- if (rotation == 0)
+ if (rotation == 0 && !flip)
rotate_flag = 0;
else
{
# if (defined USE_CAIRO || defined HAVE_XRENDER \
|| defined HAVE_NTGUI || defined HAVE_NS)
int cos_r, sin_r;
- if (rotation == 90)
+ if (rotation == 0)
+ {
+ /* FLIP is always true here. As this will rotate by 0
+ degrees, it has no visible effect. Applying only
+ translation matrix to the image would be sufficient for
+ horizontal flipping, but writing special handling for
+ this case would increase code complexity somewhat. */
+ cos_r = 1;
+ sin_r = 0;
+ rotate_flag = 1;
+ }
+ else if (rotation == 90)
{
width = img->height;
height = img->width;
@@ -2674,9 +2690,14 @@ image_set_transform (struct frame *f, struct image *img)
matrix3x3 v;
matrix3x3_mult (rot, u, v);
- /* 3. Translate back. */
+ /* 3. Translate back. Flip horizontally if requested. */
t[2][0] = width * -.5;
t[2][1] = height * -.5;
+ if (flip)
+ {
+ t[0][0] = -t[0][0];
+ t[2][0] = -t[2][0];
+ }
matrix3x3_mult (t, v, matrix);
# else
/* 1. Translate so (0, 0) is in the center of the image. */
@@ -2694,9 +2715,10 @@ image_set_transform (struct frame *f, struct image *img)
matrix3x3 v;
matrix3x3_mult (u, rot, v);
- /* 3. Translate back. */
+ /* 3. Translate back. Flip horizontally if requested. */
t[2][0] = width * .5;
t[2][1] = height * .5;
+ if (flip) t[0][0] = -t[0][0];
matrix3x3_mult (v, t, matrix);
# endif
img->width = width;
@@ -11940,6 +11962,7 @@ non-numeric, there is no explicit limit on the size of
images. */);
DEFSYM (QCtransform_smoothing, ":transform-smoothing");
DEFSYM (QCcolor_adjustment, ":color-adjustment");
DEFSYM (QCmask, ":mask");
+ DEFSYM (QCflip, ":flip");
/* Other symbols. */
DEFSYM (Qlaplace, "laplace");
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 6fbea946bf: Add support for image flipping,
Lars Ingebrigtsen <=