From: Jimmy Yuen Ho Wong <wyuenho@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: Need `truncate-string-to-pixel-width` and `glyph-pixel-width` functions in C
Date: Fri, 25 Oct 2024 14:35:16 +0100 [thread overview]
Message-ID: <CAKDRQS5Kktf7OQBn_+e00RiGNeMMfKtXajEUSNGZmZss6KKPng@mail.gmail.com> (raw)
In-Reply-To: <865xpgd4vi.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 4899 bytes --]
>
> We are mis-communicating. My suggestion is _not_ to compute the
> :align-to from the width of the prefix+candidate+suffix. My
> suggestion is to calculate the width of <Type>+scroll-bar, then use
> :align-to relative to the right edge of the window, like this:
>
> :align-to (- right (N))
>
> where N is the pixel-width of <Type>+scroll-bar
>
> > The reason for this is that `string-pixel-width` will be
> > called on all of these concatenated strings, and the maximum of which
> will be given as the width to a function
> > to render the child frame. This also answers your next question, yes the
> pop up width is already calculated
> > dynamically, but against a max width, this is what I mean by "confined",
> hence the need for truncation before
> > blitzing the strings to a child frame. :align-to (- right suffix-width)
> will lead `string-pixel-width` to return a
> > ridiculously large number that, funnily enough, is calculated from the
> current window's text area width, instead
> > of the child frame's window, of which the size is unknown at this time.
>
> I don't understand this. What is "suffix-width" in the above text,
> and in what units is it measured? And why the size of the window is
> unknown?
>
> > As to the reason for a max width, let's just say there exists language
> servers such as Rust Analyzer, that will
> > return the signature of a function as the completion annotation, which
> can be quite long. Nobody wants their
> > completion pop up box taking up half the screen.
>
> Long strings can be truncated with one of the known methods. Those
> methods will not give you pixel accuracy, you don't need that if you
> use :align-to relative to the right edge of the window.
>
>
Here are more gaps to fill in for you. The margin and the scroll bar widths
are both calculated relative to the `default-font-width`, the reason for
that is, assuming most of the text is in the default font, if it is 20px
wide, it's undesirable to have a fixed scroll bar size of 3px. The scroll
bar and the margin need to scale with the default font size to fight for
just enough of the user's attention when viewed. This can be known with
some refactoring by the time `string-pixel-width` is called on all the
formatted completion strings, but the whole issue is the "right" in
:align-to (- right <whatever>) would be referring to the window from which
you calculate `string-pixel-width` from, not the window in the child frame,
because we are trying calculate the child frame width from the content
width at this point. What you are suggesting has a logical circular
dependency here, which is why I explained to you that :align-to can only be
calculated from `(+ prefix-column-width candidate--column-width (-
suffix-column-width suffix-width)`. The suffix width means the annotation's
pixel width, the part you keep calling type, which is not necessarily the
case. I.e:
```
;; you just calculated the width of the space from the left to the right
of the __current-window__ minus some offset
(let ((content-width (cl-loop for (prefix candidate suffix) in
formatted-lines maximize (string-pixel-width (concat prefix candidate
(propertize " " :align-to `(- right ,(whatever))) suffix)))))
....
;; now you just made a child frame as large as your current window's
width minus whatever, presumably much smaller than your current window's
width, thus this frame now covers most of your screen.
(make-frame `((width . ,content-width)))
```
> I don't understand this, either. Why cannot the calculation of the
> frame parameters take the scroll-bar into account, so as to avoid its
> deletion/truncation?
>
For the second time, there's a max child frame width variable that
"confines" how large it can be, the implication is it can be < content
width, therefore necessitates programmatic truncation of the content width,
which __does not__ include the scroll bar.
> IOW, your proposed idea will work for the simple cases, but falls
> apart for a general-purpose API which will rightfully be expected to
> work in any situation and use case supported by Emacs.
>
Ok, makes sense. Thanks for filling in the missing parts for me. Here's
some further questions.
WRT case 1, translating tab sizes is a simple multiplication, it sounds to
me it can still be fast by bypassing windows. Is this correct? Anything
else that can slow this case down?
WRT case 2, boldly extrapolating from my simple benchmarks, resolving the
font from faces takes ~10% of the time in `string-pixel-width`, besides
saving and restoring window states and scanning window positions, what else
does "string-pixel-width" spend on the other 90% of the time?
> The existing
> high-level C APIs, which we use in window-text-pixel-size and its ilk,
> are inappropriate, because they are unable to reliably find a buffer
> or string position that corresponds to a given pixel-width.
>
Agreed.
[-- Attachment #2: Type: text/html, Size: 5951 bytes --]
next prev parent reply other threads:[~2024-10-25 13:35 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-23 5:01 Need `truncate-string-to-pixel-width` and `glyph-pixel-width` functions in C Jimmy Yuen Ho Wong
2024-10-23 8:01 ` Eli Zaretskii
2024-10-23 13:52 ` Jimmy Yuen Ho Wong
2024-10-23 17:39 ` Eli Zaretskii
2024-10-23 20:03 ` Jimmy Yuen Ho Wong
2024-10-24 9:55 ` Eli Zaretskii
2024-10-24 14:26 ` Jimmy Yuen Ho Wong
2024-10-24 14:39 ` Eli Zaretskii
2024-10-24 15:33 ` Jimmy Yuen Ho Wong
2024-10-24 16:02 ` Eli Zaretskii
2024-10-24 16:49 ` Jimmy Yuen Ho Wong
2024-10-24 17:56 ` Eli Zaretskii
2024-10-24 21:11 ` Jimmy Yuen Ho Wong
2024-10-25 7:21 ` Eli Zaretskii
2024-10-25 13:35 ` Jimmy Yuen Ho Wong [this message]
2024-10-25 15:11 ` Eli Zaretskii
2024-10-28 20:21 ` Jimmy Yuen Ho Wong
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=CAKDRQS5Kktf7OQBn_+e00RiGNeMMfKtXajEUSNGZmZss6KKPng@mail.gmail.com \
--to=wyuenho@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
/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).