From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Joseph Turner via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#69602: 29.1; Image :map should adjust with :scale and :rotation Date: Fri, 08 Mar 2024 00:39:16 -0800 Message-ID: <87bk7phzdz.fsf@breatheoutbreathe.in> References: <87msramv72.fsf@breatheoutbreathe.in> <86jzmejzfd.fsf@gnu.org> <87a5namqyz.fsf@breatheoutbreathe.in> <86cys63281.fsf@gnu.org> <87wmqelakx.fsf@breatheoutbreathe.in> <86bk7q2xye.fsf@gnu.org> <871q8lk2o7.fsf@breatheoutbreathe.in> <87o7bpi4c1.fsf@breatheoutbreathe.in> <867cid15wv.fsf@gnu.org> Reply-To: Joseph Turner Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="26922"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 69602@debbugs.gnu.org, stephen.berman@gmx.net, juri@linkov.net To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Mar 08 10:01:49 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1riW6v-0006lg-Ft for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 08 Mar 2024 10:01:49 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1riW6f-0004HB-Fu; Fri, 08 Mar 2024 04:01:33 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1riW6d-0004Gb-C5 for bug-gnu-emacs@gnu.org; Fri, 08 Mar 2024 04:01:31 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1riW6d-0001Wk-4B for bug-gnu-emacs@gnu.org; Fri, 08 Mar 2024 04:01:31 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1riW78-0006ti-0l for bug-gnu-emacs@gnu.org; Fri, 08 Mar 2024 04:02:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Joseph Turner Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 08 Mar 2024 09:02:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 69602 X-GNU-PR-Package: emacs Original-Received: via spool by 69602-submit@debbugs.gnu.org id=B69602.170988849226469 (code B ref 69602); Fri, 08 Mar 2024 09:02:01 +0000 Original-Received: (at 69602) by debbugs.gnu.org; 8 Mar 2024 09:01:32 +0000 Original-Received: from localhost ([127.0.0.1]:56571 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1riW6e-0006sq-79 for submit@debbugs.gnu.org; Fri, 08 Mar 2024 04:01:32 -0500 Original-Received: from out-174.mta0.migadu.com ([91.218.175.174]:26490) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1riW6a-0006sI-RJ for 69602@debbugs.gnu.org; Fri, 08 Mar 2024 04:01:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=breatheoutbreathe.in; s=key1; t=1709888420; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=4Z2RXJx0CSOO/92SmVSK19oFKXmRpsZD/Nf35MwXVJQ=; b=FmGy0bPrUcVkG4gIbpfUfa6Tt/QVNP3fSWNUAsIEh4In8z8w9xKkvgoYUWAXPn5xpiY0+Y suunFcLM2ChcBFUXy6iLQeZn23RviCQE3OobloEI2VOdoX0KRaVvD34+8IyFCi7mIUHp5v yDzY8DB0FmmWCaCzC65KEtb0ljuoqr8= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. In-reply-to: <867cid15wv.fsf@gnu.org> X-Migadu-Flow: FLOW_OUT X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:281218 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> From: Joseph Turner >> Date: Thu, 07 Mar 2024 23:02:24 -0800 >> >> Joseph Turner 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. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-Allow-map-to-not-be-recalculated-after-image-rescali.patch >From feafa5a4e967254fc58c2ad223cd7033d4c4be02 Mon Sep 17 00:00:00 2001 From: Joseph Turner 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 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-Recalculate-map-when-image-scale-changes.patch >From 7a3d9fa5cc08c40696ad65101d62cb4babb4dc76 Mon Sep 17 00:00:00 2001 From: Joseph Turner 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 --=-=-=--