macvim-dev / macvim

Vim - the text editor - for macOS
https://macvim.org
Vim License
7.47k stars 680 forks source link

Support strikethrough/underdouble/underdashed/underdotted styles #1287

Closed ychin closed 1 year ago

ychin commented 1 year ago

Add support for all the missing text styles for MacVim for Vim parity.

For strikethrough, this needed to be done as a second pass to make sure they get drawn on top of the text. This is necessary because currently the logic buffers texts up before dispatching them later in a line, so it's just easier to loop through the line a second time if we detected strikethrough. For the strikethrough position, we simply use the half of xheight which seems to work best in looking good.

For underdouble, the logic is a little tricky because sometimes we don't have space below the line. When that's the case, simply draw the second line on top of the first line.

For underdotted, need to do something smart to space out the dots. When the width is divisible by 2, they get spaced out evenly. If they are not, try to make it work if divisible by 3. If that's not the case, we just readjust the size of dot/gap a little bit to make it fit, even though now we have non-integer sizes (from experimentation, the antialising works well enough that it's not too jarring).

Also fix rendering of undercurl to work for double-width characters as well.

Note that underdouble/underdotted/underdashed are not supported in regular gVim yet, and so I had to add the ifdef for those in gui.c. These may cause merge conflicts later which should be easily resolved.

Known issue 1: Note that currently underline is not respecting the font's underline thickness and position. We always use a thickness of 1 pt, and hard-code a 0.4*descent position, which are not great. Thickness in particular should scale with the font size. They should be fixed in a future commit.

Known issue 2: There are some current clipping bugs in the renderer. This is because the line height returned by NSLayoutManager is sometimes smaller than ascent+descent+leading, and MMCoreTextView for some reason takes the ceil(descent) (presumably to make the rendering grid-aligned). This should be fixed later.

Fix #1034