unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Retain image properties after image-mode commands
@ 2024-03-04  6:07 Joseph Turner
  2024-03-05 16:34 ` Juri Linkov
  0 siblings, 1 reply; 5+ messages in thread
From: Joseph Turner @ 2024-03-04  6:07 UTC (permalink / raw)
  To: Emacs Devel Mailing List

Hello!

I would like to use `image-mode' commands such as
`image-transform-set-scale' on non-file-backed images which have image
properties.  That command internally calls `image-toggle-display-image',
which recontructs the image with `create-image', throwing away any
existing image properties.

A concrete example:

Evalute the following form to render an SVG image in an Emacs buffer:

(with-current-buffer (get-buffer-create "*image-properties-test*")
  (let ((svg-string "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Generated by graphviz version 2.43.0 (0)\n -->\n<!-- Title: orggraphview Pages: 1 -->\n<svg width=\"128pt\" height=\"128pt\"\n viewBox=\"0.00 0.00 127.59 127.59\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 123.59)\">\n<title>orggraphview</title>\n<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-123.59 123.59,-123.59 123.59,4 -4,4\"/>\n<!-- a -->\n<g id=\"node1\" class=\"node\">\n<title>a</title>\n<g id=\"a_node1\"><a xlink:href=\"1\" xlink:title=\"Hover me!\">\n<ellipse fill=\"none\" stroke=\"black\" cx=\"59.79\" cy=\"-59.79\" rx=\"59.59\" ry=\"59.59\"/>\n<text text-anchor=\"middle\" x=\"59.79\" y=\"-56.09\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Hover me!</text>\n</a>\n</g>\n</g>\n</g>\n</svg>\n")
        (map '(((circle (85 . 85) . 80) "1" (help-echo "Surprise!"))))
        (inhibit-read-only t))
    (fundamental-mode)
    (erase-buffer)
    (insert-image (create-image svg-string 'svg t :map map) svg-string)
    (image-mode)
    (pop-to-buffer (current-buffer))))

Mouse over the circle in the center of the SVG to see the tooltip.

Then zoom in on the image: Interactively run `image-transform-set-scale'
by pressing "s s" then type the number 2 and press RET.

The image gets bigger, but now mousing over the circle has no effect.

How can I keep the mouse-over effect (the image :map property) after
running `image-mode' commands which reconstruct the image?

Thank you!!

Joseph



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Retain image properties after image-mode commands
  2024-03-04  6:07 Retain image properties after image-mode commands Joseph Turner
@ 2024-03-05 16:34 ` Juri Linkov
  2024-03-05 17:10   ` Stephen Berman
  0 siblings, 1 reply; 5+ messages in thread
From: Juri Linkov @ 2024-03-05 16:34 UTC (permalink / raw)
  To: Joseph Turner; +Cc: Emacs Devel Mailing List

> Then zoom in on the image: Interactively run `image-transform-set-scale'
> by pressing "s s" then type the number 2 and press RET.

Instead of "s s" you can use "i +" that works correctly.
Thus "s s 2 RET" is equivalent to "2 0 i +".

> How can I keep the mouse-over effect (the image :map property) after
> running `image-mode' commands which reconstruct the image?

Unfortunately, image-mode is not applicable to images inserted to a buffer.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Retain image properties after image-mode commands
  2024-03-05 16:34 ` Juri Linkov
@ 2024-03-05 17:10   ` Stephen Berman
  2024-03-06  7:51     ` Joseph Turner
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Berman @ 2024-03-05 17:10 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Joseph Turner, Emacs Devel Mailing List

On Tue, 05 Mar 2024 18:34:07 +0200 Juri Linkov <juri@linkov.net> wrote:

>> Then zoom in on the image: Interactively run `image-transform-set-scale'
>> by pressing "s s" then type the number 2 and press RET.
>
> Instead of "s s" you can use "i +" that works correctly.
> Thus "s s 2 RET" is equivalent to "2 0 i +".

When I do this, the region in which the tooltip is activated does not
increase: with the enlarged image the tooltip only appears when the
mouse hovers over part of the upper left section of the large circle,
and the adjacent region outside of the circumference of the circle
(i.e., exactly the region occupied by the original circle AFAICT).

Steve Berman



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Retain image properties after image-mode commands
  2024-03-05 17:10   ` Stephen Berman
@ 2024-03-06  7:51     ` Joseph Turner
  2024-03-08  7:33       ` Joseph Turner
  0 siblings, 1 reply; 5+ messages in thread
From: Joseph Turner @ 2024-03-06  7:51 UTC (permalink / raw)
  To: Stephen Berman; +Cc: Juri Linkov, Emacs Devel Mailing List

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

Stephen Berman <stephen.berman@gmx.net> writes:

> On Tue, 05 Mar 2024 18:34:07 +0200 Juri Linkov <juri@linkov.net> wrote:
>
>>> Then zoom in on the image: Interactively run `image-transform-set-scale'
>>> by pressing "s s" then type the number 2 and press RET.
>>
>> Instead of "s s" you can use "i +" that works correctly.
>> Thus "s s 2 RET" is equivalent to "2 0 i +".

Good point!

> When I do this, the region in which the tooltip is activated does not
> increase: with the enlarged image the tooltip only appears when the
> mouse hovers over part of the upper left section of the large circle,
> and the adjacent region outside of the circumference of the circle
> (i.e., exactly the region occupied by the original circle AFAICT).

My experience matches Steve's; neither `image-increase-size' nor
`image-transform-set-scale' scales the image map with the image.

The attached patch attempts to scale the :map image property whenever
the :scale property changes.  After applying it, run this snippet:

(with-current-buffer (get-buffer-create "*image-properties-test*")
  (let ((svg-string "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Generated by graphviz version 2.43.0 (0)\n -->\n<!-- Title: orggraphview Pages: 1 -->\n<svg width=\"128pt\" height=\"128pt\"\n viewBox=\"0.00 0.00 127.59 127.59\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 123.59)\">\n<title>orggraphview</title>\n<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-123.59 123.59,-123.59 123.59,4 -4,4\"/>\n<!-- a -->\n<g id=\"node1\" class=\"node\">\n<title>a</title>\n<g id=\"a_node1\"><a xlink:href=\"1\" xlink:title=\"Hover me!\">\n<ellipse fill=\"none\" stroke=\"black\" cx=\"59.79\" cy=\"-59.79\" rx=\"59.59\" ry=\"59.59\"/>\n<text text-anchor=\"middle\" x=\"59.79\" y=\"-56.09\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Hover me!</text>\n</a>\n</g>\n</g>\n</g>\n</svg>\n")
        (map '(((circle (85 . 85) . 80) "1" (help-echo "Surprise!"))))
        (inhibit-read-only t))
    (erase-buffer)
    (insert-image (create-image svg-string 'svg t :map map) svg-string)
    (goto-char (point-min))
    (pop-to-buffer (current-buffer))))

Press "i +".  Now the tooltip and image should line up correctly.

The patch doesn't quite work correctly. Since image map coordinates must
be integers, they are scaled then rounded in the patch. However, if you
repeatedly increase and decrease the image size ("i +", then "+" & "-"),
eventually the image map drifts from the rendered image.

An untested potential solution is to add another image property
:unscaled-map, containing an image map which corresponds to the image
with :scale 1.  Then each time the image is scaled, we calculate the new
:map based on the :unscaled-map, avoiding the drift.

The :unscaled-map solution may even be able to handle image rotation...

Thoughts?

Thanks!

Joseph


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Scale-image-map-property-according-to-image-scale.patch --]
[-- Type: text/x-diff, Size: 1863 bytes --]

From a3bf934ad872999d0e63f0757429621b4e4b082c Mon Sep 17 00:00:00 2001
From: Joseph Turner <joseph@breatheoutbreathe.in>
Date: Wed, 6 Mar 2024 00:16:24 -0800
Subject: [PATCH] Scale image :map property according to image :scale

* lisp/image.el (image--scale-map): Add function to scale an image map.
(image--change-size): Use image--scale-map internally.
---
 lisp/image.el | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/lisp/image.el b/lisp/image.el
index 2ebce59a98c..48c38a0c9ec 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -1269,7 +1269,28 @@ image--change-size
          (new-image (image--image-without-parameters image))
          (scale (image--current-scaling image new-image)))
     (setcdr image (cdr new-image))
-    (plist-put (cdr image) :scale (* scale factor))))
+    (plist-put (cdr image) :scale (* scale factor))
+    (setf (image-property new-image :map)
+          (image--scale-map (image-property new-image :map) factor))))
+
+(defun image--scale-map (map factor)
+  "Scale MAP by FACTOR, destructively modifying it."
+  (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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: Retain image properties after image-mode commands
  2024-03-06  7:51     ` Joseph Turner
@ 2024-03-08  7:33       ` Joseph Turner
  0 siblings, 0 replies; 5+ messages in thread
From: Joseph Turner @ 2024-03-08  7:33 UTC (permalink / raw)
  To: Stephen Berman, Juri Linkov, Emacs Devel Mailing List

This discussion continues as #69602:

https://yhetil.org/emacs-bugs/87msramv72.fsf@breatheoutbreathe.in/T/#mcd3d5f7b1564ba95d985ec42ab2c610b8a08558c



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-03-08  7:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-04  6:07 Retain image properties after image-mode commands Joseph Turner
2024-03-05 16:34 ` Juri Linkov
2024-03-05 17:10   ` Stephen Berman
2024-03-06  7:51     ` Joseph Turner
2024-03-08  7:33       ` Joseph Turner

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).