line-pixel-height beyond eol

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

line-pixel-height beyond eol

Tak Kunihiro
I want to scroll pixel-wise with auto-hscroll-mode off.

When auto-hscroll-mode is nil, `hollow’ cursor can go over the end
of line with an inline image.  As soon as the image is scrolled out to
the left, on display, height of line shrinks to frame-char-height.

Since point is on the line, the function `line-pixel-height’ returns
height of image instead of that of text.

  GNU Emacs 26.0.50 (build 3, x86_64-apple-darwin13.4.0, NS appkit-1265.21 Version 10.9.5 (Build 13F1911))
  src/emacs -Q
  M-x eww
  www.gnu.org
  C-n 16 times (to reach to GNU image)
  M-: (line-pixel-height) => 144
  M-: (setq auto-hscroll-mode nil)
  M-: (set-window-hscroll nil 256)
  M-: (line-pixel-height) => 144

  -- Function: line-pixel-height
     This function returns the height in pixels of the line at point in
     the selected window.  The value includes the line spacing of the
     line (*note Line Height::).

Is there a way to obtain the height in pixels of the line at the `hollow’
point in the selected window?  Or is there a way to maintain the height of
a line even when an image is horizontally scrolled out?




Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> From: Tak Kunihiro <[hidden email]>
> Date: Tue, 12 Sep 2017 19:12:23 +0900
> Cc: Kunihiro Tak <[hidden email]>
>
> I want to scroll pixel-wise with auto-hscroll-mode off.
>
> When auto-hscroll-mode is nil, `hollow’ cursor can go over the end
> of line with an inline image.  As soon as the image is scrolled out to
> the left, on display, height of line shrinks to frame-char-height.

The display engine only renders what's on the screen.

> Since point is on the line, the function `line-pixel-height’ returns
> height of image instead of that of text.

Correct.  line-pixel-height is not documented to depend on what is
displayed on the screen, it reports the dimensions of the line as a
whole.

> Is there a way to obtain the height in pixels of the line at the `hollow’
> point in the selected window?  Or is there a way to maintain the height of
> a line even when an image is horizontally scrolled out?

I don't think I understand what value you want to obtain.  Can you
elaborate, and perhaps also explain what do you want to do with that
value and why?

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Tak Kunihiro
Thank you for the response.

>> Is there a way to obtain the height in pixels of the line at the `hollow’
>> point in the selected window?  Or is there a way to maintain the height of
>> a line even when an image is horizontally scrolled out?
>
> I don't think I understand what value you want to obtain.  Can you
> elaborate, and perhaps also explain what do you want to do with that
> value and why?

With Eww, I often meet pages with wide images.  I want to scroll
pixel-wisely the buffers with auto-hscroll-mode off even when
(current-column) is a large number.

The building block of pixel-wise scrolling is described as below.

  (progn (vertical-motion 1)
         (dolist (vs (number-sequence 1 (1- (frame-char-height))))
           (set-window-vscroll nil vs t) (sit-for 0.01))
         (scroll-up 1))

To determine when to flush in a buffer of lines with different height,
I have to know
  - height of line in pixel of the top line on screen.
I think that, on XXX condition, I rather should obtain it as
frame-char-height instead of line-pixel-height.  I cannot find how to
describe the XXX condition.

Also, to avoid unexpected jump, I want to calculate margin to move the
`hollow’ cursor by vertical-motion.  Here the `hollow’ cursor is
defined as a cursor shown up when (current-column) is large, that can
go over the end of line.  I want to know following two valuse, that
are
  - height of line in pixel where the `hollow’ cursor is
  - y position of the `hollow’ cursor instead of (cdr (posn-x-y (posn-at-point))).
I have no idea how to get those.

Please give me suggestions!
Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> Date: Wed, 13 Sep 2017 09:24:30 +0900 (JST)
> Cc: [hidden email], [hidden email]
> From: Tak Kunihiro <[hidden email]>
>
> > I don't think I understand what value you want to obtain.  Can you
> > elaborate, and perhaps also explain what do you want to do with that
> > value and why?
>
> With Eww, I often meet pages with wide images.  I want to scroll
> pixel-wisely the buffers with auto-hscroll-mode off even when
> (current-column) is a large number.
>
> The building block of pixel-wise scrolling is described as below.
>
>   (progn (vertical-motion 1)
>          (dolist (vs (number-sequence 1 (1- (frame-char-height))))
>            (set-window-vscroll nil vs t) (sit-for 0.01))
>          (scroll-up 1))
>
> To determine when to flush in a buffer of lines with different height,
> I have to know

Just a moment: why would you need to change the above code when lines
have variable height?  The above code scrolls the buffer one pixel at
a time until you scroll the height of frame's canonical character;
with tall lines, doing that will scroll less than the full line.  But
why is that a problem?  The user will just have to spin the wheel some
more.

>   - height of line in pixel of the top line on screen.

Why the top line on screen?  What is special about that line?

> I think that, on XXX condition, I rather should obtain it as
> frame-char-height instead of line-pixel-height.  I cannot find how to
> describe the XXX condition.

I think you may be trying a specific solution too early.  I'm not yet
sure I understand why the original code doesn't work for your needs.

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Tak Kunihiro
Thank you for the response.

>> The building block of pixel-wise scrolling is described as below.
>>
>>   (progn (vertical-motion 1)
>>          (dolist (vs (number-sequence 1 (1- (frame-char-height))))
>>            (set-window-vscroll nil vs t) (sit-for 0.01))
>>          (scroll-up 1))
>>

> I think you may be trying a specific solution too early.  I'm not yet
> sure I understand why the original code doesn't work for your needs.

Let me rephrase.  More specifically, the building block of pixel-wise
scrolling is described as below.

  (progn (vertical-motion 1)
         (dolist (vs (number-sequence 1 (1- (save-excursion
                                              (goto-char (window-start))
                                              (line-pixel-height)))))
           (set-window-vscroll nil vs t) (sit-for 0.01))
         (scroll-up 1))

Let's assume a line with image of height 144 pixel is located on the
top line.  When auto-hscroll-mode is off and (current-column) is large
(the 144 pixel image is scrolled left), the top line looks 27 pixel
height but (line-pixel-height) returns 144 pixel.  The inconsistency
results in jump.

I hope this describes my concern!

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> Date: Thu, 14 Sep 2017 08:14:26 +0900 (JST)
> Cc: [hidden email], [hidden email]
> From: Tak Kunihiro <[hidden email]>
>
>   (progn (vertical-motion 1)
>          (dolist (vs (number-sequence 1 (1- (save-excursion
>                                               (goto-char (window-start))
>                                               (line-pixel-height)))))
>            (set-window-vscroll nil vs t) (sit-for 0.01))
>          (scroll-up 1))
>
> Let's assume a line with image of height 144 pixel is located on the
> top line.  When auto-hscroll-mode is off and (current-column) is large
> (the 144 pixel image is scrolled left), the top line looks 27 pixel
> height but (line-pixel-height) returns 144 pixel.  The inconsistency
> results in jump.

Would it help not to use the height of the top window line, but
instead simply use the value returned by frame-char-height?  That
takes its value from the frame's default font, and so should be
independent on what's in the window.

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Tak Kunihiro
>>   (progn (vertical-motion 1)
>>          (dolist (vs (number-sequence 1 (1- (save-excursion
>>                                               (goto-char (window-start))
>>                                               (line-pixel-height)))))
>>            (set-window-vscroll nil vs t) (sit-for 0.01))
>>          (scroll-up 1))
>>
>> Let's assume a line with image of height 144 pixel is located on the
>> top line.  When auto-hscroll-mode is off and (current-column) is large
>> (the 144 pixel image is scrolled left), the top line looks 27 pixel
>> height but (line-pixel-height) returns 144 pixel.  The inconsistency
>> results in jump.
>
> Would it help not to use the height of the top window line, but
> instead simply use the value returned by frame-char-height?  That
> takes its value from the frame's default font, and so should be
> independent on what's in the window.

That is a good idea!  I want to scroll that way.

To scroll pixels by frame-char-height, a line should be flushed by
(scroll-up 1) when (window-vscroll nil t) is very close to height of
pixel on the top window line.

If this flush does not happened on the right timing, screen jumps
unexpectedly as demonstrated below.

M-x about-emacs
M-: (progn
        (dolist (vs (number-sequence 1 (1- (frame-char-height))))
          (set-window-vscroll nil vs t) (sit-for 0.01))
        (scroll-up 1))

Thus I have to know height of pixel on the top window line.

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> Date: Fri, 15 Sep 2017 10:39:53 +0900 (JST)
> Cc: [hidden email], [hidden email]
> From: Tak Kunihiro <[hidden email]>
>
> Thus I have to know height of pixel on the top window line.

Can you use vertical-motion for that?

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Tak Kunihiro
Thank you for the response.

>> Thus I have to know height of pixel on the top window line.
>
> Can you use vertical-motion for that?

After try and error, I learned how to get height of pixel on
visual-line using `vertical-motion' and `posn-x-y' as shown below.

However, when (window-hscroll) is large, I cannot get y location of
cursor using `posn-x-y'.  Can you give me suggestion how to get y
location of cursor even when when (window-hscroll) is large?


(defun pixel-visual-line-height ()
  "Return height in pixels of text line in the selected window.

Value is the height of pixels in the line visually shown by
current screen.  Note that `line-pixel-height' returns the
maximum height of a line."
  (let ((pos-save (window-start)) ; save window configuration
        (vs-save (window-vscroll nil t))
        (height (frame-char-height)) ; (line-pixel-height)
        pos-a pos-b y-a y-b
        height-meas)
    (save-excursion ; measure actual height
      (beginning-of-visual-line)
      (set-window-vscroll nil 0 t)
      (set-window-start nil (point) t)
      (and (setq pos-a (posn-at-point))
           (vertical-motion 1)
           (setq pos-b (posn-at-point))
           (integerp (setq y-a (cdr (posn-x-y pos-a))))
           (integerp (setq y-b (cdr (posn-x-y pos-b))))
           (integerp (setq height-meas (- y-b y-a)))
           (setq height height-meas))
      (set-window-start nil pos-save t) ; restore window configuration
      (set-window-vscroll nil vs-save t))
    height))

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> Date: Sat, 23 Sep 2017 21:57:00 +0900 (JST)
> Cc: [hidden email], [hidden email]
> From: Tak Kunihiro <[hidden email]>
>
> > Can you use vertical-motion for that?
>
> After try and error, I learned how to get height of pixel on
> visual-line using `vertical-motion' and `posn-x-y' as shown below.
>
> However, when (window-hscroll) is large, I cannot get y location of
> cursor using `posn-x-y'.  Can you give me suggestion how to get y
> location of cursor even when when (window-hscroll) is large?

I need to see an example of a situation where you cannot get the Y
coordinate of the cursor due to a large window-hscroll.  Is it at all
an interesting situation, or just a theoretical one?  Also, if you
just use frame-char-height in that case, does that solve the problem?


Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Tak Kunihiro
>> > Can you use vertical-motion for that?
>>
>> After try and error, I learned how to get height of pixel on
>> visual-line using `vertical-motion' and `posn-x-y' as shown below.
>>
>> However, when (window-hscroll) is large, I cannot get y location of
>> cursor using `posn-x-y'.  Can you give me suggestion how to get y
>> location of cursor even when when (window-hscroll) is large?
>
> I need to see an example of a situation where you cannot get the Y
> coordinate of the cursor due to a large window-hscroll.  Is it at all
> an interesting situation, or just a theoretical one?  Also, if you
> just use frame-char-height in that case, does that solve the problem?

That happens when I scroll a buffer with an image.  When point in an
image and left edger of the image is out of screen by window-hscroll,
I cannot get (posn-at-point).

Here is an example of a situation.

  M-x about-emacs
  M-<, C-e, C-b
  (posn-at-point) => (#<window 55 on *About GNU Emacs*> 2 (152 . 0) 0 nil 2 (1 . 0) (image :type png :file "splash.png") (0 . 0) (333 . 233))
  (set-window-hscroll nil 28)
  (posn-at-point) => nil

This case, I want to estimate height of a line as height of the image
thus frame-char-height does not work.

Please give me suggestion to get y location of a cursor on the
situation!

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> Date: Thu, 05 Oct 2017 18:50:38 +0900 (JST)
> Cc: [hidden email], [hidden email]
> From: Tak Kunihiro <[hidden email]>
>
>   M-x about-emacs
>   M-<, C-e, C-b
>   (posn-at-point) => (#<window 55 on *About GNU Emacs*> 2 (152 . 0) 0 nil 2 (1 . 0) (image :type png :file "splash.png") (0 . 0) (333 . 233))
>   (set-window-hscroll nil 28)
>   (posn-at-point) => nil
>
> This case, I want to estimate height of a line as height of the image
> thus frame-char-height does not work.
>
> Please give me suggestion to get y location of a cursor on the
> situation!

You can go to end of line and call posn-at-point there, no?  Here's a
snippet that works in your case:

  M-: (global-set-key [f5] (lambda () (interactive) (save-excursion (end-of-line) (message "%s" (posn-at-point))))) RET

Then press F5, and you will see what you need, no?

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Tak Kunihiro
Thank you for the response.

>>   M-x about-emacs
>>   M-<, C-e, C-b
>>   (posn-at-point) => (#<window 55 on *About GNU Emacs*> 2 (152 . 0) 0 nil 2 (1 . 0) (image :type png :file "splash.png") (0 . 0) (333 . 233))
>>   (set-window-hscroll nil 28)
>>   (posn-at-point) => nil
>>
>> This case, I want to estimate height of a line as height of the image
>> thus frame-char-height does not work.
>>
> You can go to end of line and call posn-at-point there, no?  Here's a
> snippet that works in your case:
>
>   M-: (global-set-key [f5] (lambda () (interactive) (save-excursion (end-of-line) (message "%s" (posn-at-point))))) RET
>
> Then press F5, and you will see what you need, no?

Yes, however, it is not guaranteed if end-of-line is always shown on a
screen.  I have to know a char that is shown on the screen in advance.
I think I can find it by (pos-visible-in-window-p xxx nil t).

When a char is shown in the screen, I can get height by
(line-pixel-height).  When no char is shown, I can assume height as
(frame-char-height).

Now I see height of the top line remains tall even an image is off.

 emacs 26.0.90
 emacs -Q
 M-x eww www.gnu.org
 C-n x 16 (to move to GNU picture)
 M-: (set-window-hscroll nil 100)
 M-: (line-pixel-height) ; => 144 (but visually nominal)
 C-l C-l (locate line of GNU picture to the top of the screen)
 M-: (line-pixel-height) ; => 144 (visually tall)

Is this expected behavior?

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> Date: Mon, 16 Oct 2017 14:13:03 +0900 (JST)
> Cc: [hidden email], [hidden email]
> From: Tak Kunihiro <[hidden email]>
>
> Now I see height of the top line remains tall even an image is off.
>
>  emacs 26.0.90
>  emacs -Q
>  M-x eww www.gnu.org
>  C-n x 16 (to move to GNU picture)

(a.k.a. "C-u C-u C-n")

>  M-: (set-window-hscroll nil 100)
>  M-: (line-pixel-height) ; => 144 (but visually nominal)
>  C-l C-l (locate line of GNU picture to the top of the screen)
>  M-: (line-pixel-height) ; => 144 (visually tall)
>
> Is this expected behavior?

The behavior was changed in response to your report in bug#28391.

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Tak Kunihiro
Thank you for the response.  Let me rephrase.

(a)  emacs 26.0.90
(b)  emacs -Q
(c)  M-x eww www.gnu.org
(d)  C-u C-u C-n (to move to GNU picture)
(e)  M-: (set-window-hscroll nil 100)
(f)  C-l C-l (locate GNU-picture line to the top of the screen)

Let me define `physical height' as length of height of a line, that is measured by physical scale.
After operation (e), physical height of GNU-picture line is (frame-char-height) such as 20 pixel.
After operation (f), physical height of GNU-picture line is tall such like 144 pixel.

The same GNU-picture line is shown with different physical height
depending on where the line is located.  Is this expected behavior?

Reply | Threaded
Open this post in threaded view
|

Re: line-pixel-height beyond eol

Eli Zaretskii
> Date: Tue, 17 Oct 2017 09:29:55 +0900 (JST)
> Cc: [hidden email], [hidden email]
> From: Tak Kunihiro <[hidden email]>
>
> (a)  emacs 26.0.90
> (b)  emacs -Q
> (c)  M-x eww www.gnu.org
> (d)  C-u C-u C-n (to move to GNU picture)
> (e)  M-: (set-window-hscroll nil 100)
> (f)  C-l C-l (locate GNU-picture line to the top of the screen)
>
> Let me define `physical height' as length of height of a line, that is measured by physical scale.
> After operation (e), physical height of GNU-picture line is (frame-char-height) such as 20 pixel.
> After operation (f), physical height of GNU-picture line is tall such like 144 pixel.
>
> The same GNU-picture line is shown with different physical height
> depending on where the line is located.  Is this expected behavior?

Yes, this is the intended behavior of the display engine.