diff --git a/NEWS.md b/NEWS.md index fb42b2b72..9e3b772fb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,17 @@ This document attempts to list user-visible changes and any major internal rearrangements of Notcurses. -* 2.4.6 (not yet released) **"In the A"** +* 3.0.0 (not yet released) **"In the A"** + * Made the ABI changes that have been planned/collected during 2.x + development. This primarily involved removing deprecated functions, + and making some `static inline` (and thus no longer linkable symbols). + There have been a few small renamings (i.e. `ncplane_pixelgeom()` to + `ncplane_pixel_geom()`) for purposes of regularity. The only thing removed + without an obvious replacement is the `renderfp` field of + `notcurses_options`, for which I make no apology. If you've been avoiding + deprecated functionality, ABI3 ought require small changes, if any. + +* 2.4.6 (not yet released) * Features 1, 2, and 8 of the Kitty keyboard protocol are now supported. This provides much more detailed and fine-grained keyboard reports, including key repeat and release events, and modifier events (i.e. pressing Shift by @@ -13,6 +23,20 @@ rearrangements of Notcurses. DA1 response will be considered as claiming support for Sixel with 256 color registers. If you're a terminal author, please do `XTSMGRAPHICS`. Actually, please implement the vastly superior Kitty graphics protocol. + * `ncvisualplane_create()` now allows for a new pile to be created, by + passing a `NULL` ancestor `ncplane` in `vopts`. The first argument is + now a `struct notcurses*` rather than a `struct ncplane*`. + * `ncvisual_render()` has been deprecated in favor of the new function + `ncvisual_blit()`. When a `NULL` `vopts->n` is passed to `ncvisual_blit()`, + a new plane is created (as it was in `ncvisual_render()`, but that plane + is the root of a new pile, rather than a child of the standard plane. + The only tricky conversion is if you previously had `vopts.n` as `NULL`, + and were not using `NCVISUAL_OPTION_CHILDPLANE` (or were passing `NULL` + as `vopts`). This would result in a new plane bound to the standard plane + with `ncvisual_render()`, but with `ncvisual_blit()` it will create a new + pile. To keep the behavior, explicitly pass the standard plane as + `vopts->n`, and include `NCVISUAL_OPTION_CHILDPLANE` in `vopts->flags`. + All other cases will continue to work as they did before. * 2.4.5 (2021-10-06) * The poorly-considered function `ncplane_boundlist()`, added in 2.3.17, has diff --git a/USAGE.md b/USAGE.md index 04bd64151..c2ea59499 100644 --- a/USAGE.md +++ b/USAGE.md @@ -3308,17 +3308,30 @@ struct ncplane* ncvisual_subtitle(struct ncplane* parent, And finally, the `ncvisual` can be blitted to one or more `ncplane`s: ```c -// Render the decoded frame to the specified ncplane. If one is not provided, -// one will be created, having the exact size necessary to display the visual. +// Render the decoded frame according to the provided options (which may be +// NULL). The plane used for rendering depends on vopts->n and vopts->flags. +// If NCVISUAL_OPTION_CHILDPLANE is set, vopts->n must not be NULL, and the +// plane will always be created as a child of vopts->n. If this flag is not +// set, and vopts->n is NULL, a new plane is created as root of a new pile. +// If the flag is not set and vopts->n is not NULL, we render to vopts->n. // A subregion of the visual can be rendered using 'begx', 'begy', 'lenx', and // 'leny'. Negative values for 'begy' or 'begx' are an error. It is an error to -// specify any region beyond the boundaries of the frame. Returns the -// (possibly newly-created) plane to which we drew. -struct ncplane* ncvisual_render(struct notcurses* nc, struct ncvisual* ncv, - const struct ncvisual_options* vopts) +// specify any region beyond the boundaries of the frame. Returns the (possibly +// newly-created) plane to which we drew. Pixels may not be blitted to the +// standard plane. +struct ncplane* ncvisual_blit(struct notcurses* nc, struct ncvisual* ncv, + const struct ncvisual_options* vopts); + +// Create a new plane as prescribed in opts, either as a child of 'vopts->n', +// or the root of a new pile if 'vopts->n' is NULL (or 'vopts' itself is NULL). +// Blit 'ncv' to the created plane according to 'vopts'. If 'vopts->n' is +// non-NULL, NCVISUAL_OPTION_CHILDPLANE must be supplied. +static inline struct ncplane* +ncvisualplane_create(struct notcurses* nc, const struct ncplane_options* opts, + struct ncvisual* ncv, struct ncvisual_options* vopts); // decode the next frame ala ncvisual_decode(), but if we have reached the end, -// rewind to the first frame of the ncvisual. a subsequent `ncvisual_render()` +// rewind to the first frame of the ncvisual. a subsequent `ncvisual_blit()` // will render the first frame, as if the ncvisual had been closed and reopened. // the return values remain the same as those of ncvisual_decode(). int ncvisual_decode_loop(struct ncvisual* nc); diff --git a/doc/man/man3/notcurses.3.md b/doc/man/man3/notcurses.3.md index 69824883e..52bcc57fd 100644 --- a/doc/man/man3/notcurses.3.md +++ b/doc/man/man3/notcurses.3.md @@ -89,7 +89,7 @@ Following initialization, a single ncplane exists, the "standard plane" (see **notcurses_stdplane(3)**). This plane cannot be destroyed nor manually resized, and is always exactly as large as the screen (if run without a TTY, the "screen" is assumed to be 80x24 cells). Further ncplanes can be created with -**ncplane_new(3)**. A total z-ordering always exists on the set of ncplanes, +**ncplane_create(3)**. A total z-ordering always exists on the set of ncplanes, and new ncplanes are placed at the top of the z-buffer. Ncplanes can be larger, smaller, or the same size as the physical screen, and can be placed anywhere relative to it (including entirely off-screen). Ncplanes are made up of diff --git a/doc/man/man3/notcurses_visual.3.md b/doc/man/man3/notcurses_visual.3.md index a36cba34d..b7022c12a 100644 --- a/doc/man/man3/notcurses_visual.3.md +++ b/doc/man/man3/notcurses_visual.3.md @@ -75,7 +75,9 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*); **int ncvisual_decode_loop(struct ncvisual* ***ncv***);** -**struct ncplane* ncvisual_render(struct notcurses* ***nc***, struct ncvisual* ***ncv***, const struct ncvisual_options* ***vopts***);** +**struct ncplane* ncvisual_blit(struct notcurses* ***nc***, struct ncvisual* ***ncv***, const struct ncvisual_options* ***vopts***);** + +**static inline struct ncplane* ncvisualplane_create(struct notcurses* ***nc***, const struct ncplane_options* ***opts***, struct ncvisual* ***ncv***, struct ncvisual_options* ***vopts***);** **int ncvisual_simple_streamer(struct ncplane* ***n***, struct ncvisual* ***ncv***, const struct timespec* ***disptime***, void* ***curry***);** @@ -93,7 +95,7 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*); **int ncvisual_set_yx(const struct ncvisual* ***n***, int ***y***, int ***x***, uint32_t ***pixel***);** -**struct ncplane* ncvisual_subtitle(struct ncplane* ***parent***, const struct ncvisual* ***ncv***);** +**struct ncplane* ncvisual_subtitle_plane(struct ncplane* ***parent***, const struct ncvisual* ***ncv***);** **int notcurses_lex_scalemode(const char* ***op***, ncscale_e* ***scaling***);** @@ -124,7 +126,7 @@ Once the visual is loaded, it can be transformed using **ncvisual_rotate**, **ncvisual_resize**, and **ncvisual_resize_noninterpolative**. These are persistent operations, unlike any scaling that takes place at render time. If a subtitle is associated with the frame, it can be acquired with -**ncvisual_subtitle**. **ncvisual_resize** uses the media layer's best scheme +**ncvisual_subtitle_plane**. **ncvisual_resize** uses the media layer's best scheme to enlarge or shrink the original data, typically involving some interpolation. **ncvisual_resize_noninterpolative** performs a naive linear sampling, retaining only original colors. @@ -152,11 +154,12 @@ glyphs within this region are those used by the specified blitter. **ncvisual_rotate** executes a rotation of ***rads*** radians, in the clockwise (positive) or counterclockwise (negative) direction. -**ncvisual_subtitle** will return a UTF-8-encoded subtitle corresponding to -the current frame if such a subtitle was decoded. Note that a subtitle might -be returned for multiple frames, or might not. +**ncvisual_subtitle_plane** returns a **struct ncplane** suitable for display, +if the current frame had such a subtitle. Note that the same subtitle might +be returned for multiple frames, or might not. It is atypical for all frames +to have subtitles. Subtitles can be text or graphics. -**ncvisual_render** blits the visual to an **ncplane**, based on the contents +**ncvisual_blit** draws the visual to an **ncplane**, based on the contents of its **struct ncvisual_options**. If ***n*** is not **NULL**, it specifies the plane on which to render, and ***y***/***x*** specify a location within that plane. Otherwise, a new plane will be created, and placed at ***y***/***x*** relative to @@ -270,7 +273,7 @@ information. Some terminals support pixel-based output via one of a number of protocols. **NCBLIT_PIXEL** has some stringent requirements on the type of planes it can -be used with; it is usually best to let **ncvisual_render** create the backing +be used with; it is usually best to let **ncvisual_blit** create the backing plane by providing a **NULL** value for **n**. If you must bring your own plane, it must be perfectly sized for the bitmap (i.e. large enough, and not more than a full cell larger in either dimension--the bitmap, always placed at @@ -304,12 +307,12 @@ that the entire file is properly-formed. failure. It is only necessary for multimedia-based visuals. It advances one frame for each call. **ncvisual_decode_loop** has the same return values: when called following decoding of the last frame, it will return 1, but a subsequent -**ncvisual_render** will return the first frame. +**ncvisual_blit** will return the first frame. **ncvisual_from_plane** returns **NULL** if the **ncvisual** cannot be created and bound. This is usually due to illegal content in the source **ncplane**. -**ncvisual_render** returns **NULL** on error, and otherwise the plane to +**ncvisual_blit** returns **NULL** on error, and otherwise the plane to which the visual was rendered. If **opts->n** is provided, this will be **opts->n**. Otherwise, a plane will be created, perfectly sized for the visual and the specified blitter. @@ -328,7 +331,8 @@ aspect-preserving **NCBLIT_2x1** will be returned. If sextants are available Multimedia decoding requires that Notcurses be built with either FFmpeg or OpenImageIO support. What formats can be decoded is totally dependent on the linked library. OpenImageIO does not support subtitles. Functions requiring -a multimedia backend include **ncvisual_from_file** and **ncvisual_subtitle**. +a multimedia backend include **ncvisual_from_file** and +**ncvisual_subtitle_plane**. Sixel documentation can be found at [Dankwiki](https://nick-black.com/dankwiki/index.php?title=Sixel). Kitty's graphics protocol is specified in [its documentation](https://sw.kovidgoyal.net/kitty/graphics-protocol.html). @@ -365,7 +369,7 @@ sprixel cannot be accessed. **ncvisual_rotate** currently supports only **M_PI**/2 and -**M_PI**/2 radians for **rads**, but this will change soon. -**ncvisual_render** should be able to create new planes in piles other than +**ncvisual_blit** should be able to create new planes in piles other than the standard pile. This ought become a reality soon. **ncvisual_stream** currently requires a multimedia engine, which is silly. @@ -374,7 +378,7 @@ This will change in the near future. Sprixels interact poorly with multiple planes, and such usage is discouraged. This situation might improve in the future. -Multiple threads may not currently call **ncvisual_render** concurrently +Multiple threads may not currently call **ncvisual_blit** concurrently using the same **ncvisual**, even if targeting distinct **ncplane**s. This will likely change in the future.