Subject: bug#67533: SVG images confound position pixel measurements

From: JD Smith <[email-masked]>
Date: Sun, 3 Dec 2023 10:48:20 -0500

> On Dec 3, 2023, at 8:02 AM, Eli Zaretskii <[email-masked]> wrote:
>> 
>> 
>> 
>> I don’t think there should be anything special about this particular SVG file; it was automatically generated from the underlying latex fragment.  But it seems to be confusing the display engine somehow (as do many others).
> 
> There _is_ something special about that SVG: it is wider that 1/4th of
> the default frame width.  If you widen the frame to be wider than
> 4*209=836 pixels, the problem disappears.  Such wide images are
> handles specially by the display engine.
> 
> The cumulative patch below should fix all the problems you threw on me
> till now.

Most excellent, thank you for the sleuthing Eli!  Your roll-up patch applies cleanly and fixes all the pixel size related issues in my large complex org-with-latex-preview file.  I can induce the same behavior in my original svg-generating code by bumping the default width up to:

      (w (+ 142 (* 2 (round (expt (1+ r) 1.25)))))

and it solves it there too. (I’ve updated the gist to do this, and included the final function below, for posterity).

Now, because every good novel has a denouement, there’s... one more thing.    When I was running my/check-buffer-pixel-values in my large latex-preview-laden org file with your new patch, everything was going swimmingly.  No reported problems at all at a variety of frame widths.  But, then, at a single magic frame width (81 chars, but I think this is arbitrary), a bunch of `expected 28 got 14’ errors showed up on one particular line.

A new flavor of under-reported pixel size?  No!  In fact, all the characters on the reported line were yielding the correct size above themselves.  Instead, around this line, (vertical-motion) as well as previous/next line is *skipping a screen line*, confusing my test!  I have sometimes seen this while using up/down arrow to navigate such image-rich files, when an image is wrapped to column zero.  E.g. instead of moving directly up, point jumps to the end of the line above.

Given that the size problems are fixed, I think I should try to isolate this motion problem and submit it as a separate bug.  So far it has eluded a simple reproduction.  I’ve included a short movie of the effect in a gist comment[1] to spurs some thoughts.

[1] https://gist.github.com/jdtsmith/ad765047a6afe20f353de573d8c07da9?permalink_comment_id=4780726#gistcomment-4780726

+++

(defun my/test-svg-positions (arg)
  (interactive "P")
  (let ((buf "svg-pixel-demo")
(default-height (frame-char-height)))
    (with-current-buffer (get-buffer-create buf)
      (erase-buffer)
      (insert "\nPellentesque condimentum, magna ut suscipit hendrerit, ipsum augue ornare nulla, non luctus diam neque sit amet urna.\nEtiam vel tortor sodales tellus ultricies commodo. Curabitur vulputate vestibulum lorem.  Nam euismod tellus id erat.\n\nNullam tristique diam non turpis.\n")
      (goto-char (point-min))
      (cl-loop for i from 1
      for p = (point) then (progn (forward-word) (point))
      while (< p (point-max))
      if (zerop (% i 5)) do
      (let* ((word-start (save-excursion (backward-word) (point)))
     (r0 (/ (float i) 11))
     (r (round (* 10 (- r0 (floor r0))))) ; some psuedo-randoms
     (r2 (round (* 10 (- (* r0 10) (floor (* r0 10))))))
     (h (+ default-height (* 3 r2)))
     (w (+ 142 (* 2 (round (expt (1+ r) 1.25)))))
     (m (/ w 2))
     (svg (svg-create w h)))
(svg-circle svg m m m
    :fill-color (face-foreground 'default)
    :stroke-width 3
    :stroke-color (if (zerop (% i 2)) "green" "red"))
(if arg
    (let ((ov (make-overlay word-start p)))
      (overlay-put ov 'evaporate t)
      (overlay-put ov 'display
   (svg-image svg :ascent 'center)))
  (put-text-property word-start p 'display
     (svg-image svg :ascent 'center)))))
      (pop-to-buffer buf)
      (visual-line-mode 1)
      (my/check-buffer-pixel-values))))