Add convenience function ncplane_home(). Add an ncblitter_e param
to ncplane_qrcode(), and split int maxversion into value-result
int* ymax and int* xmax. Write the actual sizes of the resulting
visual into these parameters. Update the qrcode demo. Add the
qrcode PoC. Update demos to ncplane_home(), where possible.
ncplane_qrcode() now takes an ncblitter_e and two value-result int*s
in the place of a single value int. The final size of the displayed qrcode
is written to *ymax and *xmax. If the code can't fit within the specified
dimensions, an error is returned. Standard rules for pluggable blitters
apply regarding fallback etc. #699
The Plot unit tests were reaching directly into the objects,
which meant the implementations couldn't include anything
we didn't want public. This was annoying, so I've changed it.
This required adding ncdplot_sample() and ncuplot_sample(),
which we should have had anyway.
Very simple take at ncplane_puttext(), a new function for linebroken text. Also some very basic unit tests. I doubt this works very well yet, but it handles the simplest cases #682. Added nclog(), internal function for logging. #520
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.
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.
* normal/visual: need dup stdplane for rotate
* add ncplane_center(), unit tests
* ncplane_center_abs(): add, unit tests
* ncvisual_bounding_box() for #599
* ncvisual_rotate(): works via bounding box #599
* normal demo: comment out broken section
* rotate: resize underlying plane as needed #599
* ncvisual_rotate: support negative rads #599
Unify ffmpeg/oiio/null implementations, where possible. This effectively
required placing all three in the same file, which meant they're all now
C++. Update FFmpeg implemenation to be C++-usable. Implement
ncvisual_rotate_cw() and ncvisual_rotate_ccw() #515. Move most of tetris
over to Visual from Plane #558. Add bgra_to_rgba(), necessary for
creating ncvisual from BGRA memory. Implement ncvisual_from_rgba()
and ncvisual_from_bgra() #557. Add unit tests on ncvisual rotation.
We need support three distinct paths for destruction of
ncsubprocs: (1) external call to ncsubproc_destroy() while
the subprocess is running, (2) external call to
ncsubproc_destroy() after the subprocess has terminated, and
(3) internal call to ncsubproc_destroy() without any external
call. To do this properly, we always waitid() on the subprocess
in our ncsubproc thread, and do not cancel said thread. This
guarantees that the subprocess has been reaped if the thread
has exited. We throw a pidfd_send_signal() into the thread
prior to the waitid(), because this is safe with pidfds. The
thread reclaims no resources otherwise. ncsubproc_destroy(),
instead, reclaims them, after joining the ncsubproc thread.
It sends SIGKILL before the join, which is once again safe
thanks to pidfds. Resolves#552.
* fedora: dep on OpenImageIO, and use it
* fedora: dep on libqrcodegen-devel
* fedora: BuildRequires OpenEXR-devel
* tight check on USE_MULTIMEDIA
* CMake: enable notcurses-view for ffmpeg OR oiio
* notcurses-view: don't reach into libav
* oiio: ncvisual_render() #453
* oiio: need our own properly-offset ncvisual_plane()
* `visual` poc: accept optional command line argument
* oiio: work for 3-channel images #453
* oiio: destroy ncvisual's plane if we own it #453
* notcurses_visual.3: s/FFmpeg/multimedia/g
* ncplane_at_* and ncplane_at_cursor_*
We had notcurses_at_yx() expanding into three distinct parts of
the cell structure, and ncplane_at_yx() / ncplane_at_cursor()
writing directly to a cell. It was annoying to remember which
was which. The latter two now have a signature matching
notcurses_at_yx(), while the old functionality has been moved
to ncplane_at_yx_cell() and ncplane_at_cursor_yx(). #476
* packaging: s/libtinfo/Terminfo/g
* rust: add stddim_yx()
* rust: check for valid init in unit tests
* rust: serialize up tests
* constify notcurses_term_dim_yx()
* rust: add dim wrappers
* remove notcurses_resize() from public API #367
* call notcurses_resize() from notcurses_refresh() #367
Fill-type functions used to return 0 for success, and -1
on failure. They now return the number of cells written
on success, similarly to ncvisual_render(). Resolves#427.
Certain unit tests required UTF8 encoding on the output
terminal to work (#428). This includes anything which does
any kind of fill. Add enforce_utf8() checks to all such
tests that were missing them. Unit tests once again pass in
a pure ASCII environment.
Resolves#410. notcurses_at_yx() accepted a cell*, but the
gcluster of this cell was always set to 0. The EGC is instead
a heap-allocated copy, returned as the primary return value.
This is due to the absence of an egcpool to bind against.
Existing callers can be converted thus:
* instead of passing cell 'c', pass &(c)->attrword, &(c)->channels
* either initialize 'c' with CELL_TRIVIAL_INITIALIZER, or set its
gcluster field to 0 following the call
I've updated all calls from tests/demos, updated the docs, and
updated the C++ and Python wrappers.
Add ncplane_bound(3). This allows a new plane N to be created in the
*bound* state relative to another ncplane B. If B moves, N moves the
same amount. If N is moved, the coordinates are taken relative to B
as opposed to the standard plane. If B is destroyed, N is destroyed.
Each plane can have many planes bound to it, but can only be bound to
a single plane. Add ncplane_reparent(3). This allows a plane to be
detached from any plane to which it is bound, and optionally rebound
to a new plane. The standard plane cannot be reparented.
Documentation and unit tests have been added for both.
ncvisual_render() now returns the number of cells emitted
rather than just 0/-1. -1 is still returned on failure.
Rather than 0 for length meaning "all possible length", it
now means 0, and -1 means "all possible length". All demos,
tests, and PoCs have been updated. #422
Introduce limited plane rotation capability. We currently support clockwise and counterclockwise rotation of planes. Square and rectangular geometries are both supported, but there must be an even number of columns. The atomic unit of rotation is a 2x1 "square" (this assumes .5 cell aspect ratio). We can only rotate those glyphs which have rotated equivalents, and not even all of those. We currently handle only:
* null glyph
* space
* upper half block
* lower half block
* full block
I've added unit tests as well. This functionality is used by our Tetris example in the book
ncplane_mouseevent_p() is retired--it was poorly named, and
ncplane_translate_abs() does what it does, plus more, plus
more generally (it works on any y, x, not necessarily an
ncinput). update c++ wrappers #394.
* CMake: add USE_PANDOC, USE_DOXYGEN options #101
* README: mention rust
* start integrating rust into build #101
* CMake: add USE_NETWORK option for cargo
* Debian: build-dep on doxygen
* rust: colloquy checks in Cargo.lock
* extract NCKEY defines into their own include
* colloquy: use clap to parse CLI args
* CMake: unify option namespace
* Python: update include path
* Rust: fix up --frozen workings for -DUSE_NETWORK=off
* CMake: abstract out colloquy a little
* Sync direct.hh to the New Way
Get rid of annoying empty line in notcurses-view (and ncvisuals at offsets in general)
Implement most of the Selector widget. Need to add styling and scrolling still. #166
Reenable ubuntu focal build
Subtitles! We decode them, and display them in notcurses-view. If ncvisual_simple_streamer() is provided an extra ncplane, it will use it to display subtitles. #95
We now build Python by default, as things are working much better.
ncplane_set_base() now takes channel, attrword, and EGC, so you can usually avoid having to set up and release a cell. ncplane_set_base_cell() takes over duty from ncplane_set_base() for ease of conversion.
notcurses-demo and notcurses-view now both accept a 0 for delay multiplier, meaning 'go as fast as you possibly can'. Very small multipliers (e.g. 0.00001) no longer cause floating point exceptions.
fading routines no longer cause floating point exceptions on very small timescales.
* palette_set: update pal256 damage map #230
* drone: use newest builders
* palette: send oc on exit for color reset #285
* palette_new: copy existing palette in #230
* Python: use checkRGB everywhere
* more palette unit testing
* add ncplane_set_*_palindex()
* render fg palindex #230
* palette index color is out of 1000
* jungle demo works #253
* sync up some docs #244
* sync README and man page
* notcurses_output() man page work
* pull attr/channels from output functions #244
* witherworm: clean up explicit moves #244
* still more man page work
* notcurses_lines, last of the man pages i think
* panelreel man page #244
* debian: ruby-ronn->pandoc
* debian: full multiarch compliance
* debian: symbols file
* pandoc: fix syntax for lexgrog
* fm6.mkv: strip audio
* pandoc: fix up apropos man syntax #249
* ncurses_lines man page
* higher planes stomp wide glyphs
* broken unit test
* develop out widestomp PoC
* fix notcurses_at_yx()
* fix up dig_visible_cell() return value
* refuse wide glyph on last column #242
* set adjacent cell wide when rendering #158
* xray: eliminate weird color flicker
* witherworm: don't eat wide glyphs
* unit test for boxed glyph
* uniblock: no need to emit so many U+200Es
* witherworm: remove wide glyph hack
* introduce doctest over googletest #202
* call dtester in in targets
* doctest conversion #202
* channel.cpp -> doctest #202
* egcpool tests -> doctest #202
* input tests to doctester
* zaxis -> doctest
* drone: always define LANG
* libav to doctest #202
* panelreel tests to doctest #202
* spec that a C++17 compiler is now required for doctest #202
* enmetric tests -> doctest #202
* fade tests -> doctest #202
* notcurses test case -> doctest #202
* last conversion to doctest #202
* finish move to doctest #202
* drone: set up make test
Allow -1 in move specification to remain where we are on that
axis (#210), necessary for context-sensitive aligned output.
Add _aligned forms to printf and vprintf. Invert various output
functions so that simpler form is static inline wrapper around
more complicated form, rather than complicated form being a
static inline composition, facilitating atomic move+output. All
output forms now have a simple form (no alignment, placement at
cursor), an _aligned() form, and a _yx() form.
* planereels tester #180
* suppress_banner in all tests
* tabletcb: start passing back tablet
* properly initialize fbbytes stat
* panelreel: logic fixes#178
* install all testing data
Implement a fairly conservative, line-granularity, two-level damage map. One on the overall notcurses object is dirtied by planar moves, creations, deletions, and resizes. One on each ncplane is dirtied by glyph output, media rendering, fades, and erasure. #83 This has some definite false positives: a hidden plane which moves will damage a bunch of lines unnecessarily. For now, don't do things like that :D.
Extra byte per line per plane, shouldn't be a problem.
Two new stats for cell elisions and emissions
Allow keypress to interrupt view-demo
ncvisual_stream() now allows a callback per frame
Allow ncvisual_open() to create its own, perfectly-sized, ncplane #128
Typical performance prior to this PR:
4655 renders, 18.3s total (0.000305s min, 0.196s max, 0.0039s avg 253.9 fps)
401046.505KB total (9.688KB min, 139.697KB max, 86.15KB avg)
Emits/elides: def 1082115/116196 fg 10547624/7236460 bg 10602717/6208644
Elide rates: 9.70% 40.69% 36.93%
4680 renders, 18.4s total (0.000285s min, 0.15s max, 0.0039s avg 255.0 fps)
403078.188KB total (9.688KB min, 139.697KB max, 86.13KB avg)
Emits/elides: def 1088994/116196 fg 10604983/7267750 bg 10655426/6237472
Elide rates: 9.64% 40.66% 36.92%
4699 renders, 17.8s total (0.000227s min, 0.192s max, 0.0038s avg 263.8 fps)
403266.907KB total (9.688KB min, 139.697KB max, 85.82KB avg)
Emits/elides: def 1086511/116196 fg 10601709/7359116 bg 10661910/6326744
Elide rates: 9.66% 40.97% 37.24%
After this PR:
5625 renders, 15s total (9.36e-05s min, 0.187s max, 0.0027s avg 375.2 fps)
168365.640KB total (0.930KB min, 139.600KB max, 29.93KB avg)
Emits/elides: def 310575/116196 fg 4486002/4473416 bg 4116835/4630666
Elide rates: 27.23% 49.93% 52.94%
Cells emitted; 9928000 elided: 12572000 (55.88%)
5642 renders, 14.2s total (9.17e-05s min, 0.154s max, 0.0025s avg 397.0 fps)
168669.009KB total (0.605KB min, 139.600KB max, 29.90KB avg)
Emits/elides: def 310819/116196 fg 4499833/4482134 bg 4118562/4652470
Elide rates: 27.21% 49.90% 53.04%
Cells emitted; 9962160 elided: 12605840 (55.86%)
5650 renders, 14.3s total (0.000118s min, 0.143s max, 0.0025s avg 395.7 fps)
169461.884KB total (0.860KB min, 139.600KB max, 29.99KB avg)
Emits/elides: def 305431/116196 fg 4515396/4456376 bg 4149967/4613668
Elide rates: 27.56% 49.67% 52.65%
Cells emitted; 9945200 elided: 12654800 (55.99%)
on netcurses-demo, we're eliding about half of the total cells via this damage map. that's pretty fucking sweet! FPS increase of about 50% -- I'll take that any day of the fuckin' week, boyo. w00t!
https://www.youtube.com/watch?v=XbGs_qK2PQA