unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Timo Taipalus <timo@taipalus.cc>
To: Timo Taipalus <timo@taipalus.cc>
Cc: 47095@debbugs.gnu.org
Subject: bug#47095: [PATCH] Add support for image mirroring (Bug#47095)
Date: Wed, 29 Dec 2021 11:10:03 +0200	[thread overview]
Message-ID: <3b23f6a58f935098122e3bbf21e0f59c@taipalus.cc> (raw)
In-Reply-To: <YcrzY297jC/MFYU8@idiocy.org>

[-- Attachment #1: Type: text/plain, Size: 1628 bytes --]

On 28.12.2021 13:22, Alan Third wrote:
> On Mon, Dec 27, 2021 at 10:36:43AM +0200, Timo Taipalus wrote:
>> It seems image-mode does not have capability for image mirroring, so
>> here's a patch for it.  Tested NS (macOS) and XRender/Cairo
>> implementations.  As it is, it has no effect if ImageMagick is
>> enabled.
> 
> I suspect this won't work at all on windows due to the way the
> transform is implemented there, but someone should probably check.
> 
>> I chose 'h' as the action key because 'm' and 'f' were reserved, and
>> 'h' is easy to memorize ("horizontal").
> 
> 'r' for reverse, maybe?
> 
> Is it possible to do the mirroring before the rotation instead of as
> part of it? I feel like it would make the code a little clearer,
> although I suspect you're doing it in the rotation to reduce the
> number of calculations? Would it be possible to have both horizontal
> and vertical mirroring?

As said elsewhere, "r" is reserved for rotation. :)

I added an elisp function to do a vertical flip. Also I renamed the
procedure flipping because that's what GIMP calls it. Attached is a
revised patch to replace the previous one.

As for the C code, I agree it adds some complexity to the transform
function, but this is probably the fastest way to achieve it.

Flipping before rotation would lead to strange results when the image
has been rotated 90/270 degrees. Then the flip commands seem reversed
– horizontal flip actually flips vertically and vice versa. This is
because the transform function always rotates the initial image,
which is what would be flipped.

Hopefully someone can test this patch on Windows.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-support-for-image-flipping-Bug-47095.patch --]
[-- Type: text/x-diff; name=0001-Add-support-for-image-flipping-Bug-47095.patch, Size: 4706 bytes --]

From b58619431d6fa0f6b9f50a94aefc09be6121fa3e Mon Sep 17 00:00:00 2001
From: Timo <timo@taipalus.cc>
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)


  parent reply	other threads:[~2021-12-29  9:10 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-12 10:34 bug#47095: 27.1; Feature request: mirror image display ynyaaa
2021-12-27  8:36 ` bug#47095: [PATCH] Add support for image mirroring (Bug#47095) Timo Taipalus
2021-12-28  1:01   ` bug#47095: 27.1; Feature request: mirror image display Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-12-28  9:54     ` Timo Taipalus
2021-12-28 10:07       ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-12-28 11:22   ` bug#47095: [PATCH] Add support for image mirroring (Bug#47095) Alan Third
2021-12-28 18:09     ` bug#47095: [External] : " Drew Adams
2021-12-29  9:10     ` Timo Taipalus [this message]
2022-01-02 14:54       ` Alan Third
2022-01-04 10:25         ` Alan Third
2022-01-05 16:14           ` Lars Ingebrigtsen
2022-01-07 17:00         ` Timo Taipalus
2022-06-24 12:45           ` bug#47095: 27.1; Feature request: mirror image display Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3b23f6a58f935098122e3bbf21e0f59c@taipalus.cc \
    --to=timo@taipalus.cc \
    --cc=47095@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).