Notcurses Versions Save

blingful character graphics/TUI library. definitely not curses.

v3.0.9

1 year ago

by far the longest time between Notcurses releases, and there's not very much here, save a nasty infinite loop discovered and fixed by @drewt. is this project dead? let me answer that with dmx:

dank's gonna give it to ya

hell no this project isn't dead, but this project has achieved most of its primary goals, and i don't intend to move on longer-term, more speculative ones until next spring (2023) at the earliest. gotta make that paper in the meantime, and i'm deeply embroiled in the shit at work, keeping the satellites doing what they do best and generally doing the do as it's done. but this bugfix release did feel warranted.

ALSO, regarding inability to build against the most recent doctest 2.4.9, yeah it totally fucking sucks. it's a bug in doctest, and it was fixed months ago, and we just haven't had a new doctest release. I've asked for one; we'll see. Ugh. this isn't really something we can work around easily, and there's no reason i can see for doctest not dropping a fixed 2.4.10. if this continues, i might have to rethink reliance on doctest... =\

anyway! here you go, ya filthy animals

v3.0.8

2 years ago

we haven't had as much notcurses lately as we were! well, after two and odd years going balls-to-the-wall on it, it had reached a point where i could finally cool off a bit, and i did! still absolutely resolving bugs and adding new features, just took some time to do other things. like build a new workstation and write a lengthy essay and regain favor at my day job, where terminal graphics absolutely do not pay the bills. but i still love ye, and we're still here.

this fixes use of bare Escape as input in terminals other than kitty, and recognizes curly underlines in Contour. some other bugs came in over this period, but most of them were resolved via external fixes, hurrah.

v3.0.7

2 years ago

I made the horrible decision to upgrade and generally trick out my home workstation, and a seeming eternity later, I finally have it more or less back up, except it now prints something about "spurious native exception"s every ~3s, Never get into watercooling, kids.

  • You can now output tabs (\t in Cese, ASCII/UCS 9 "Horizontal Tab")! Tabstops are relative to the output plane, and fixed at 8 cells (#1233)
  • Fixed bad bug in Sixel threading engine (#2627)
  • Oh! In a major change to fundamental operations, if the standard plane is scrolling, and you cause it to scroll, notcurses_render() will now be called in the context of that output. This was done to work around a major annoyance and limitation of CLI mode, that you can't just dump output like one does in a ... CLI, and instead had to call notcurses_render() explicitly a bunch if you wanted to actually generate all the output you wrote, and have it in the scrollback buffer etc. This was universally despised. So in a Alexanderish strike at this Gordian shit sandwich, we now call notcurses_render(). This means you can just dump output to a scrolling standard plane, and not worry about anything except a final notcurses_render(). Your output will be displayed as you write it, and all of it will be displayed.

This mechanism is subject to change, but it's probably how things are working going forward.

"but dank" i hear you asking, "wouldn't this rule apply to all planes? why the special case?" the answer is no, and the reasoning is that you've chosen to engage a scrolling standard plane, which comes with a host of different behaviors. ineluctable modalities of the hackable, as stephen daedalus might say.

v3.0.6

2 years ago
  • Fix empty output when ncplane_puttext() is used with NCALIGN_UNALIGNED (#2611 ) , thanks @alexhsamuel for the report!
  • Fixed numerous issues regarding mouse interactions with ncmenu (#2592), thanks @kascote for the report!
  • Fixed bug where ncmenu entered an infinite loop when opening a menu with no enabled items (#2606)
  • Fixed assert() when replies came broken across multiple reads (#2590 ); this was especially nasty when running over ssh. You wouldn't see this bug unless your Notcurses was built with CMAKE_BUILD_TYPE=Debug or NDEBUG was explicitly undefined, thanks @christianparpart for the report!
  • Don't emit DECSDM unless we know for sure what terminal we're talking to (#2587), thanks @autumnmeowmeow / @j4james / @dnkl for the report and discussion!
  • Massive overhaul of the Sixel encoder, ending this area of work for the time being. We now consume ~90% less memory per Sixel-targeted ncvisual, and encode in about 20%--50% of the 3.0.5 times. A tremendous improvement. How delightfully baller. We're still not where I'd like to be, but we're so much better than we have ever been. This work was tough, and dominated the 3.0.6 cycle (#2573 , #2603). #2573 is an epic story indeed, well worth reading IMHO.

Welcome @alexhsamuel , who appears to be taking over the Python wrappers, aka the bane of my existence.

i'll be having some intestines removed next week, having deemed them unfit for my august personage, but i doubt it'll slow me down for more than a few hours. hack on!

I checked the guidebook and it said: Excellent food, malevolent ambience. I'd been habitually abusing an illegal growth hormone extracted from the pituitary glands of human corpses and I felt as if I were drowning in excremental filthiness but the prospect of having something good to eat cheered me up. I asked the waitress about the soup du jour and she said that it was primordial soup—which is ammonia and methane mixed with ocean water in the presence of lightning. Oh I'll take a tureen of that embryonic broth, I say, constraint giving way to exuberance—but as soon as she vanishes my spirit immediately sags because the ambience is so malevolent. The bouncers are hassling some youngsters who want drinks—instead of simply carding the kids, they give them radiocarbon tests, using traces of carbon 14 to determine how old they are—and also there's a young wise guy from Texas A&M at a table near mine who asks for freshly ground Rolaids on his fettuccine and two waiters viciously work him over with heavy bludgeon-sized pepper mills, so I get right back into my car and narcissistically comb my thick jet-black hair in the rearview mirror and I check the guidebook. There's an inn nearby—it's called Little Bo Peep's— its habitues are shepherds. And after a long day of herding, shearing, panpipe playing, muse invoking, and conversing in eclogues, it's Miller time, and Bo Peep's is packed with rustic swains who've left their flocks and sunlit, idealized arcadia behind for the more pungent charms of hard-core social intercourse. Everyone's favorite waitress is Kikugoro. She wears a pale-blue silk kimono and a brocade obi of gold and silver chrysanthemums with a small fan tucked into its folds, her face is painted and powdered to a porcelain white. A cowboy from south of the border orders a "Biggu Makku." But Kikugoro says, "This is not Makudonarudo." She takes a long cylinder of gallium arsenide crystal and slices him a thin wafer which she serves with soy sauce, wasabi, pickled ginger, and daikon. "Conducts electrons ten times faster than silicon... taste good, gaucho-san, you eat," she says, bowing.

v3.0.5

2 years ago

For all my test images, Notcurses now encodes sixels as quickly or more quickly than libsixel, while producing output at least as good as libsixel (when the latter is run without dithering). This completes the drive to improve Sixel quantization described in the 3.0.0 release notes. Yay!

  • Fix invalid access resulting from Sixel moves when margins were in use #2546
  • notcurses-info colors its gradient based on colors 4--7 of the palette, allowing it to be "themed" #2568
  • add ncpalette_get() #2565
  • fix up cursor report location misaccounting when not attached to a terminal #2558
    • this finally fixed the growlight autopkgtests on debian
  • treat permanent failure reading as EOF rather than looping on failing read #2558
  • properly propagate error code from get_cursor_location()
  • unlock on error path in get_cursor_location()
  • always treat ctrl+d as EOF in ncdirect_readline()
  • avoid input drops under pressure by properly accounting for output space availability #2548
  • when CapsLock is set in the kitty protocol, capitalize any lowercase ascii to match other situations
  • when Ctrl is set in the kitty or XTMODKEYS protocols, capitalize any lowercase ascii to match other situations #2555
  • consider kitty events without an event type to be PRESS #2554
  • add support for super, hyper, numlock, and capslock modifiers from kitty protocol #2553
  • notcurses-demo: stop trying to read after EOF to avoid hot loop #2547
  • reject invalid XTGETTCAP bytes (see contour 582)
  • skip merge if it's not necessary in sixel quantization #2516
  • handle negative XTGETTCAP #2544
  • fold down XTGETTCAP responses #2541
  • improve accuracy in sixel color quantizing by using 100 scale, then folding 100 to 99

v3.0.4

2 years ago

[a weary dank emerges from the codemines] This one had some rough bugs deep in the input layer to resolve. Hopefully they're all actually fixed. I think they are.

  • Yelled at our friends at the Alpine project and Notcurses there is now compiled the way mamma used to, for significant perf gainz. Thanks!
  • With any luck or justice or if I'm just not going to die a dickrotted leper, Debian bug 997845 is fixed
  • The input readiness file descriptor has for a long time been unreliable on all but Kitty. Unfortunately, I use Kitty as my daily driver, and tend to miss things easily. Thanks to @kmarius for staying on top of #2216, which i likewise believe to be well and truly fixed, finally
  • Work out the semantics of NCKEY_EOF and implement it properly along all paths #2525
  • Further work on improving the Sixel quantizer #2515
  • Full level-2 XTMODKEYS support including the Meta modifier and synthesized signals from XTMODKEYS #2522, #2518 thanks @cyanideforbreakfast for motivation and @dnkl for assistance
  • Report pixel-granular information for mouse events when Protocol 1016 is supported. Add pmouse entry to notcurses-info to see whether 1016 is available #2326.
  • Clean up the legend in the [reels] demo, which otherwise looked stupid in the [fission] demo for DFSG builds #2535
  • handle iTerm's particular XTSMGRAPHICS failure messages #2531 thanks @michaelsbradleyjr for report
  • properly reset keyboard protocol when leaving alternate screen #2509 thanks @Mukundan314 for report
  • fix sixel unit tests to work in all geometries
  • terminology now supports XTVERSION. good for them.
  • install tfman.1 into doc tarball.
  • actually implement BUILD_FFI_LIBS #2519

this was not a fun work cycle, not at all. but these were all deep bugs that needed be knocked out. work on input isn't sexy, and it's hard to show off, but when the chips are down, it's something that'll differentiate the players from the scrubs. ours is the most general, complex, and powerful of which i'm aware (would you expect anything less?), and input's something where a lot of terminals went their own ways.

anyway, hack on.

metal fingers in my body

v3.0.3

2 years ago

No big changes here. Sixel quantization has been rewritten; it is now substantially faster, but has taken a quality hit on some images. I'll be working on rectifying this for 3.0.4 (see #1452, #2503, and #2516).

  • Eliminate garbage input in XTerm on startup when Sixel is not supported (#2517)
  • Count sixel properly in bitmap stats (#2507)
  • Fix [box] demo when there is no available pixel geometry (#2505)

there might have been a few other things in there, but they were small. Most work was related to improving SIxel quantization.

v3.0.2

2 years ago
  • General blending: default colors and palette-indexed colors can now be blended along with RGB colors (#2433, #2442)
  • ncplayer -k and the notcurses-demo usage screen have been converted from Direct Mode to CLI mode (#2188, #2486)
  • Cell blitters properly clear target cells when transparent.
    • Results in colors being properly preserved from [highcontrast] to [dragon] (#2419)
  • When libdeflate is unavailable, use zlib for kitty graphics (#2423)
  • Avoid lockup when redirecting input from a small file (#2496)
  • Call nccell_release() on cells lost to ncplane_resize() (#2426)
  • Fix bug where NCALIGN_RIGHT with overfull line resulted in no output (#2472)
  • Fix crash in certain cases when resizing the visible area (#2471)
  • The [view] demo now keeps the picture-in-a-picture aligned with the right border on resize (#2479)
  • Implement the -L option for ncls (dereference symlinks) (#2006)
  • Don't assert() out of ncneofetch when lacking a logo (#2494)
  • New binary tfman, a man page browser ala man(1). Experimental.

2021-12-21-144807_1453x1410_scrot

v3.0.1

2 years ago
  • fixes up build and unit test problems when using DFSG_BUILD.
  • add NCPLANE_OPTION_VSCROLL to enable scrolling on a plane from the beginning.
  • add NCPLANE_OPTION_AUTOGROW to support autogrowth of planes
    • if scrolling is enabled, autogrowth happens down
    • otherwise, it happens right
  • nctrees are now dynamic. add nctree_del() and nctree_add(). you can now create an empty nctree. #2458
  • query palette from terminals supporting this functionality #2442
  • restore original palette on terminals lacking XTPUSHCOLORS/XTPOPCOLORS #2435
  • stop issuing oc on startup and shutdown, preserving custom palettes #2450
  • fix static linking #2454
  • add some Kitty keyboard protocol elements we were missing #2439, #2452
  • properly handle control sequences split across multiple reads #2448
  • properly handle newlines in ncplane_puttext() #2446
  • don't allow ncchannels_reverse() to enter illegal states #2421
  • copy EGCs when calling ncplane_putc(), as they could be invalidated within (fixes OfflineEGCs unit test) #2420
  • fix for Linuxbrew build #2428
  • install alternate signal stack handler via sigaltstack() on UNIX #2424
  • faster ncplane_resize() when only the y dimension is changing #2425

v3.0.0

2 years ago

in the A! I keep it playa while some choose to play it safe boi, check the résumé: it's risky business in the 'A'

Notcurses 3.0.0 “In the 'A'” with API/ABI3

boom! =]

Notcurses 3.0.0 represents over a year of development since Notcurses 2.0.0 "Stankonia".

The overall vision remains unchanged from the very beginning—composition of z-ordered planes, with an API naturally expressed in terms of 888RGB DirectColor and Unicode Extended Grapheme Clusters, amenable to multithreading—but it's grown beyond all my dreams. Notcurses has pushed the terminal ecosystem forward, with patches and influence going into XTerm, Kitty, Alacritty, MLterm, Contour, foot, the Linux console, iTerm2, MSYS2, console-setup, Valgrind, musl, and some I'm forgetting. Notcurses makes use of advanced new kernel functionality like Linux's pidfds, but at the same time runs on various BSDs, macOS, and even Microsoft Windows (natively, not just through WSL). It fully supports the new Windows ConPTY and Microsoft Terminal. It can be used to build fixed-screen TUIs and scrolling CLIs. Aside from its lack of Curses compatibility, it is—as far as I'm aware—the best, most powerful, ballinest terminal graphics library in existence.

If you're writing a new terminal application in 202x, you probably ought be using Notcurses.

help wanted/needed

a python eating a crocodile

are you a python hacker with a solid understanding of wrapping C? because i absolutely am not, and honestly have no interest in becoming one. i desperately need someone committed to adapting new C functionality in python as it emerges, ideally further extending that to create a truly pythonesque Notcurses interface. pick up @igo95862 's work in python/ and go to town. do you write go? same shit! c#? dot-net this motherfucker! what's in it for you? i wish i knew the answer to that question myself. @joseluis seems to have the situation pretty well handled for rust; ask him. i'll be handling fortran, prolog, and threaded intercal wrappers.

left: a python eats a crocodile, before unhinging its dynamically-typed jaw and eating my time. note that the python is devouring the crocodile without a hint of parallelism, despite having seemingly evolved for, like, six hundred million years now. i bet it OOMs.

API and ABI break

Notcurses 3.0.0 introduces a hard ABI break relative to previous versions, and changes the SONAME to reflect this. Previous binaries will not link against Notcurses 3.0.0+. Even if you use no new API, nor any API which has been deprecated, your binary must be recompiled. The API has expanded throughout 2.x development, but 3.0.0 removes all functionality previously only deprecated. See the API changenotes below for complete information. I'm sorry for the API changes, but they leave Notcurses much improved for the future. Most changes can be safely implemented via global regex.

There may be any number of additions to the API for Notcurses 4, but every attempt will be made to maintain backwards compatibility. The ABI will not change across 3.x development.

major additions since 2.0.0

kill your masters; become ungovernable

With that, the most major changes since 2.0.0 include:

  • Direct interrogation of terminals, when present, to determine capabilities—Notcurses is moving away from reliance on Terminfo. Capabilities acquired in this fashion aren't dependent on the local copy of the terminfo database, nor upstream authors getting their terminfo changes into NCURSES, and especially not on the user correctly setting TERM.
  • Support for XTMODKEYS and the Kitty keyboard protocol for rich events. Support for console mice via GPM. Note that the Kitty keyboard protocol is now supported by foot! Among other things, this allows disambiguation of key depress, repeat, and release, as well as detection of modifier keys by themselves. Clients can now specify which mouse events they want, and get mouse movement events even when no buttons are pressed.
  • Support for Sixel and Kitty bitmap graphics, and direct draws to the Linux framebuffer console. Note that Kitty graphics are now supported by WezTerm! Bitmap capabilities are determined at runtime, and no matter what the backend, they're efficiently integrated into the overall z-axis model. They cover glyphs, and are covered by glyphs, just like any other plane. As always, Notcurses steps down among its blitters based on local capabilities.
  • The Unicode 13-based 3x2 "sexblitter" and 8x1 "eightsplotter" were added.
  • Support for Microsoft Windows, macOS, and Dragonfly BSD. macOS support benefitted greatly from @michaelsbradleyjr 's assistance testing, setting up GitHub CI, and providing a development platform. Windows support benefitted greatly from the wisdom and grandmotherly patience of @j4james. Both were substantial efforts, with Windows being by far the larger one, consuming close to two months' development time. It was worth it, though, to show off the powerful new Microsoft Terminal and the ConPTY, wherein Microsoft gets it almost right. Notcurses is nothing less than a sea change for Windows console app developers.
  • Non-interpolative scaling suitable for e.g. pixel art.
  • Scrolling on the standard plane for construction of CLI-like programs in Rendered Mode.
  • New nctree, ncprogbar, and nctabbed widgets, the latter from @MasFlam.
  • Much-improved Python wrappers from @igo95862.
  • Rust wrappers taken to an entirely new level by @joseluis.
  • Construction of ncvisuals via various RGB formats, as requested by @kaniini .
  • libnotcurses-core has been split out from libnotcurses, allowing binaries to be linked without the multimedia stack, even if the installed Notcurses was built with a multimedia stack.
  • Distinct rendering contexts are available as piles; there are no concurrency hazards shared between piles.
  • The new notcurses-info binary provides a quick summation and exercise of terminal capabilities.
  • The new ncls binary lists and renders files.
  • notcurses-view has been renamed to ncplayer, and now accepts -n for non-interpolative scaling, and -a to alpha-mask a color.

...but this is only a small sample of the expansions, improvements, and achievements of Notcurses 3.0.0! Give it a test drive. Write some apps around it. Hack. May one hundred flowers bloom! 百花齊放,百家爭鳴

868 issues were closed via 7.7K+ commits in this release cycle.

what they're saying

the south's got somethin' to say

The first time I ran notcurses’ “jungle” demo in foot nothing happened. Turned out to be a bug in foot’s handling of color palette changes. This phenomenon has kept repeating itself; notcurses using features in novel ways unearths terminal emulator bugs. notcurses-demo turns your terminal emulator into a 90s computer demo—and that’s a good thing." —Daniel Eklöf (@dnkl), author of foot

I believe notcurses forms an excellent foundation for the next generation of terminal applications, with rich support for graphics and input, and lots of effort into graceful degradation for legacy terminals. I recommend anyone starting to build a terminal application in 2021 consider it as the foundation layer. —Kovid Goyal (@kovidgoyal), author of Kitty

Terminals have long been seen as an old era tech, and so, many applications retain the behavior of those apps and standard being even older than I am. Notcurses not so much! I am glad notcurses is trying to break out and breathe fresh air and new life into our beloved eco system again with many features the young generation of users and developers want and will expect. A huge thanks to Nick Black for helping us move forward in the terminal land. The notcurses demos are mind blowing and inspiring of what modern terminal applications can be capable of and I recommend anyone asking me what to use when building terminal apps to give notcurses a try. Hack on! —Christian Parpart (@christianparpart), author of Contour

The demo is great, and looks like it can push out enough detail to pull off silliness like pushing an SNES game’s output straight to the console. What might be the most impressive element of the library is that while it can blit high res graphics through a terminal emulator with graphical support, it will also work on the basic Linux console, with no graphical system installed, by using some very old tricks. I know what you’re wondering: That’s all well and good, but can it run Doom? Yep. —Hackaday 2021-05-20 "Terminal Magic with Notcurses"

Just ran notcurses-demo. Mind blowing. Is it even legal? —u/rmrfchik

gallery

Microsoft Terminal running ncneofetch

Two Microsoft Terminals run ncneofetch and ncplayer. Microsoft Terminal does not (yet) support bitmap graphics, nor Unicode 13 (necessary for the sexblitter), so here we see the quadblitter.

Microsoft Terminal running ncneofetch

Terminal.App, iTerm2, and Kitty 0.21.2 on macOS. iTerm2 does not yet support partially-transparent bitmap graphics, but its author is working on it. Terminal.App is a somewhat lackluster program.

Microsoft Terminal running ncneofetch

WezTerm runs ncneofetch while ssh'd into a FreeBSD 13 virtual machine. On the left, Kitty 0.21.3 churns through the [xray] phase of notcurses-demo.

the new CLI mode

In the beginning, there was struct notcurses for a "Rendered Mode" context, and struct ncdirect for a "Direct Mode" context. Among other differences, output never resulted in true, externally-meaningful screen scrolling in Rendered Mode (you could fake it internally with a scrolling plane, but this wouldn't e.g. scroll existing content you hadn't generated). Rendered Mode was geared towards fullscreen TUIs, and free-scrolling CLIs were only possible in Direct Mode.

Well, Direct Mode allows other programs to generate output, and thus never knows the screen contents, eliminating most optimizations. The two APIs diverged extensively, and you basically couldn't use any of the Notcurses widgets etc. with a CLI program. @klamonte's "The Command Line vs. the Terminal" speaks truth:

...users really need the "command line", but not so much the "terminal". What do I mean by that? By "command line", I mean pipe-able (composable) programs that read from stdin, write to stdout, and do a sequence of command / response / command / response. Just like the "read-eval-print-loop" (REPL) used by Lisp, Python, and many other programming languages.

We needed to unleash the full power of Rendered Mode on CLI-style applications. Hence "CLI mode", which uses the struct notcurses context. It ought be initialized with NCOPTION_NO_CLEAR_BITMAPS (to leave previous output unmolested), NCOPTION_PRESERVE_CURSOR (to start wherever the program was launched), and NCOPTION_NO_ALTERNATE_SCREEN (hopefully obvious). Upon acquiring the context, invoke ncplane_set_scrolling() on the standard plane (it was not previously possible to enable scrolling on the standard plane). Congratulations, you now have a CLI app. You must continue to invoke notcurses_render() or some other rasterizer to generate output.

I'm not yet satisfied with the CLI mode (see "Notcurses IV" below), but think its shortcomings can be remedied without any API/ABI breakage. In particular, it's currently too difficult to simply stream data and ensure you have it all in your scrollback history, due to all those manual render/raster calls. This will be improved.

porting api2 applications to api3

let the breakage begin!

If you've kept your application up to date through the 2.x.x development cycle, updating to eliminate deprecation warnings, congratulations! 3.0.0 introduces no user-visible changes relative to 2.4.x, save the removal of long-deprecated material. Some functions which were previously symbols in the library are now static inline header-only implementations, and a recompile will be sufficient to get you linked and going. A recompile is in any case necessary due to struct changes and other ABI variations.

Let's assume the worst plausible case: you have a program built against Notcurses 2.0.0, and want to build it against 3.0.0, retaining prior behavior. You'll probably need to make a change or two, most of them insubstantial:

  • It is no longer possible to have multiple contexts open concurrently, including a rendered mode notcurses context alongside a direct mode ncdirect context. If you were doing this to handle input, manage your cursor and use an ncreader. If you were doing this to run a subprocess, use an ncsubproc.
  • ncvisual_render() has been dropped in favor of ncvisual_blit(). The latter responds to a NULL target plane by creating a new pile, rather than creating a new plane in the standard pile. To get the old behavior, pass the standard plane as n in ncvisual_options, and add NCVISUAL_OPTION_CHILDPLANE to flags.
  • Removed unsafe cell_fchannel(), cell_bchannel(), cell_set_fchannel(), and cell_set_bchannel(). If you were using these, the safe parts can be accomplished with other existing functions. cell_width() has been replaced by nccell_cols(), and no longer requires an ncplane* argument. All other functions starting with cell now start with nccell, and the cell type is now nccell. Macros starting with CELL now start with NCCELL.
  • All functions starting with channel now start with ncchannel, and the channel/channels types are now ncchannel/ncchannels. Macros beginning with CHANNEL now begin with NCCHANNEL.
  • All functions starting with palette now start with ncpalette. The palette256 type has been renamed ncpalette.
  • ncvisual_subtitle() has been replaced with ncvisual_subtitle_plane(), and returns a new ncplane*.
  • NCSTYLE_REVERSE has been eliminated. ncchannels_reverse() is available to reverse the fore- and background of an ncchannels variable, but is not a direct replacement.
  • NCSTYLE_DIM has been eliminated. The same effect can be more portably achieved with channel RGB.
  • NCSTYLE_BLINK has been eliminated. The same effect can be more portably achieved with ncplane_pulse().
  • renderfp has been removed from notcurses_options, with no replacement functionality.
  • ncplane_rgba() has been renamed ncplane_as_rgba().
  • ncvisual_geom() has been reworked to use the new ncvgeom struct.
  • ncplane_align() has been replaced by ncplane_halign().
  • notcurses_stats() traded the const modifier on its notcurses* parameter for elimination of data races.
  • ncplane_qrcode() no longer accepts a blitter specification, since only NCBLIT_2x1 works.
  • All ncplane_put*() functions now return the number of columns output, as documented (some were erroneously returning the number of bytes output).
  • ncdirect_styles_{set, on, off}() have been renamed ncdirect_{set, on, off}_styles().
  • ncdirect_raster_frame() no longer requires blitter nor scale.
  • ncdirect_{fg, bg}_{default, rgb}() have been renamed ncdirect_set_{fg, bg}_{default, rgb}().
  • ncplane_options lost its horiz union, which was replaced with its x member.
  • There were many changes to Direct Mode, but I've not bothered listing them here because you ought be using CLI mode.

what's coming in Notcurses IV

good news from home! I've got big plans for Notcurses IV, most of them regarding sweet, sweet perf.

the endankification of CLI mode

The CLI mode came up kinda late in Notcurses design, well into the 2.x cycle. It became clear that streaming stdio CLIs are more frequently authored than high-performance, non-scrolling TUIs. By allowing the standard plane to be placed into scrolling mode, this functionality was bolted on. It's not where I want it. You currently have to manage all the scrolling yourself, which gets pretty hairy once you bring multiple planes into the picture. You furthermore need decide when to render, and no one wants to think about that. Render insufficiently frequently, and data will be lost to virtual internal scrolling; render every line, and you do a lot of extra work (CLI mode doesn't yet always take advantage of hardware scrolling). I intend to make fuller use of hardware scrolling so that rendering can take place on every virtual scroll event, for full fidelity, full performance, and no developer effort.

wholesale emancipation from terminfo

Notcurses has made use of Terminfo (as distributed with NCURSES) since its inception. The limitations of that library have become more and more apparent, and with Notcurses now using direct terminal queries wherever possible, it's time to consider ditching libterminfo (and perhaps even the TERM environment variable, which can be—and all too often is—incorrect). Terminfo doesn't cover a substantial amount of behavior Notcurses actively employs, from bitmap graphics to extended input protocols. Many terminals in any case don't bother putting together an accurate terminfo database entry, simply calling themselves xterm or xterm-256color and approximating XTerm to one degree or another. Let us cast off this taint, and become taintless.

If you're a terminal author, I encourage you to implement the XTGETTCAP and XTVERSION control sequences.

mosaicworld

It was obvious from the very first days of bitmap graphics support that breaking an image into cell-sized fragments offered many significant advantages. Performance issues of some terminals when making use of hundreds of independent graphics prevented me from immediately pursuing this implementation, but it's time to use it where possible. Mosaics will improve performance when interacting with other planes, improve reliability when the screen geometry changes, eliminate problems when a sprixel moves partially off-screen, and drastically simplify the logic of bitmapped graphics atop a terminal's matrix of cells.

better and faster sixel quantization

My quantization algorithm is slower than libsixel, and yet manages to also produce lower-quality encodings (on the plus side, it's not known to be riddled with major security problems). I look forward to significant improvements in both regards, certainly to the level of libsixel. It's likely that we'll want to integrate some dithering capabilities as well. Here's another area where mosaics have benefits: when your sixels are only as large as a single cell, you're less likely to suffer from quantization effects (at the cost, of course, of bandwidth).

When using the Kitty graphics protocol, Notcurses is unparalleled.

a replacement for libsixel

The maintainer of libsixel has been missing for years. @ctrlcctrlv roped me into comaintainership of a fork earlier this year, and we've been patching up the worst of things, but it's a fundamentally insecure API. I'll be wrapping the Notcurses sixel code with a libsixel-like API, one existing applications can move to with simple changes (essentially, a length needs be passed in along with the source buffer).

Notcurses-within-Notcurses and Background-Stay-Resident terminal "widgets"

This is some Deeper Fucking Magic from Beyond the Dawn of Time. Stay tuned to see something fundamentally new, if I can pull it off.

optimized PseudoColor palettes derived from dynamic RGB DirectColor content

It's oftentimes (almost always, actually) the case that a palette-indexed encoding of a given frame can require less bandwidth than a pure RGB version, yet encode all colors losslessly (assuming it can freely fall back to RGB). Notcurses currently always uses RGB when it is available, and maps RGB to palette-indexed terminals in a naive fashion. We can instead come up with an optimal palette on the fly, so long as it can be done with sufficient performance (i.e. median cut on all cells of every frame is not going to cut it). Suitable algorithms seem pretty obvious, if perhaps non-trivial. Implement this to save bandwidth (the first-order determinant of overall performance), and also to improve image quality when rendering to non-RGB terminals, especially color-starved terminals like the Linux console.

support for Linux's Direct Rendering Infrastructure

Just when I added Linux framebuffer support, it gets well and truly obsoleted. DRM is the (relatively) new hotness. I started in on some support during this development cycle, but it proved an unexpectedly tremendous pain in my ass, and was punted down the road.

more of the usual bullshit

  • more commit messages making esoteric references to the literature of High Modernism
  • more Ice Cube videos embedded into GitHub issues
  • more ballin'
  • yes of course i'm going to make a dank hype video for this release, gimme a week/fortnight

in the 'A'

A-T-L
That's my City in the Forest, the Capital of the New South,
home to Georgia Tech, Home Park, and the Danktower.
The South's got somethin' to say. ATL, baby, ATL!
🖤 dank 2021-12-01