2020-06-03 20:32:27 +00:00
% notcurses_visual(3)
2020-01-02 02:23:11 +00:00
% nick black < nickblack @ linux . com >
2021-06-12 21:27:28 +00:00
% v2.3.4
2020-01-02 02:23:11 +00:00
# NAME
2020-06-03 20:32:27 +00:00
notcurses_visual - notcurses multimedia
2020-01-02 02:23:11 +00:00
# SYNOPSIS
2020-04-19 22:46:32 +00:00
**#include < notcurses / notcurses . h > **
2020-01-02 02:23:11 +00:00
2020-01-04 07:37:55 +00:00
```c
typedef enum {
NCSCALE_NONE,
NCSCALE_SCALE,
NCSCALE_STRETCH,
2020-12-25 23:25:44 +00:00
NCSCALE_NONE_HIRES,
NCSCALE_SCALE_HIRES,
2020-01-04 07:37:55 +00:00
} ncscale_e;
2020-01-14 20:50:17 +00:00
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
typedef enum {
2020-07-25 22:36:15 +00:00
NCBLIT_DEFAULT, // let the ncvisual pick
2020-10-25 22:49:57 +00:00
NCBLIT_1x1, // spaces only
NCBLIT_2x1, // halves + 1x1
NCBLIT_2x2, // quadrants + 2x1
NCBLIT_3x2, // sextants + 1x1
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille)
2021-02-25 07:03:01 +00:00
NCBLIT_PIXEL, // pixel graphics
2021-03-14 07:49:18 +00:00
NCBLIT_4x1, // four vertical levels, (plots)
NCBLIT_8x1, // eight vertical levels, (plots)
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
} ncblitter_e;
2021-06-08 05:09:15 +00:00
#define NCVISUAL_OPTION_NODEGRADE 0x0001ull
#define NCVISUAL_OPTION_BLEND 0x0002ull
#define NCVISUAL_OPTION_HORALIGNED 0x0004ull
#define NCVISUAL_OPTION_VERALIGNED 0x0008ull
#define NCVISUAL_OPTION_ADDALPHA 0x0010ull
#define NCVISUAL_OPTION_CHILDPLANE 0x0020ull
#define NCVISUAL_OPTION_NOINTERPOLATE 0x0040ull
2020-05-29 05:24:34 +00:00
struct ncvisual_options {
struct ncplane* n;
ncscale_e scaling;
2021-02-08 03:10:41 +00:00
int y, x;
2020-05-29 05:24:34 +00:00
int begy, begx; // origin of rendered section
int leny, lenx; // size of rendered section
2020-10-25 22:49:57 +00:00
ncblitter_e blitter; // glyph set to use
2020-05-29 18:53:53 +00:00
uint64_t flags; // bitmask over NCVISUAL_OPTION_*
2021-04-10 14:17:41 +00:00
uint32_t transcolor; // use this color for ADDALPHA
2020-05-29 05:24:34 +00:00
};
2020-05-29 05:47:53 +00:00
typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
2020-01-04 07:37:55 +00:00
```
2020-11-06 21:10:58 +00:00
**struct ncvisual* ncvisual_from_file(const char* ** *file***);**
2020-01-04 07:37:55 +00:00
2020-11-06 21:10:58 +00:00
**struct ncvisual* ncvisual_from_rgba(const void* ** *rgba***, int ** *rows***, int ** *rowstride***, int ** *cols***);**
2020-05-04 08:55:10 +00:00
2021-06-19 08:36:59 +00:00
**struct ncvisual* ncvisual_from_rgb_packed(const void* ** *rgba***, int ** *rows***, int ** *rowstride***, int ** *cols***, int ** *alpha***);**
**struct ncvisual* ncvisual_from_rgb_loose(const void* ** *rgba***, int ** *rows***, int ** *rowstride***, int ** *cols***, int ** *alpha***);**
2020-11-06 21:10:58 +00:00
**struct ncvisual* ncvisual_from_bgra(const void* ** *bgra***, int ** *rows***, int ** *rowstride***, int ** *cols***);**
2020-05-04 08:55:10 +00:00
2020-11-06 21:10:58 +00:00
**struct ncvisual* ncvisual_from_plane(struct ncplane* ** *n***, ncblitter_e ** *blit***, int ** *begy***, int ** *begx***, int ** *leny***, int ** *lenx***);**
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
2021-04-18 03:11:11 +00:00
**int ncvisual_blitter_geom(const struct notcurses* ** *nc***, const struct ncvisual* ** *n***, const struct ncvisual_options* ** *vopts***, int* ** *y***, int* ** *x***, int* ** *scaley***, int* ** *scalex***, ncblitter_e* ** *blitter***);**
2020-05-07 00:10:01 +00:00
2020-11-06 21:10:58 +00:00
**void ncvisual_destroy(struct ncvisual* ** *ncv***);**
2020-01-04 07:37:55 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_decode(struct ncvisual* ** *ncv***);**
2020-01-04 07:37:55 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_decode_loop(struct ncvisual* ** *ncv***);**
2020-10-19 22:42:09 +00:00
2020-11-06 21:10:58 +00:00
**struct ncplane* ncvisual_render(struct notcurses* ** *nc***, struct ncvisual* ** *ncv***, const struct ncvisual_options* ** *vopts***);**
2020-01-04 07:37:55 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_simple_streamer(struct ncplane* ** *n***, struct ncvisual* ** *ncv***, const struct timespec* ** *disptime***, void* ** *curry***);**
2020-01-04 07:37:55 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_stream(struct notcurses* ** *nc***, struct ncvisual* ** *ncv***, float ** *timescale***, streamcb ** *streamer***, const struct ncvisual_options* ** *vopts***, void* ** *curry***);**
2020-01-04 07:37:55 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_rotate(struct ncvisual* ** *n***, double ** *rads***);**
2020-05-04 04:51:42 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_resize(struct ncvisual* ** *n***, int ** *rows***, int ** *cols***);**
2020-06-06 09:11:45 +00:00
2021-06-08 20:32:03 +00:00
**int ncvisual_resize_noninterpolative(struct ncvisual* ** *n***, int ** *rows***, int ** *cols***);**
2021-04-18 04:16:46 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_polyfill_yx(struct ncvisual* ** *n***, int ** *y***, int ** *x***, uint32_t ** *rgba***);**
2020-06-06 09:11:45 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_at_yx(const struct ncvisual* ** *n***, int ** *y***, int ** *x***, uint32_t* ** *pixel***);**
2020-06-06 09:11:45 +00:00
2020-11-06 21:10:58 +00:00
**int ncvisual_set_yx(const struct ncvisual* ** *n***, int ** *y***, int ** *x***, uint32_t ** *pixel***);**
2020-06-07 01:38:05 +00:00
2020-11-06 21:10:58 +00:00
**char* ncvisual_subtitle(const struct ncvisual* ** *ncv***);**
2020-05-04 04:51:42 +00:00
2020-11-06 21:10:58 +00:00
**int notcurses_lex_scalemode(const char* ** *op***, ncscale_e* ** *scaling***);**
2020-07-20 01:53:01 +00:00
2020-11-06 21:10:58 +00:00
**const char* notcurses_str_scalemode(ncscale_e ** *scaling***);**
2020-07-20 01:53:01 +00:00
2020-11-06 21:10:58 +00:00
**int notcurses_lex_blitter(const char* ** *op***, ncblitter_e* ** *blitter***);**
2020-07-20 01:53:01 +00:00
2020-11-06 21:10:58 +00:00
**const char* notcurses_str_blitter(ncblitter_e ** *blitter***);**
2020-07-19 06:54:53 +00:00
2020-12-25 22:37:27 +00:00
**ncblitter_e ncvisual_media_defblitter(const struct notcurses ** *nc***, ncscale_e ** *scaling***);**
2020-09-06 16:56:16 +00:00
2021-02-15 08:32:13 +00:00
**int ncplane_qrcode(struct ncplane* ** *n***, int* ** *ymax***, int* ** *xmax***, const void* ** *data***, size_t ** *len***)**
2020-01-02 02:23:11 +00:00
# DESCRIPTION
2020-05-29 05:47:53 +00:00
An **ncvisual** is a virtual pixel framebuffer. They can be created from
RGBA/BGRA data in memory (**ncvisual_from_rgba**/**ncvisual_from_bgra**),
or from the content of a suitable **ncplane** (**ncvisual_from_ncplane**).
If Notcurses was built against a multimedia engine (FFMpeg or OpenImageIO),
image and video files can be loaded into visuals using
**ncvisual_from_file**. **ncvisual_from_file** discovers the container
and codecs, but does not verify that the entire file is well-formed.
2020-05-29 12:39:11 +00:00
**ncvisual_decode** ought be invoked to recover subsequent frames, once
2020-10-20 23:35:16 +00:00
per frame. **ncvisual_decode_loop** will return to the first frame,
as if **ncvisual_decode** had never been called.
2020-05-29 05:47:53 +00:00
2021-04-18 04:16:46 +00:00
Once the visual is loaded, it can be transformed using **ncvisual_rotate** ,
2021-06-08 20:32:03 +00:00
**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
to enlarge or shrink the original data, typically involving some interpolation.
**ncvisual_resize_noninterpolative** performs a naive linear sampling,
retaining only original colors.
2020-05-29 05:47:53 +00:00
**ncvisual_from_rgba** and **ncvisual_from_bgra** both require a number of
2021-05-04 17:55:36 +00:00
***rows***, a number of image columns **cols** , and a virtual row length of
***rowstride*** / 4 columns. The input data must provide 32 bits per pixel, and
thus must be at least ** *rowstride*** * * **rows*** bytes, of which a
***cols*** * * **rows*** * 4-byte subset is used. It is not possible to * *mmap(2)** an image
2020-05-29 05:47:53 +00:00
file and use it directly--decompressed, decoded data is necessary. The
resulting plane will be ceil(**rows**/2) rows, and **cols** columns.
2021-06-19 08:36:59 +00:00
**ncvisual_from_rgb_packed** performs the same using 3-byte RGB source data.
**ncvisual_from_rgb_loose** uses 4-byte RGBx source data. Both will fill in
the alpha component of every target pixel with the specified **alpha** .
2021-05-04 17:55:36 +00:00
**ncvisual_from_plane** requires specification of a rectangle via ** *begy***,
2021-06-19 08:36:59 +00:00
***begx***, ** *leny***, and ** *lenx***, and also a blitter. The only valid
glyphs within this region are those used by the specified blitter.
2020-05-07 00:10:01 +00:00
2021-05-04 17:55:36 +00:00
**ncvisual_rotate** executes a rotation of ** *rads*** radians, in the clockwise
2020-06-03 16:22:46 +00:00
(positive) or counterclockwise (negative) direction.
2020-05-04 04:51:42 +00:00
2020-05-04 04:56:52 +00:00
**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.
2020-06-05 12:05:02 +00:00
**ncvisual_render** blits the visual to an **ncplane** , based on the contents
2021-05-04 17:55:36 +00:00
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
the rendering area. ** *begy***/***begx*** specify the upper left corner of a
subsection of the **ncvisual** to render, while ** *leny***/***lenx*** specify the
geometry of same. ** *flags*** is a bitfield over:
2020-06-05 12:05:02 +00:00
* **NCVISUAL_OPTION_NODEGRADE** If the specified blitter is not available, fail rather than degrading.
2021-06-10 07:02:30 +00:00
* **NCVISUAL_OPTION_BLEND**: Render with **NCALPHA_BLEND** . Not available with
2021-06-08 07:44:30 +00:00
**NCBLIT_PIXEL** when using Sixel graphics. When used with **NCBLIT_PIXEL** when
using Kitty graphics, the alpha channel is divided by 2 for each pixel.
2021-04-18 03:11:11 +00:00
* **NCVISUAL_OPTION_HORALIGNED**: Interpret ** *x*** as an **ncalign_e** .
* **NCVISUAL_OPTION_VERALIGNED**: Interpret ** *y*** as an **ncalign_e** .
2021-05-04 17:55:36 +00:00
* **NCVISUAL_OPTION_ADDALPHA**: Interpret the lower 24 bits of ** *transcolor***
as a transparent color.
* **NCVISUAL_OPTION_CHILDPLANE**: Make a new plane, as a child of ** *n***.
2021-04-18 03:11:11 +00:00
**ncvisual_blitter_geom** allows the caller to determine any or all of the
visual's pixel geometry, the blitter to be used, and that blitter's scaling
in both dimensions. Any but the first argument may be **NULL** .
2020-06-05 12:05:02 +00:00
2021-02-15 08:32:13 +00:00
**ncplane_qrcode** draws an ISO/IEC 18004:2015 QR Code for the **len** bytes of
**data** using **NCBLIT_2x1** (this is the only blitter that will work with QR
Code scanners, due to its 1:1 aspect ratio).
2021-03-25 23:57:35 +00:00
# OPTIONS
2021-05-04 17:55:36 +00:00
***begy*** and ** *begx*** specify the upper left corner of the image to start
drawing. ** *leny*** and ** *lenx*** specify the area of the subimage drawn.
***leny*** and/or ** *lenx*** may be specified as a negative number to draw
2021-03-25 23:57:35 +00:00
through the bottom right corner of the image.
2021-05-04 17:55:36 +00:00
The ** *n*** field specifies the plane to use. If this is **NULL** , a new plane
2021-03-25 23:57:35 +00:00
will be created, having the precise geometry necessary to blit the specified
section of the image. This might be larger (or smaller) than the visual area.
2021-05-04 17:55:36 +00:00
***y*** and ** *x*** have different meanings depending on whether or not
***n*** is **NULL** . If not (drawing onto a preexisting plane), they specify
where in the plane to start drawing. If **n** was **NULL** (new plane), they
2021-06-11 21:28:27 +00:00
specify the origin of the new plane relative to the visible area. If the
2021-05-04 17:55:36 +00:00
***flags*** field contains **NCVISUAL_OPTION_HORALIGNED** , the ** *x*** parameter
is interpreted as an **ncalign_e** rather than an absolute position. If the
***flags*** field contains **NCVISUAL_OPTION_VERALIGNED** , the ** *y*** parameter
is interpreted as an **ncalign_e** rather than an absolute position. If the
***flags*** field contains **NCVISUAL_OPTION_CHILDPLANE** , ** *n*** must be
non-**NULL**, and the ** *x*** and ** *y*** parameters are interpreted relative
to that plane.
2021-03-25 23:57:35 +00:00
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
# BLITTERS
The different **ncblitter_e** values select from among available glyph sets:
* **NCBLIT_DEFAULT**: Let the **ncvisual** choose its own blitter.
2021-03-28 23:40:21 +00:00
* **NCBLIT_1x1**: Spaces only. Works in ASCII, unlike most other blitters.
2020-10-25 22:49:57 +00:00
* **NCBLIT_2x1**: Adds the half blocks (▄▀) to **NCBLIT_1x1** .
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
* **NCBLIT_2x2**: Adds left and right half blocks (▌▐) and quadrants (▖▗▟▙) to **NCBLIT_2x1** .
2020-10-25 22:49:57 +00:00
* **NCBLIT_3x2**: Adds sextants to **NCBLIT_1x1** .
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
* **NCBLIT_BRAILLE**: 4 rows and 2 columns of braille (⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿).
2021-03-28 23:40:21 +00:00
* **NCBLIT_PIXEL**: Adds pixel graphics (these also work in ASCII).
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
2021-03-14 07:49:18 +00:00
Two more blitters exist for plots, but are unsuitable for generic media:
* **NCBLIT_4x1**: Adds ¼ and ¾ blocks (▂▆) to **NCBLIT_2x1** .
* **NCBLIT_8x1**: Adds ⅛, ⅜, ⅝, and ⅞ blocks (▇▅▃▁) to **NCBLIT_4x1** .
2020-10-19 03:15:50 +00:00
**NCBLIT_4x1** and **NCBLIT_8x1** are intended for use with plots, and are
2021-01-31 23:04:49 +00:00
not really applicable for general visuals. **NCBLIT_BRAILLE** doesn't tend
to work out very well for images, but (depending on the font) can be very
good for plots.
2021-02-25 07:03:01 +00:00
A string can be transformed to a blitter with **notcurses_lex_blitter** ,
2021-02-27 21:05:19 +00:00
recognizing **ascii** , **half** , **quad** , **sex** , **fourstep** , **braille** ,
**eightstep**, and **pixel** . Conversion in the opposite direction is performed
with **notcurses_str_blitter** .
2021-02-25 07:03:01 +00:00
2021-01-31 23:04:49 +00:00
In the absence of scaling, for a given set of pixels, more rows and columns in
the blitter will result in a smaller output image. An image rendered with
**NCBLIT_1x1** will be twice as tall as the same image rendered with
**NCBLIT_2x1**, which will be twice as wide as the same image rendered with
**NCBLIT_2x2**. The same image rendered with **NCBLIT_3x2** will be one-third
as tall and one-half as wide as the original **NCBLIT_1x1** render (again, this
depends on **NCSCALE_NONE** ). If the output size is held constant (using for
instance **NCSCALE_SCALE_HIRES** and a large image), more rows and columns will
result in more effective resolution.
2021-02-25 07:03:01 +00:00
A string can be transformed to a scaling mode with **notcurses_lex_scalemode** ,
2021-06-08 20:32:03 +00:00
recognizing **stretch** , **scalehi** , **hires** , **scale** , and **none** .
Conversion in the opposite direction is performed with **notcurses_str_scalemode** .
2021-02-25 07:03:01 +00:00
2021-01-31 23:04:49 +00:00
Assuming a cell is twice as tall as it is wide, **NCBLIT_1x1** (and indeed
any NxN blitter) will stretch an image by a factor of 2 in the vertical
dimension. **NCBLIT_2x1** will not distort the image whatsoever, as it maps a
vector two pixels high and one pixel wide to a single cell. **NCBLIT_3x2** will
stretch an image by a factor of 1.5.
The cell's dimension in pixels is ideally evenly divisible by the blitter
geometry. If **NCBLIT_3x2** is used together with a cell 8 pixels wide and
14 pixels tall, two of the vertical segments will be 5 pixels tall, while one
will be 4 pixels tall. Such unequal distributions are more likely with larger
blitter geometries. Likewise, there are only ever two colors available to us in
a given cell. **NCBLIT_1x1** and **NCBLIT_2x2** can be perfectly represented
with two colors per cell. Blitters of higher geometry are increasingly likely
to require some degree of interpolation. Transparency is always honored with
complete fidelity.
Finally, rendering operates slightly differently when two planes have both been
blitted, and one lies atop the other. See **notcurses_render(3)** for more
information.
2020-10-19 03:15:50 +00:00
2021-02-27 19:52:16 +00:00
# PIXEL BLITTING
2021-04-24 06:28:23 +00:00
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
plane by providing a **NULL** value for **n** . If you must bring your own
2021-04-24 06:38:30 +00:00
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
the origin, must at least partially cover every cell of the plane). Using
**NCSCALE_STRETCH** means that the second condition will always be met. Once a
2021-04-24 07:46:19 +00:00
sprixel is blitted to a plane, cell methods (including cell blitting) may not
be used with it. Resizing the plane eliminates the sprixel, as does destroying
the plane. A sprixelated plane may be moved in all three dimensions,
duplicated, and reparented. The base cell of a sprixelated plane is
meaningless; if the sprixel is not an even multiple of the cell geometry, any
excess cell material is ignored during rendering.
2021-04-24 06:28:23 +00:00
Only one bitmap can be blitted onto a plane at a time (but multiple planes
with bitmaps may be visible); blitting a second to the same plane will delete
2021-04-24 07:46:19 +00:00
the original.
2021-03-16 23:24:39 +00:00
2020-01-02 02:23:11 +00:00
# RETURN VALUES
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
**ncvisual_from_file** returns an **ncvisual** object on success, or **NULL**
on failure. Success indicates that the specified **file** was opened, and
enough data was read to make a firm codec identification. It does not imply
2020-08-24 05:23:35 +00:00
that the entire file is properly-formed.
**ncvisual_decode** returns 0 on success, or 1 on end of file, or -1 on
failure. It is only necessary for multimedia-based visuals. It advances one
2020-10-20 23:35:16 +00:00
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.
2020-04-24 07:17:34 +00:00
2020-05-07 00:10:01 +00:00
**ncvisual_from_plane** returns **NULL** if the **ncvisual** cannot be created
and bound. This is usually due to illegal content in the source **ncplane** .
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
**ncvisual_render** 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.
2021-04-18 03:11:11 +00:00
**ncvisual_blitter_geom** returns non-zero if the specified blitter is invalid.
Fully general ncvisual layer (#647)
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.
2020-05-29 01:16:58 +00:00
2020-12-25 22:37:27 +00:00
**ncvisual_media_defblitter** returns the blitter selected by **NCBLIT_DEFAULT**
2020-11-01 12:19:02 +00:00
in the specified configuration. If UTF8 is not enabled, this will always be
2020-12-25 22:37:27 +00:00
**NCBLIT_1x1**. If ** *scale*** is **NCSCALE_NONE** or **NCSCALE_SCALE** , the
aspect-preserving **NCBLIT_2x1** will be returned. If sextants are available
(see **notcurses_cansextant** ), this will be **NCBLIT_3x2** , or otherwise
**NCBLIT_2x2**.
2020-11-01 12:19:02 +00:00
2020-04-24 07:17:34 +00:00
# NOTES
Multimedia decoding requires that Notcurses be built with either FFmpeg or
OpenImageIO support. What formats can be decoded is totally dependent on the
2021-06-06 00:34:14 +00:00
linked library. OpenImageIO does not support subtitles. Functions requiring
a multimedia backend include **ncvisual_from_file** and **ncvisual_subtitle** .
2020-03-24 22:43:10 +00:00
2021-03-09 04:31:27 +00:00
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 ).
2020-11-11 08:12:37 +00:00
Bad font support can ruin **NCBLIT_2x2** , **NCBLIT_3x2** , **NCBLIT_4x1** ,
2021-01-31 23:04:49 +00:00
**NCBLIT_BRAILLE**, and **NCBLIT_8x1** . Braille glyphs ought ideally draw only
the raised dots, rather than drawing all eight dots with two different styles.
It's often best for the emulator to draw these glyphs itself.
2020-10-19 03:15:50 +00:00
2021-04-24 06:28:23 +00:00
Several emulators claim to implement Sixel, but do so in a more or less broken
fashion. I consider **XTerm** and **foot** to be reference Sixel
implementations on X.org and Wayland, respectively.
Sixels are fundamentally expressed in terms of six-line bands. If the rendered
bitmap is not a multiple of six rows, the necessary rows will be faked via
transparent rows. All sprixels have a height in rows, and if this height is
not a multiple of the cell height in rows, the last rows will only partially
obstruct a row of cells. This can lead to undesirable redraws and flicker if
the cells underneath the sprixel change. A sprixel which is both a multiple of
the cell height and a multiple of six is the most predictable possible sprixel.
2021-06-19 05:12:49 +00:00
When using non-interpolative blitting together with scaling, unless your goal
includes minimizing the total area required, lower-resolution blitters will
generally look just as good as higher resolution blitters, and be faster.
2021-04-24 06:28:23 +00:00
# BUGS
Functions which describe rendered state such as **ncplane_at_yx** and
**notcurses_at_yx** will return an **nccell** with a sprixel ID, but this
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
2021-03-25 23:57:35 +00:00
the standard pile. This ought become a reality soon.
2021-06-06 00:34:14 +00:00
**ncvisual_stream** currently requires a multimedia engine, which is silly.
This will change in the near future.
2021-04-24 06:28:23 +00:00
Sprixels interact poorly with multiple planes, and such usage is discouraged.
This situation might improve in the future.
2021-04-30 06:56:20 +00:00
Multiple threads may not currently call **ncvisual_render** concurrently
using the same **ncvisual** , even if targeting distinct **ncplane**s. This
will likely change in the future.
2020-01-02 02:23:11 +00:00
# SEE ALSO
2020-05-04 04:56:52 +00:00
**notcurses(3)**,
2020-12-25 22:37:27 +00:00
**notcurses_capabilities(3)**,
2020-05-09 00:56:39 +00:00
**notcurses_plane(3)**,
2021-01-31 23:04:49 +00:00
**notcurses_render(3)**,
2020-05-04 04:56:52 +00:00
**utf-8(7)**