Update tweak.scaling-filter to recognize the new scaling filters added
in fcft-3.3.0.
Since fcft_set_scaling_filter() is deprecated in 3.3.0, don't use it
anymore, and set the scaling filter via fcft_font_options instead.
This ensures empty lines are treated correctly, and is also more in
line with how lines are handled at runtime, when filling the
scrollback.
For now, set linebreak=false as soon as something is printed on a
line. It will remain like that *until* we reach the end of an old row
with linebreak=true, at which point we set linebreak=true on the
current new line.
This way, all lines are treated as having a hard linebreak, until it's
cleared when we do an auto-wrap.
This change alone causes issues when reflowing text, as now all
trailing lines in an otherwise empty window are treated as hard
linebreaks, causing the new grid to insert lots of unwanted, empty
lines.
Fix by doing two things:
* *clear* the linebreak flag when we pull in new lines for the new
grid. We only want to set it explicitly, when an old row has its
linebreak flag set.
* Coalesce empty lines with linebreak=true, and only "emit" them as
new liens in the new grid if they are followed by non-empty lines.
Don't set linebreak on linefeed. Instead, rely on the default value of
true, and that it is only cleared when a character is printed while
LCF=1.
Note that printing to a row that has linebreak cleared, will set the
linebreak flag again.
This implements gamma-correct blending, which mainly affects font
rendering.
The implementation requires compile-time availability of the new
color-management protocol (available in wayland-protocols >= 1.41),
and run-time support for the same in the compositor (specifically, the
EXT_LINEAR TF function and sRGB primaries).
How it works: all colors are decoded from sRGB to linear (using a
lookup table, generated in the exact same way pixman generates it's
internal conversion tables) before being used by pixman. The resulting
image buffer is thus in decoded/linear format. We use the
color-management protocol to inform the compositor of this, by tagging
the wayland surfaces with the 'ext_linear' image attribute.
Sixes: all colors are sRGB internally, and decoded to linear before
being used in any sixels. Thus, the image buffers will contain linear
colors. This is important, since otherwise there would be a
decode/encode penalty every time a sixel is blended to the grid.
Emojis: we require fcft >= 3.2, which adds support for sRGB decoding
color glyphs. Meaning, the emoji pixman surfaces can be blended
directly to the grid, just like sixels.
Gamma-correct blending is enabled by default *when the compositor
supports it*. There's a new option to explicitly enable/disable it:
gamma-correct-blending=no|yes. If set to 'yes', and the compositor
does not implement the required color-management features, warning
logs are emitted.
There's a loss of precision when storing linear pixels in 8-bit
channels. For this reason, this patch also adds supports for 10-bit
surfaces. For now, this is disabled by default since such surfaces
only have 2 bits for alpha. It can be enabled with
tweak.surface-bit-depth=10-bit.
Perhaps, in the future, we can enable it by default if:
* gamma-correct blending is enabled
* the user has not enabled a transparent background
If the user has configured cursor.style=hollow, make DECSCUSR 1/2 set
the cursor to hollow rather than block, and make DECRQSS DECSCUSR
respond as if cursor.style=block.
The idea is to not expose the hollow variant in DECSCUSR in any way,
to avoid having to extend it with custom encodings.
Another way to think about it is this is just a slightly more
discoverable way of doing:
cursor.style=block
cursor.block-cursor-is-hollow=yes
When compiled with grapheme clustering support, zero-width characters
that also are grapheme breaks, were ignored (not stored in the
grid).
When utf8proc says the character is a grapheme break, we try to print
the character to the current cell. But this is only done when width >
0. As a result, zero width grapheme breaks were simply discarded.
This only happens when grapheme clustering is enabled; when disabled,
all zero width characters are appended.
Fix this by also requiring the width to be non-zero when if we should
append the character or not.
Closes#1960
When the cursor is at the end of the line, with a pending wrap (LCF
set), the lcf flag should be cleared *and* the cursor moved one cell
to the right.
Before this patch, we cleared LCF, but didn't move the cursor.
Closes#1954
Wrap *all* cell copying logic in a for-loop for the characters
width. This _should_, in theory, mean reflow of e.g. cursor
coordinates in the middle of a multi-column character works correctly.
Also fix reflow of cmd start/end integration.
We've been trying to performance optimize reflow by "chunking" cells;
try to gather as many as possible, and memcpy a chunk at once.
The problem is that a) this quickly becomes very complex, and b) is
very hard to get right for multi-column characters, especially when we
need to truncate long ones due to the window being too small.
Refactor, and once again walk and copy all cells one by one. This is
slower, but at least it's correct.
Commit 859b4c89 (url-mode: wip: more work on regex matching,
2025-01-30) regressed URL detection in weechat. Some of the URLs
still work but others don't. This is because regexec() stops at the
first NUL, thus skipping the rest of the line. weechat seems create
NUL cells between their UI widgets.
Work around this by replacing NUL with space. This is probably correct
because selecting and copying those cells also translates to space
(not sure where in the code).
Zero-initialize the 'launch' spawn template before calling
value_to_spawn_template(). This is needed since
value_to_spawn_template() tries to free the old value before assigning
the new one.
Closes#1951
When checking if we're breaking in the middle of a multi-column
character, we counted spacers starting from the break point. But,
the character may be wider than that. Use the fact that the spacers
cells encode how many *more* there are after them; when we get to the
first one, we know exactly how wide the character is.
When appending to an existing composed character, "inherit" its forced
width, if set.
Also make sure to actually _use_ the forced width, if set, rather than
the calculated width.
This fixes an issue when appending zero-width codepoints to a
forced-width combining character.
If there's a single codepoint in the text portion of the OSC sequence,
and its calculated width matches the forced width, print it directly
to the grid instead of emitting a combining character.
When w=0, we split up the text string "as we normally would". Since we
don't support any other text-sizing parameters, this means simply
printing each codepoint to the grid.
This function "prints" any non-ascii character (i.e. any character
that ends up in the action_utf8_print() function in vt.c) to the
grid. This includes grapheme cluster processing etc.
action_utf8_print() now simply calls this function.
This allows us to re-use the same functionality from other
places (like the text-sizing protocol).