[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#71039: :box :line-width and :underline :position should accept fract
From: |
JD Smith |
Subject: |
bug#71039: :box :line-width and :underline :position should accept fractional sizes |
Date: |
Sat, 18 May 2024 21:32:23 -0400 |
> On May 18, 2024, at 12:06 PM, Eli Zaretskii <eliz@gnu.org> wrote:
>
>> From: JD Smith <jdtsmith@gmail.com>
>> Date: Sat, 18 May 2024 10:52:03 -0400
>>
>> There are, however, two face size attributes which are hard-coded in pixels:
>> :box :linewidth and :underline :
>> position. It would be very convenient if these also accepted fractional
>> floating point values. E.g. a face
>> attribute of:
>>
>> :box (:line-width (0.5 . -0.25))
>>
>> would indicate a box with half a char width outside padding left & right,
>> and one-quarter char height padding
>> above and below.
>
> Are you sure this is a good idea?
Definitely! I've spent a good bit of time working around the absence of this
feature (and, while I found solutions, they were too convoluted to be
practical).
> What would you like this to do when
> two adjacent runs of text are shown using different-size fonts (which
> AFAIU is the main use case for this feature)?
They'd have different height boxes, and that would be the desired effect. Sort
of the same idea as something like:
(insert "\n"
(propertize " Short " 'face '(:box (:line-width (0 . -4))
:inverse-video t))
(propertize " BOX " 'face '(:box (:line-width (0 . -2)) :inverse-video
t))
(propertize " tall box " 'face '(:box (:line-width (1 . 1))))
"\n")
except also adaptive to the text height. Normally of course you would not do
this for random text. Instead you'd apply targeted floating :box widths to
short stretches of text, like labels.
> We currently force the
> thickness and position of the underline to be identical for all the
> characters of a stretch of underlined text, even if they are displayed
> using different fonts, and we take those values from the first part of
> the underlined text's stretch. This is because having the underline
> break or show differently in the middle of an underlined text has ugly
> appearance.
I wan't aware of this behavior, but I do see the value in that special rule for
underlines. It's possible that pixel position indeed makes the most sense for
underline, given the face-merging behavior you describe. I included it mostly
for completeness.
More important is :box. For various effects which cover short stretches of
text like label boxes, etc., the ability to have the box thickness scale with
char size would be very useful. Often these use inverse-video, so that the
"box" is in the background color. Many packages reach for SVG images in this
context, but with a little help, many of those uses could be avoided.
> OTOH, calculating the thickness and position in pixels from the face
> font's dimensions is easy enough if your code needs that.
Sure, but upon text-scaling, this calculation needs to be performed again
(probably in a temporary buffer, and across many faces). Then, per-buffer face
remaps must be applied and managed, etc. I've done that, but it's a lot to
juggle for a simple box.
> Given these two facts, I'm not sure supporting float values here will
> be worth the effort.
I'm confident they'd be used quite a lot. Do you have a sense of how difficult
these improvements would be? Since you can already now apply fractional
specified space like (space :width (0.25 . width)), I was hopeful the
calculations would be close at hand.
>> In addition, :box would be even more powerful, and obviate the use of SVG
>> styling in many situations, if :box :
>> line-width optionally accepted a list of four parameters for box dimensions,
>> one for each side:
>>
>> :line-width (left right top bottom)
>>
>> naturally as either pixel or floating point fractions.
>
> How is this different from specifying the thickness and the position,
> as we have today?
AFAIU there is no :position offset for :box? Right now, :box can specify
thickness as a fixed number of pixels outside (or inside, if negative) the
character(s), and in recent versions these widths can differ vertically and
horizontally. But boxes are always centered horizontally on the boxed text and
vertically on the line (including any line-spacing).
What the above proposal would do is allow you to specify the box width
separately on all 4 sides of the affected text: left, right, top, and bottom.
So for example:
:line-width (4 0 -0.25 -0.1)
would push the box 4 pixel to the left, and pull the box down from the top more
than up from the bottom. As a related idea, following your suggestion, you
could keep :line-width as-is and add a :box :position attribute that shifts the
box vertically (which would be the same except symmetric left/right).
The floating point width is probably more important, but this would enable some
useful effects like simple text-based progress bars, etc.