Subject: Re: bug#64420: string-width of … is 2 in CJK environments

From: Dmitry Gutov <[email-masked]>
Date: Sun, 2 Jul 2023 16:20:25 +0300

On 02/07/2023 16:10, Eli Zaretskii wrote:
>> Date: Sun, 2 Jul 2023 15:57:07 +0300
>> From: Dmitry Gutov <[email-masked]>
>>
>> Hi! This was reported to company-mode
>> (https://github.com/company-mode/company-mode/issues/1388), as a
>> scenario that makes the overlay-based completion popup misrender because
>> the columns are not computed right when that char is present.
>>
>> To repro:
>>
>>     (set-language-environment "Chinese-BIG5")
>>     (string-width "…") ;; => 2
>>
>> In the default language environment its width is reported to be 1.
>>
>> This doesn't seem to make sense because it's rendered one column wide
>> either way.
> 
> On GUI frames Lisp programs that need to know the actual width of some
> string should use string-pixel-width, not string-width.  The latter is
> basically only for TTY frames.
> 
>     (progn
>       (set-language-environment "Chinese-BIG5")
>       (ceiling (/ (string-pixel-width "…")
>                   (float (default-font-width))))) ;; => 1

Thank you.

Is there some inherent reason why string-width differs from the result 
of the above expression, and especially only does that on CJK?

Since the overlay-based popup is used on both GUI and Terminal frames, 
are you suggesting I define my own string-width like this?

(defun company--string-width (str)
   (if (display-graphic-p)
       (ceiling (/ (string-pixel-width str)
                   (float (default-font-width))))
     (string-width str)))