From: Joseph Turner via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 69602@debbugs.gnu.org, stephen.berman@gmx.net, juri@linkov.net
Subject: bug#69602: 29.1; Image :map should adjust with :scale and :rotation
Date: Fri, 08 Mar 2024 00:39:16 -0800 [thread overview]
Message-ID: <87bk7phzdz.fsf@breatheoutbreathe.in> (raw)
In-Reply-To: <867cid15wv.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 1078 bytes --]
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Joseph Turner <joseph@breatheoutbreathe.in>
>> Date: Thu, 07 Mar 2024 23:02:24 -0800
>>
>> Joseph Turner <joseph@breatheoutbreathe.in> writes:
>>
>> > The attached patch adds two hooks in `image.el' which allow packages to
>> > recompute an image's map after it's rescaled or rotated.
>>
>> In this new attached patch, rescaling image maps is handled within
>> image.el. No new hooks are added. This change should be backwards
>> compatible, except that :unscaled-map is now a reserved image property.
>
> Are we sure no Lisp program out there would want the coordinates in
> :map to remain unchanged under these transformation? Maybe we should
> add a variable to control this, so that the change could be truly
> backward-compatible?
Good point. Thanks!
What if explicitly passing :unscaled-map 'no-recalculate in
`create-image' prevented :map from being recalculated later?
If not, what kind of variable did you have in mind? A special variable
let-bound the call? Or another argument to `create-image'?
See patches.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-Allow-map-to-not-be-recalculated-after-image-rescali.patch --]
[-- Type: text/x-diff, Size: 1472 bytes --]
From feafa5a4e967254fc58c2ad223cd7033d4c4be02 Mon Sep 17 00:00:00 2001
From: Joseph Turner <joseph@breatheoutbreathe.in>
Date: Fri, 8 Mar 2024 00:53:44 -0800
Subject: [PATCH 2/2] Allow :map to not be recalculated after image rescaling
* lisp/image.el (create-image): Don't append :unscaled-map if passed in.
(image--image-without-parameters): Don't rescale :map when :unscaled-map
is 'no-recalculate.
---
lisp/image.el | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lisp/image.el b/lisp/image.el
index c72332172f0..b7de9817009 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -534,7 +534,8 @@ create-image
('nil nil)
(func (funcall func image)))))))
;; Add unscaled map.
- (when-let ((map (plist-get props :map)))
+ (when-let ((map (plist-get props :map))
+ ((not (plist-member props :unscaled-map))))
(setq image (nconc image
(list :unscaled-map
(image--scale-map
@@ -1279,7 +1280,8 @@ image--change-size
(new-scale (* scale factor)))
(setcdr image (cdr new-image))
(plist-put (cdr image) :scale new-scale)
- (when unscaled-map
+ (when (and unscaled-map
+ (not (eq 'no-recalculate unscaled-map)))
(setf (image-property image :map)
(image--scale-map (copy-tree unscaled-map t) new-scale)))))
--
2.41.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-Recalculate-map-when-image-scale-changes.patch --]
[-- Type: text/x-diff, Size: 3941 bytes --]
From 7a3d9fa5cc08c40696ad65101d62cb4babb4dc76 Mon Sep 17 00:00:00 2001
From: Joseph Turner <joseph@breatheoutbreathe.in>
Date: Thu, 7 Mar 2024 21:55:00 -0800
Subject: [PATCH 1/2] Recalculate :map when image :scale changes
Now, when rescaling an image with a :map using `image-increase-size' or
`image-decrease-size', the image map scales along with the image.
Image map coordinates are integers, so when scaling :map, coordinates
must be rounded. To prevent an image from drifting from its map after
repeatedly scaling up and down, `create-image' now stores the original
:unscaled-map, which is combined with the image's scale after resizing
to recalculate :map.
* lisp/image.el (create-image): Add :unscaled-map image property
(image--delayed-change-size): Fix comment
(image--change-size): Also scale image map
(image--scale-map): Add function to scale an image map
---
lisp/image.el | 38 +++++++++++++++++++++++++++++++++++---
1 file changed, 35 insertions(+), 3 deletions(-)
diff --git a/lisp/image.el b/lisp/image.el
index 2ebce59a98c..c72332172f0 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -533,6 +533,13 @@ create-image
('t t)
('nil nil)
(func (funcall func image)))))))
+ ;; Add unscaled map.
+ (when-let ((map (plist-get props :map)))
+ (setq image (nconc image
+ (list :unscaled-map
+ (image--scale-map
+ (copy-tree map t)
+ (/ 1.0 (image-property image :scale)))))))
image)))
(defun image--default-smoothing (image)
@@ -1185,7 +1192,7 @@ image-increase-size
(defun image--delayed-change-size (size position)
;; Wait for a bit of idle-time before actually performing the change,
;; so as to batch together sequences of closely consecutive size changes.
- ;; `image--change-size' just changes one value in a plist. The actual
+ ;; `image--change-size' just changes :scale and :map. The actual
;; image resizing happens later during redisplay. So if those
;; consecutive calls happen without any redisplay between them,
;; the costly operation of image resizing should happen only once.
@@ -1267,9 +1274,34 @@ image--get-imagemagick-and-warn
(defun image--change-size (factor &optional position)
(let* ((image (image--get-imagemagick-and-warn position))
(new-image (image--image-without-parameters image))
- (scale (image--current-scaling image new-image)))
+ (unscaled-map (image-property image :unscaled-map))
+ (scale (image--current-scaling image new-image))
+ (new-scale (* scale factor)))
(setcdr image (cdr new-image))
- (plist-put (cdr image) :scale (* scale factor))))
+ (plist-put (cdr image) :scale new-scale)
+ (when unscaled-map
+ (setf (image-property image :map)
+ (image--scale-map (copy-tree unscaled-map t) new-scale)))))
+
+(defun image--scale-map (map factor)
+ "Scale MAP by FACTOR, destructively modifying it."
+ (unless (= 1 factor)
+ (pcase-dolist (`(,`(,type . ,coords) ,_id ,_plist) map)
+ (pcase-exhaustive type
+ ('rect
+ (setf (caar coords) (round (* (caar coords) factor)))
+ (setf (cdar coords) (round (* (cdar coords) factor)))
+ (setf (cadr coords) (round (* (cadr coords) factor)))
+ (setf (cddr coords) (round (* (cddr coords) factor))))
+ ('circle
+ (setf (caar coords) (round (* (caar coords) factor)))
+ (setf (cdar coords) (round (* (cdar coords) factor)))
+ (setf (cdr coords) (round (* (cdr coords) factor))))
+ ('poly
+ (dotimes (i (length coords))
+ (aset coords i
+ (round (* (aref coords i) factor))))))))
+ map)
(defun image--image-without-parameters (image)
(cons (pop image)
--
2.41.0
next prev parent reply other threads:[~2024-03-08 8:39 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-07 5:37 bug#69602: 29.1; Image :map should adjust with :scale and :rotation Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-07 7:04 ` Eli Zaretskii
2024-03-07 7:14 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-07 7:55 ` Eli Zaretskii
2024-03-07 8:08 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-07 9:27 ` Eli Zaretskii
2024-03-07 13:53 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-08 7:02 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-08 8:31 ` Eli Zaretskii
2024-03-08 8:39 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-03-08 11:50 ` Eli Zaretskii
2024-03-21 6:45 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-21 11:59 ` Eli Zaretskii
2024-03-23 0:11 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-23 7:58 ` Eli Zaretskii
2024-03-23 17:41 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-23 17:58 ` Eli Zaretskii
2024-03-23 18:18 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-23 20:32 ` Joseph Turner via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-28 10:13 ` Eli Zaretskii
2024-03-08 7:24 ` Eli Zaretskii
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=87bk7phzdz.fsf@breatheoutbreathe.in \
--to=bug-gnu-emacs@gnu.org \
--cc=69602@debbugs.gnu.org \
--cc=eliz@gnu.org \
--cc=joseph@breatheoutbreathe.in \
--cc=juri@linkov.net \
--cc=stephen.berman@gmx.net \
/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).