From 3e67734ceb1f710a6039824b8c224b97cdebcd44 Mon Sep 17 00:00:00 2001 From: Timo Date: Sat, 25 Dec 2021 15:38:20 +0200 Subject: [PATCH] Add support for image mirroring (Bug#47095) * lisp/image.el (image-map): Keybinding for mirroring function. (image-mirror): New function that toggles image mirroring property. * src/image.c (syms_of_image): Add property. (image_set_transform): Modify image rotation code to also horizontally mirror the image when the property is set. * etc/NEWS: Add description. --- etc/NEWS | 4 ++++ lisp/image.el | 9 +++++++++ src/image.c | 26 ++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index c9466d0fef..08cf624020 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -570,6 +570,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 command 'image-mirror'. +This command mirrors (horizontally flips) the image under point. + ** Image-Dired +++ diff --git a/lisp/image.el b/lisp/image.el index 702985f41f..c060c4c650 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -181,6 +181,7 @@ image-map (define-key map [C-wheel-up] 'image-mouse-increase-size) (define-key map [C-mouse-4] 'image-mouse-increase-size) (define-key map "r" 'image-rotate) + (define-key map "h" 'image-mirror) (define-key map "o" 'image-save) map)) @@ -1249,6 +1250,14 @@ image-save (write-region (point-min) (point-max) (read-file-name "Write image to file: "))))) +(defun image-mirror () + "Mirror (horizontally flip) the image under point." + (interactive) + (let ((image (image--get-image))) + (image-flush image) + (setf (image-property image :mirror) + (not (image-property image :mirror))))) + (provide 'image) ;;; image.el ends here diff --git a/src/image.c b/src/image.c index 1d83065cf7..5b324637ce 100644 --- a/src/image.c +++ b/src/image.c @@ -2406,6 +2406,11 @@ image_set_transform (struct frame *f, struct image *img) double rotation = 0.0; compute_image_rotation (img, &rotation); + /* Determine mirroring. */ + bool mirroring; + Lisp_Object m = image_spec_value (img->spec, QCmirror, NULL); + mirroring = !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 @@ -2445,14 +2450,20 @@ image_set_transform (struct frame *f, struct image *img) /* Perform rotation transformation. */ int rotate_flag = -1; - if (rotation == 0) + if (rotation == 0 && !mirroring) 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) + { + cos_r = 1; + sin_r = 0; + rotate_flag = 1; + } + else if (rotation == 90) { width = img->height; height = img->width; @@ -2493,9 +2504,14 @@ image_set_transform (struct frame *f, struct image *img) matrix3x3 v; matrix3x3_mult (rot, u, v); - /* 3. Translate back. */ + /* 3. Translate back. Apply mirroring if requested. */ t[2][0] = width * -.5; t[2][1] = height * -.5; + if (mirroring) + { + 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. */ @@ -2513,9 +2529,10 @@ image_set_transform (struct frame *f, struct image *img) matrix3x3 v; matrix3x3_mult (u, rot, v); - /* 3. Translate back. */ + /* 3. Translate back. Apply mirroring if requested. */ t[2][0] = width * .5; t[2][1] = height * .5; + if (mirroring) t[0][0] = -t[0][0]; matrix3x3_mult (v, t, matrix); # endif img->width = width; @@ -11363,6 +11380,7 @@ syms_of_image (void) DEFSYM (QCtransform_smoothing, ":transform-smoothing"); DEFSYM (QCcolor_adjustment, ":color-adjustment"); DEFSYM (QCmask, ":mask"); + DEFSYM (QCmirror, ":mirror"); /* Other symbols. */ DEFSYM (Qlaplace, "laplace"); -- 2.32.0 (Apple Git-132)