Whip the ol' llama's ass (fix ncvisual rotation)
* notcurses: flush cursor change requests #673
* rotator: verify ncplane_rgba and ncblit_rgba
* ncblit: rename, accept ncblitter_e #674
* rotator: render from rgba
* rotator: get to rotation
* rotator: add a pi/4 turn at the end
* normal: reuse incoming plane for rendering #672
* rotator poc: rotate a fullplane gradient #672
* normal demo: place visual correctly
* rotator: verify ncplane_rgba and ncblit_rgba
* ncblit: rename, accept ncblitter_e #674
* rotator: render from rgba
* rotator: add a pi/4 turn at the end
* normal: reuse incoming plane for rendering #672
* rotator poc: rotate a fullplane gradient #672
* normal demo: place visual correctly
* rotator poc: throw some red into gradient
* rotator poc: done #662
* oiio: ncvisual_resize() needs set ibuf pointer #662
* normal: only need erase at top of loop
* visual poc: shorter delay
* normal demo: center rendered visual
* comment ncvisual_resize() call
* ncvisual_rotate: call ncvisual_details_seed()
* ffmpeg ncvisual: fix rotation #662
If we're in ASCII mode, no blitter except for NCBLIT_1x1 is going to
work. Whenever NCBLIT_DEFAULT is provided, select NCBLIT_1x1 if we're
in ASCII mode. Add NCVISUAL_OPTIONS_MAYDEGRADE and
NCPLOT_OPTIONS_MAYDEGRADE. Both serve to allow smooth degradation when a
blitter other than NCBLIT_DEFAULT has been provided. Closes#637.
Make calc_gradient_cell() static inline so our templated ncppplot
implementation can use it (ugh). When using NCBLIT_1x1 for plots in
ASCII mode, use space rather than full block, and invert colors.
Use NCBLIT_DEFAULT in the demo for the FPS plot.
This represents an essentially complete rewrite of ncvisual and associated code. It had two major goals:
Improve the ncvisual API based off lessons learned, pursuant to the upcoming API freeze. In particular, I wanted to:
decouple ncvisuals from ncplanes. It should be possible to render a ncvisual to multiple planes, with different scaling each time. It should be possible to create an ncvisual without a plane, etc.
normalize the various ways of constructing an ncvisual -- file, memory, plane, etc.
Support multiple blitters, from 7-bit ASCII to Sixel. This required writing the blitters in several cases, and they're not yet in their final implementations (but the API is fine)
I have not yet unified Plots and Visuals, and might not, given that the Plot code works fine. We could at this point implement Plots in terms of Visuals, though -- the blitter backend range has been unified. Sixel is not yet implemented, though it is listed.
There is a new POC tool, blitter. It renders its arguments using all possible blitter+scaling combinations. Another new POC, resize, displays its argument, then resizes it to the screen size and displays that, explicitly making use of ncvisual_resize() rather than a scaling parameter to ncvisual_render().
This also eliminates some memory leaks and bugs we were seeing in trunk, and brings in Sixel scaffolding.
The C++ wrapper will also need patching back up; I cut most of it down while wrestling with this crap, urk.
Closes#638, #562, and #622.
This is to make it possible, in the future, to create multiple instances
of `NotCurses` for multiple terminals. The first instance of
`NotCurses` becomes the default one, so that any instances of other
classes that aren't explicitly created with a pointer to another
`NotCurses` instance still work as expected.
Note that currently trying to call `notcurses_init` twice results in the
following error for me:
0x55555559bfc0 is already registered for signals
Couldn't drop signals: 0x55555559bfc0 != 0x5555555b6720
terminate called after throwing an instance of 'ncpp::init_error*'
Program received signal SIGABRT, Aborted.
The error is signalled by `setup_signals` and the pointer shown in the
message points to the first `struct notcurses` instance created.
Fixes: https://github.com/dankamongmen/notcurses/issues/616
SIGSEGV was caused by an invalid cast.
Short explanation: PEBKAC
Long explanation: `Selector.hh`, `Plot.hh` and `MultiSelector.hh` did
not include `Plane.hh`, they merely declared `class Plane;` because
inclusion of `Plane.hh` would cause circular dependencies to appear and
the compiler would be unhappy. On top of that, yours truly wrenched the
compiler's hands and caused it to believe that a pointer to `Plane` is
really a pointer to `ncplane*` which was quite a silly thing to do as
the compiler, not having included `Plane.hh` and thus not knowing full
definition of the type, wasn't able to look up the type cast operator in
`Plane`.
Don't abuse `reinterpret_cast`, kids!
Replace the singly-linked z-axis with a doubly-linked list,
and reimplement all z-axis moves as O(1) functions.
Eliminate ncplane_move_{above/below}_unsafe(), as there are no
longer unsafe moves.
ncplane_dup(): properly set target plane attributes/channels
ncplane_move_below_unsafe(): speedup, at most one traversal
ncplane_rgba(): accept null glyph
ncvisual_from_plane(): dup the plane, own it in ncvisual
normal: spin the visual