An implementation detail in wezterm is that it doesn't model
image placements as a separate entity; they are all bound to
the image cells in the terminal model.
The semantics of the kitty image protocol are that placements
are "permanent" wrt. overwriting a cell with text, except for
the explicit EraseInLine/EraseInDisplay sequences that are
used for clearing.
This commit takes a pass at implementing that semantic in
the wezterm data model.
refs: #986
This should give the shaper a better chance at using text
presentation in a run that mixes emoji with text and/or
uses presentation selectors.
It also exposes the presentation property to the shaper
so that it could potentially adjust its fallback strategy.
However, it doesn't do that here.
refs: https://github.com/wez/wezterm/issues/997
Make a distinction between default and selected presentation,
and account for that in the cell width.
Add a method to the cell that returns the effective presentation.
refs: https://github.com/wez/wezterm/issues/997
These modifiers have the effect of forcing us to consider the grapheme
as being either a single cell (VS15) or two cells (VS16) in the
terminal model.
These don't affect font choice as wezterm doesn't know whether a given
font in the fallback has a textual vs. an emoji version of a given
glyph, or whether a later font in the fallback has one or the other
because we can't know until we fall back, and that has a very high
cost--we perform fallback asynchronously in another thread because
of its high cost.
Depending on the selected glyph, it may or may not render as double
wide.
refs: #997
Since we can now mutate individual frames, we need to avoid
falsely caching across a change; switch from using (image_id, frame_idx)
to frame_hash.
refs: #986
Adds a use_image feature to termwiz that enables an optional
dep on the image crate. This in turn allows decoding of animation
formats (gif, apng) from file data, but more crucially, allows
modeling animation frames at the termwiz layer, which is a pre-req
for enabling kitty img protocol animation support.
refs: #986
I noticed when running the notcurses demo that we're spending a
decent amount of time decoding png data whenever we need to
re-do the texture atlas.
Let's avoid that by allowing for ImageData at the termwiz layer
to represent both the image file format and decoded rgba8 data.
This commit is a bit muddy and also includes some stuff to try
to delete placements from the model. It's not perfect by any
means--more expensive than I want, and there's something funky
that causes a large number of images to build up during some
phases of the demo.
refs: #986
This isn't complete; many of the placement options are not supported,
and the status reporting is missing in a number of cases, including
querying/probing, and shared memory objects are not supported yet.
However, this commit is sufficient to allow the kitty-png.py script
(that was copied from
https://sw.kovidgoyal.net/kitty/graphics-protocol/#a-minimal-example)
to render a PNG in the terminal.
This implementation routes the basic image display via the same
code that we use for iterm2 and sixel protocols, but it isn't
sufficient to support the rest of the placement options allowed
by the spec.
Notably, we'll need to add the concept of image placements to
the data model maintained by the terminal state and find a way
to efficiently manage placements both by id and by a viewport
range.
The renderer will need to manage separate quads for placements
and order them by z-index, and adjust the render phases so that
images can appear in the correct plane.
refs: #986
This teaches termwiz to recognize and encode the APC
sequences used by the kitty image protocol.
This doesn't include support for animations, just the
transmit, placement and delete requests.
refs: #986
These were parsed but swallowed. This commit expands the transitions
to be able to track the APC start, data and end and then adds
an `apc_dispatch` method to allow capturing APC sequences.
APC sequences are used in the kitty image protocol.
refs: #986
This commit hooks up DECRQM so that we can report that we implement
synchronized updates, and then refines the code that manages sending
data to the terminal model; the first cut at synchronized updates
was a bit simplistic, and now we make a point of "flushing" pending
actions when we start a sync point, and again as soon as we release
the sync point.
This smooths out the jaggies around the orca that I mentioned in
dcbbda7702
and while testing this, I realized that recent parser changes had
mangled processing bundled dec private mode sequences where multiple
modes were specified in the same overall escape sequence. I've
added the missing unit test case for this and made that work again.
refs: https://github.com/wez/wezterm/issues/955
refs: https://github.com/wez/wezterm/issues/882
This commit removes the intermediates parameter and collapses it
together with the parameters themselves.
This allows us to model DECSET (eg: `CSI ? 1 l`) correctly.
Previously this would get reported as:
```
params: [1],
intermediates: ['?'],
code: 'l'
```
but since the intermediates are logically things that precede the code,
the canonical interpretation of that would be as if we'd received
`CSI 1 ? l`.
AFAICT, DECSET isn't conforming to ECMA 48 when it comes to this
sequence.
That made things a bit of a headache in the CSI parser, so what we do
now is to treat intermediates as parameters so that it is much simpler
to reason about and match in the CSI parser; we now get:
```
params: ['?', 1],
code: 'l',
```
refs: https://github.com/wez/wezterm/issues/955
The original design of the vtparse crate was inspired by the vte
crate. There were some assumptions about the shape of CSI sequences
that were lossy and that is posing a problem when it comes to
implementing DECRQM.
This commit improves the situation by adjusting CsiParam to be capable
of capturing all of the possible parameters as well as intermediates.
This commit isn't done; I just need to push it to transfer it to another
machine.
refs: https://github.com/wez/wezterm/issues/882
refs: https://github.com/wez/wezterm/issues/955
This implementation doesn't include a timeout, but should be
recoverable via a SoftReset.
There's no query response either: I think I'm missing DECRQM
entirely at the moment.
refs: https://github.com/wez/wezterm/issues/882
4e99edf6f5 split the color into
thin/fat components, but overlooked copying the optional fat
part of the color.
That in turn broke sequences like:
* Set background color
* Erase to end of line
This commit teaches the sgr attribute cloning function to look
at the optional fat component.
refs: #962
Add the third device attributes (DA3) query+reply,
eliminating "unknown/unspecified CSI" error. Like
XTerm, simply reply with zeroes as opposed to site
codes or unique IDs.
https://vt100.net/docs/vt510-rm/DA3.html
* [terminfo] add smxx/rmxx, purge blink
Testing with WezTerm nightly indicates no blink support
available through the xterm \E[5m, and I didn't see any
support in the code -- purge it. smxx and rmxx, meanwhile,
have been added to indicate support for struck text.
* restore blink
Co-authored-by: Wez Furlong <wez@wezfurlong.org>
The common palette indices are in the main cell attributes.
Using true color will allocate fat storage.
This allows reducing the Cell size from 32 -> 24 across the
implementation of storing 10 bpc color (it peaked at 40 in
the last couple of commits).
This adjusts the cursor position after emitting a sixel.
@dankamongmen: I don't have much of a sixel test suite to speak
of (cat snake.six :-p); I'd appreciate it if you could run
notcurses against this and confirm that it is doing something
sane!
At the very least, we shouldn't be warning about the unhandled
mode any more!
refs: https://github.com/wez/wezterm/issues/863
refs: https://github.com/dankamongmen/notcurses/issues/1743
Rust hasn't stabilized fallible allocation, so when we are presented
with an implausibly large sixel, Rust terminates the program; it's not
even a panick that we could potentially catch -> direct to termination.
This commit introduces an arbitrary constraint so that we can
avoid unconditionally terminating for this bad input case.
Thanks to @klamonte for sharing this test case!
A relatively recent commit made it possible for the cell storage
to be smaller than the viewport width.
Avoid panicking when erasing beyond the end of the cell storage.
We can simply NOP as that cell is already implictly erased.
closes: #847
ProbeHints would unconditionally load the terminfo based on $TERM
whever it was created, even if the caller had a pre-supplied
terminfo buffer.
Defer loading that until the caps instance is created.
refs: #817