From b58619431d6fa0f6b9f50a94aefc09be6121fa3e Mon Sep 17 00:00:00 2001 From: Timo Date: Wed, 29 Dec 2021 10:55:06 +0200 Subject: [PATCH] Add support for image flipping (Bug#47095) * 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 by 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. --- etc/NEWS | 4 ++++ lisp/image.el | 18 ++++++++++++++++++ src/image.c | 26 ++++++++++++++++++++++---- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index c9466d0fef..ae894c5465 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 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 702985f41f..05e50cc4ae 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -181,6 +181,8 @@ 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-flip-horizontally) + (define-key map "v" 'image-flip-vertically) (define-key map "o" 'image-save) map)) @@ -1249,6 +1251,22 @@ image-save (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 1d83065cf7..5cbc85f357 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 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 @@ -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 && !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) + { + 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. 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. */ @@ -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. 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; @@ -11363,6 +11380,7 @@ syms_of_image (void) DEFSYM (QCtransform_smoothing, ":transform-smoothing"); DEFSYM (QCcolor_adjustment, ":color-adjustment"); DEFSYM (QCmask, ":mask"); + DEFSYM (QCflip, ":flip"); /* Other symbols. */ DEFSYM (Qlaplace, "laplace"); -- 2.32.0 (Apple Git-132)