mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 09:09:03 -04:00
Support Unicode 16 octants
This commit is contained in:
parent
c723857877
commit
e17c412736
@ -226,9 +226,9 @@ likely get blanks or <20> (U+FFFD, REPLACEMENT CHARACTER) for missing characters,
|
|||||||
and subsequent characters on the line may be misplaced.
|
and subsequent characters on the line may be misplaced.
|
||||||
|
|
||||||
It is worth knowing that several terminals draw the block characters directly,
|
It is worth knowing that several terminals draw the block characters directly,
|
||||||
rather than loading them from a font. This is generally desirable. Quadrants
|
rather than loading them from a font. This is generally desirable. Quadrants,
|
||||||
and sextants are not the place to demonstrate your design virtuosity. To
|
sextants, and octants are not the place to demonstrate your design virtuosity.
|
||||||
inspect your environment's rendering of drawing characters, run
|
To inspect your environment's rendering of drawing characters, run
|
||||||
`notcurses-info`. The desired output ought look something like this:
|
`notcurses-info`. The desired output ought look something like this:
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@ -309,7 +309,8 @@ If things break or seem otherwise lackluster, **please** consult the
|
|||||||
Notcurses will not make use of bitmap protocols unless the terminal positively
|
Notcurses will not make use of bitmap protocols unless the terminal positively
|
||||||
indicates support for them, even if <code>NCBLIT_PIXEL</code> has been
|
indicates support for them, even if <code>NCBLIT_PIXEL</code> has been
|
||||||
requested. Likewise, sextants (<code>NCBLIT_3x2</code>) won't be used without
|
requested. Likewise, sextants (<code>NCBLIT_3x2</code>) won't be used without
|
||||||
Unicode 13 support, etc. <code>ncvisual_blit()</code> will use the best blitter
|
Unicode 13 support, octants (<code>NCBLIT_4x2</code>) won't be used without
|
||||||
|
Unicode 17 support, etc. <code>ncvisual_blit()</code> will use the best blitter
|
||||||
available, unless <code>NCVISUAL_OPTION_NODEGRADE</code> is provided (in
|
available, unless <code>NCVISUAL_OPTION_NODEGRADE</code> is provided (in
|
||||||
which case it will fail).
|
which case it will fail).
|
||||||
</details>
|
</details>
|
||||||
|
@ -17,7 +17,7 @@ terminal environment, including material loaded from **terminfo(5)** (based
|
|||||||
on the **TERM** environment variable), replies from the terminal in
|
on the **TERM** environment variable), replies from the terminal in
|
||||||
response to our queries, and built-in heuristics.
|
response to our queries, and built-in heuristics.
|
||||||
|
|
||||||
The Unicode half block, quadrant, sextant, and Braille glyphs are all included
|
The Unicode half block, quadrant, sextant, octant, and Braille glyphs are all included
|
||||||
in the output. If their appearance is irregular, it might behoove you to choose
|
in the output. If their appearance is irregular, it might behoove you to choose
|
||||||
another font.
|
another font.
|
||||||
|
|
||||||
@ -70,6 +70,7 @@ The next five lines describe properties of the terminal environment:
|
|||||||
* 2x1: Upper- and lower-half blocks are available
|
* 2x1: Upper- and lower-half blocks are available
|
||||||
* 2x2: Quadrant blocks are available
|
* 2x2: Quadrant blocks are available
|
||||||
* 3x2: Sextant blocks are available
|
* 3x2: Sextant blocks are available
|
||||||
|
* 4x2: Octant blocks are available
|
||||||
* 4x2: Braille characters are available
|
* 4x2: Braille characters are available
|
||||||
* img: Images can be decoded
|
* img: Images can be decoded
|
||||||
* vid: Video can be decoded
|
* vid: Video can be decoded
|
||||||
@ -93,7 +94,7 @@ To the right of this material is the Notcurses homepage's URI, and the
|
|||||||
Notcurses logo (the latter only if bitmap graphics are available).
|
Notcurses logo (the latter only if bitmap graphics are available).
|
||||||
|
|
||||||
The final eleven lines, only printed when in a UTF8 locale, show various
|
The final eleven lines, only printed when in a UTF8 locale, show various
|
||||||
Unicode glyphs. The first four lines include the quadrant, sextant, and
|
Unicode glyphs. The first four lines include the quadrant, sextant, octant, and
|
||||||
box-drawing characters. The next four lines include the entire Braille set.
|
box-drawing characters. The next four lines include the entire Braille set.
|
||||||
The following two lines include many of the Symbols for Legacy Computing
|
The following two lines include many of the Symbols for Legacy Computing
|
||||||
introduced in Unicode 13. The final line includes many emoji.
|
introduced in Unicode 13. The final line includes many emoji.
|
||||||
|
@ -34,6 +34,8 @@ notcurses_capabilities - runtime capability detection
|
|||||||
|
|
||||||
**bool notcurses_cansextant(const struct notcurses* ***nc***);**
|
**bool notcurses_cansextant(const struct notcurses* ***nc***);**
|
||||||
|
|
||||||
|
**bool notcurses_canoctant(const struct notcurses* ***nc***);**
|
||||||
|
|
||||||
**bool notcurses_canbraille(const struct notcurses* ***nc***);**
|
**bool notcurses_canbraille(const struct notcurses* ***nc***);**
|
||||||
|
|
||||||
**bool notcurses_canpixel(const struct notcurses* ***nc***);**
|
**bool notcurses_canpixel(const struct notcurses* ***nc***);**
|
||||||
@ -92,6 +94,8 @@ multimedia support capable of decoding videos.
|
|||||||
**notcurses_canutf8** returns **true** if the configured locale uses
|
**notcurses_canutf8** returns **true** if the configured locale uses
|
||||||
UTF-8 encoding, and the locale was successfully loaded.
|
UTF-8 encoding, and the locale was successfully loaded.
|
||||||
|
|
||||||
|
**notcurses_canoctant** returns **true** if the heuristics suggest
|
||||||
|
that the terminal can properly render Unicode 17 octants. Likewise,
|
||||||
**notcurses_cansextant** returns **true** if the heuristics suggest
|
**notcurses_cansextant** returns **true** if the heuristics suggest
|
||||||
that the terminal can properly render Unicode 13 sextants. Likewise,
|
that the terminal can properly render Unicode 13 sextants. Likewise,
|
||||||
**notcurses_canquadrant** and **notcurses_canhalfblock** return **true**
|
**notcurses_canquadrant** and **notcurses_canhalfblock** return **true**
|
||||||
|
@ -114,6 +114,8 @@ notcurses_direct - the Direct Mode API
|
|||||||
|
|
||||||
**bool ncdirect_cansextant(const struct ncdirect* ***nc***);**
|
**bool ncdirect_cansextant(const struct ncdirect* ***nc***);**
|
||||||
|
|
||||||
|
**bool ncdirect_canoctant(const struct ncdirect* ***nc***);**
|
||||||
|
|
||||||
**bool ncdirect_canbraille(const struct ncdirect* ***nc***);**
|
**bool ncdirect_canbraille(const struct ncdirect* ***nc***);**
|
||||||
|
|
||||||
**bool ncdirect_canget_cursor(const struct ncdirect* ***nc***);**
|
**bool ncdirect_canget_cursor(const struct ncdirect* ***nc***);**
|
||||||
|
@ -84,9 +84,9 @@ contribute to the plot. Supplying an **x** below the current window is an
|
|||||||
error, and has no effect.
|
error, and has no effect.
|
||||||
|
|
||||||
More granular block glyphs means more resolution in your plots, but they can
|
More granular block glyphs means more resolution in your plots, but they can
|
||||||
be difficult to differentiate at small text sizes. Sextants and Braille allow
|
be difficult to differentiate at small text sizes. Octants, sextants, and Braille
|
||||||
for more resolution on the independent variable. It can be difficult to predict
|
allow for more resolution on the independent variable. It can be difficult to
|
||||||
how the Braille glyphs will look in a given font.
|
predict how the Braille glyphs will look in a given font.
|
||||||
|
|
||||||
The same **ncplot_options** struct can be used with all ncplot types. The
|
The same **ncplot_options** struct can be used with all ncplot types. The
|
||||||
**flags** field is a bitmask composed of:
|
**flags** field is a bitmask composed of:
|
||||||
|
@ -24,6 +24,7 @@ typedef enum {
|
|||||||
NCBLIT_2x1, // halves + 1x1
|
NCBLIT_2x1, // halves + 1x1
|
||||||
NCBLIT_2x2, // quadrants + 2x1
|
NCBLIT_2x2, // quadrants + 2x1
|
||||||
NCBLIT_3x2, // sextants + 1x1
|
NCBLIT_3x2, // sextants + 1x1
|
||||||
|
NCBLIT_4x2, // octants + quadrants + 2x1 + 1x1
|
||||||
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille)
|
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille)
|
||||||
NCBLIT_PIXEL, // pixel graphics
|
NCBLIT_PIXEL, // pixel graphics
|
||||||
NCBLIT_4x1, // four vertical levels, (plots)
|
NCBLIT_4x1, // four vertical levels, (plots)
|
||||||
@ -238,6 +239,7 @@ The different **ncblitter_e** values select from among available glyph sets:
|
|||||||
* **NCBLIT_2x1**: Adds the half blocks (▄▀) to **NCBLIT_1x1**.
|
* **NCBLIT_2x1**: Adds the half blocks (▄▀) to **NCBLIT_1x1**.
|
||||||
* **NCBLIT_2x2**: Adds left and right half blocks (▌▐) and quadrants (▖▗▟▙) to **NCBLIT_2x1**.
|
* **NCBLIT_2x2**: Adds left and right half blocks (▌▐) and quadrants (▖▗▟▙) to **NCBLIT_2x1**.
|
||||||
* **NCBLIT_3x2**: Adds sextants to **NCBLIT_1x1**.
|
* **NCBLIT_3x2**: Adds sextants to **NCBLIT_1x1**.
|
||||||
|
* **NCBLIT_4x2**: Adds octants to **NCBLIT_2x2**.
|
||||||
* **NCBLIT_BRAILLE**: 4 rows and 2 columns of braille (⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿).
|
* **NCBLIT_BRAILLE**: 4 rows and 2 columns of braille (⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿).
|
||||||
* **NCBLIT_PIXEL**: Adds pixel graphics (these also work in ASCII).
|
* **NCBLIT_PIXEL**: Adds pixel graphics (these also work in ASCII).
|
||||||
|
|
||||||
@ -343,10 +345,11 @@ or if both ***nc*** and ***n*** are **NULL**.
|
|||||||
|
|
||||||
**ncvisual_media_defblitter** returns the blitter selected by **NCBLIT_DEFAULT**
|
**ncvisual_media_defblitter** returns the blitter selected by **NCBLIT_DEFAULT**
|
||||||
in the specified configuration. If UTF8 is not enabled, this will always be
|
in the specified configuration. If UTF8 is not enabled, this will always be
|
||||||
**NCBLIT_1x1**. If ***scale*** is **NCSCALE_NONE** or **NCSCALE_SCALE**, the
|
**NCBLIT_1x1**. If octants are available, (see **notcurses_canictant**), the
|
||||||
aspect-preserving **NCBLIT_2x1** will be returned. If sextants are available
|
aspect-preserving **NCBLIT_4x2** will be returned. If ***scale*** is
|
||||||
(see **notcurses_cansextant**), this will be **NCBLIT_3x2**, or otherwise
|
**NCSCALE_NONE** or **NCSCALE_SCALE**, the aspect-preserving **NCBLIT_2x1**
|
||||||
**NCBLIT_2x2**.
|
will be returned. If sextants are available (see **notcurses_cansextant**),
|
||||||
|
this will be **NCBLIT_3x2**, or otherwise **NCBLIT_2x2**.
|
||||||
|
|
||||||
# NOTES
|
# NOTES
|
||||||
|
|
||||||
|
@ -126,6 +126,11 @@ namespace ncpp
|
|||||||
return notcurses_cansextant (nc);
|
return notcurses_cansextant (nc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool can_octant () const noexcept
|
||||||
|
{
|
||||||
|
return notcurses_canoctant (nc);
|
||||||
|
}
|
||||||
|
|
||||||
bool can_utf8 () const noexcept
|
bool can_utf8 () const noexcept
|
||||||
{
|
{
|
||||||
return notcurses_canutf8 (nc);
|
return notcurses_canutf8 (nc);
|
||||||
|
@ -394,6 +394,12 @@ ncdirect_cansextant(const struct ncdirect* nc){
|
|||||||
return ncdirect_canutf8(nc) && ncdirect_capabilities(nc)->sextants;
|
return ncdirect_canutf8(nc) && ncdirect_capabilities(nc)->sextants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can we reliably use Unicode 16 octants?
|
||||||
|
static inline bool
|
||||||
|
ncdirect_canoctant(const struct ncdirect* nc){
|
||||||
|
return ncdirect_canutf8(nc) && ncdirect_capabilities(nc)->octants;
|
||||||
|
}
|
||||||
|
|
||||||
// Can we reliably use Unicode Braille?
|
// Can we reliably use Unicode Braille?
|
||||||
static inline bool
|
static inline bool
|
||||||
ncdirect_canbraille(const struct ncdirect* nc){
|
ncdirect_canbraille(const struct ncdirect* nc){
|
||||||
|
@ -56,6 +56,39 @@ extern "C" {
|
|||||||
#define NCHALFBLOCKS L" ▀▄█"
|
#define NCHALFBLOCKS L" ▀▄█"
|
||||||
#define NCQUADBLOCKS L" ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█"
|
#define NCQUADBLOCKS L" ▘▝▀▖▌▞▛▗▚▐▜▄▙▟█"
|
||||||
#define NCSEXBLOCKS L" 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓▌🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧▐🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻█"
|
#define NCSEXBLOCKS L" 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓▌🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧▐🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻█"
|
||||||
|
#define NCOCTBLOCKS \
|
||||||
|
L" \U0001CEA8\U0001CEAB\U0001FB82\U0001CD00\U00002598\U0001CD01\U0001CD02"\
|
||||||
|
"\U0001CD03\U0001CD04\U0000259D\U0001CD05\U0001CD06\U0001CD07\U0001CD08\U00002580"\
|
||||||
|
"\U0001CD09\U0001CD0A\U0001CD0B\U0001CD0C\U0001FBE6\U0001CD0D\U0001CD0E\U0001CD0F"\
|
||||||
|
"\U0001CD10\U0001CD11\U0001CD12\U0001CD13\U0001CD14\U0001CD15\U0001CD16\U0001CD17"\
|
||||||
|
"\U0001CD18\U0001CD19\U0001CD1A\U0001CD1B\U0001CD1C\U0001CD1D\U0001CD1E\U0001CD1F"\
|
||||||
|
"\U0001FBE7\U0001CD20\U0001CD21\U0001CD22\U0001CD23\U0001CD24\U0001CD25\U0001CD26"\
|
||||||
|
"\U0001CD27\U0001CD28\U0001CD29\U0001CD2A\U0001CD2B\U0001CD2C\U0001CD2D\U0001CD2E"\
|
||||||
|
"\U0001CD2F\U0001CD30\U0001CD31\U0001CD32\U0001CD33\U0001CD34\U0001CD35\U0001FB85"\
|
||||||
|
"\U0001CEA3\U0001CD36\U0001CD37\U0001CD38\U0001CD39\U0001CD3A\U0001CD3B\U0001CD3C"\
|
||||||
|
"\U0001CD3D\U0001CD3E\U0001CD3F\U0001CD40\U0001CD41\U0001CD42\U0001CD43\U0001CD44"\
|
||||||
|
"\U00002596\U0001CD45\U0001CD46\U0001CD47\U0001CD48\U0000258C\U0001CD49\U0001CD4A"\
|
||||||
|
"\U0001CD4B\U0001CD4C\U0000259E\U0001CD4D\U0001CD4E\U0001CD4F\U0001CD50\U0000259B"\
|
||||||
|
"\U0001CD51\U0001CD52\U0001CD53\U0001CD54\U0001CD55\U0001CD56\U0001CD57\U0001CD58"\
|
||||||
|
"\U0001CD59\U0001CD5A\U0001CD5B\U0001CD5C\U0001CD5D\U0001CD5E\U0001CD5F\U0001CD60"\
|
||||||
|
"\U0001CD61\U0001CD62\U0001CD63\U0001CD64\U0001CD65\U0001CD66\U0001CD67\U0001CD68"\
|
||||||
|
"\U0001CD69\U0001CD6A\U0001CD6B\U0001CD6C\U0001CD6D\U0001CD6E\U0001CD6F\U0001CD70"\
|
||||||
|
"\U0001CEA0\U0001CD71\U0001CD72\U0001CD73\U0001CD74\U0001CD75\U0001CD76\U0001CD77"\
|
||||||
|
"\U0001CD78\U0001CD79\U0001CD7A\U0001CD7B\U0001CD7C\U0001CD7D\U0001CD7E\U0001CD7F"\
|
||||||
|
"\U0001CD80\U0001CD81\U0001CD82\U0001CD83\U0001CD84\U0001CD85\U0001CD86\U0001CD87"\
|
||||||
|
"\U0001CD88\U0001CD89\U0001CD8A\U0001CD8B\U0001CD8C\U0001CD8D\U0001CD8E\U0001CD8F"\
|
||||||
|
"\U00002597\U0001CD90\U0001CD91\U0001CD92\U0001CD93\U0000259A\U0001CD94\U0001CD95"\
|
||||||
|
"\U0001CD96\U0001CD97\U00002590\U0001CD98\U0001CD99\U0001CD9A\U0001CD9B\U0000259C"\
|
||||||
|
"\U0001CD9C\U0001CD9D\U0001CD9E\U0001CD9F\U0001CDA0\U0001CDA1\U0001CDA2\U0001CDA3"\
|
||||||
|
"\U0001CDA4\U0001CDA5\U0001CDA6\U0001CDA7\U0001CDA8\U0001CDA9\U0001CDAA\U0001CDAB"\
|
||||||
|
"\U00002582\U0001CDAC\U0001CDAD\U0001CDAE\U0001CDAF\U0001CDB0\U0001CDB1\U0001CDB2"\
|
||||||
|
"\U0001CDB3\U0001CDB4\U0001CDB5\U0001CDB6\U0001CDB7\U0001CDB8\U0001CDB9\U0001CDBA"\
|
||||||
|
"\U0001CDBB\U0001CDBC\U0001CDBD\U0001CDBE\U0001CDBF\U0001CDC0\U0001CDC1\U0001CDC2"\
|
||||||
|
"\U0001CDC3\U0001CDC4\U0001CDC5\U0001CDC6\U0001CDC7\U0001CDC8\U0001CDC9\U0001CDCA"\
|
||||||
|
"\U0001CDCB\U0001CDCC\U0001CDCD\U0001CDCE\U0001CDCF\U0001CDD0\U0001CDD1\U0001CDD2"\
|
||||||
|
"\U0001CDD3\U0001CDD4\U0001CDD5\U0001CDD6\U0001CDD7\U0001CDD8\U0001CDD9\U0001CDDA"\
|
||||||
|
"\U00002584\U0001CDDB\U0001CDDC\U0001CDDD\U0001CDDE\U00002599\U0001CDDF\U0001CDE0"\
|
||||||
|
"\U0001CDE1\U0001CDE2\U0000259F\U0001CDE3\U00002586\U0001CDE4\U0001CDE5\U00002588"
|
||||||
#define NCBRAILLEEGCS \
|
#define NCBRAILLEEGCS \
|
||||||
L"\u2800\u2801\u2808\u2809\u2802\u2803\u280a\u280b\u2810\u2811\u2818\u2819\u2812\u2813\u281a\u281b"\
|
L"\u2800\u2801\u2808\u2809\u2802\u2803\u280a\u280b\u2810\u2811\u2818\u2819\u2812\u2813\u281a\u281b"\
|
||||||
"\u2804\u2805\u280c\u280d\u2806\u2807\u280e\u280f\u2814\u2815\u281c\u281d\u2816\u2817\u281e\u281f"\
|
"\u2804\u2805\u280c\u280d\u2806\u2807\u280e\u280f\u2814\u2815\u281c\u281d\u2816\u2817\u281e\u281f"\
|
||||||
|
@ -68,6 +68,7 @@ typedef enum {
|
|||||||
NCBLIT_2x1, // halves + 1x1 (space) ▄▀
|
NCBLIT_2x1, // halves + 1x1 (space) ▄▀
|
||||||
NCBLIT_2x2, // quadrants + 2x1 ▗▐ ▖▀▟▌▙
|
NCBLIT_2x2, // quadrants + 2x1 ▗▐ ▖▀▟▌▙
|
||||||
NCBLIT_3x2, // sextants (*NOT* 2x2) 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞
|
NCBLIT_3x2, // sextants (*NOT* 2x2) 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞
|
||||||
|
NCBLIT_4x2, // octants
|
||||||
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille) ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿
|
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille) ⡀⡄⡆⡇⢀⣀⣄⣆⣇⢠⣠⣤⣦⣧⢰⣰⣴⣶⣷⢸⣸⣼⣾⣿
|
||||||
NCBLIT_PIXEL, // pixel graphics
|
NCBLIT_PIXEL, // pixel graphics
|
||||||
// these blitters are suitable only for plots, not general media
|
// these blitters are suitable only for plots, not general media
|
||||||
@ -1641,6 +1642,7 @@ typedef struct nccapabilities {
|
|||||||
bool halfblocks;// we assume halfblocks, but some are known to lack them
|
bool halfblocks;// we assume halfblocks, but some are known to lack them
|
||||||
bool quadrants; // do we have (good, vetted) Unicode 1 quadrant support?
|
bool quadrants; // do we have (good, vetted) Unicode 1 quadrant support?
|
||||||
bool sextants; // do we have (good, vetted) Unicode 13 sextant support?
|
bool sextants; // do we have (good, vetted) Unicode 13 sextant support?
|
||||||
|
bool octants; // do we have (good, vetted) Unicode 16 octant support?
|
||||||
bool braille; // do we have Braille support? (linux console does not)
|
bool braille; // do we have Braille support? (linux console does not)
|
||||||
} nccapabilities;
|
} nccapabilities;
|
||||||
|
|
||||||
@ -1756,6 +1758,12 @@ notcurses_cansextant(const struct notcurses* nc){
|
|||||||
return notcurses_canutf8(nc) && notcurses_capabilities(nc)->sextants;
|
return notcurses_canutf8(nc) && notcurses_capabilities(nc)->sextants;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can we reliably use Unicode 16 octants?
|
||||||
|
__attribute__ ((nonnull (1))) __attribute__ ((pure)) static inline bool
|
||||||
|
notcurses_canoctant(const struct notcurses* nc){
|
||||||
|
return notcurses_canutf8(nc) && notcurses_capabilities(nc)->octants;
|
||||||
|
}
|
||||||
|
|
||||||
// Can we reliably use Unicode Braille?
|
// Can we reliably use Unicode Braille?
|
||||||
__attribute__ ((nonnull (1))) __attribute__ ((pure)) static inline bool
|
__attribute__ ((nonnull (1))) __attribute__ ((pure)) static inline bool
|
||||||
notcurses_canbraille(const struct notcurses* nc){
|
notcurses_canbraille(const struct notcurses* nc){
|
||||||
@ -3510,11 +3518,12 @@ API ALLOC struct ncplane* ncvisual_subtitle_plane(struct ncplane* parent,
|
|||||||
// Get the default *media* (not plot) blitter for this environment when using
|
// Get the default *media* (not plot) blitter for this environment when using
|
||||||
// the specified scaling method. Currently, this means:
|
// the specified scaling method. Currently, this means:
|
||||||
// - if lacking UTF-8, NCBLIT_1x1
|
// - if lacking UTF-8, NCBLIT_1x1
|
||||||
|
// - otherwise, if octants are known to be good, NCBLIT_4x2
|
||||||
// - otherwise, if not NCSCALE_STRETCH, NCBLIT_2x1
|
// - otherwise, if not NCSCALE_STRETCH, NCBLIT_2x1
|
||||||
// - otherwise, if sextants are not known to be good, NCBLIT_2x2
|
// - otherwise, if sextants are not known to be good, NCBLIT_2x2
|
||||||
// - otherwise NCBLIT_3x2
|
// - otherwise NCBLIT_3x2
|
||||||
// NCBLIT_2x2 and NCBLIT_3x2 both distort the original aspect ratio, thus
|
// NCBLIT_2x2 and NCBLIT_3x2 both distort the original aspect ratio, thus
|
||||||
// NCBLIT_2x1 is used outside of NCSCALE_STRETCH.
|
// NCBLIT_4x2 or NCBLIT_2x1 is used outside of NCSCALE_STRETCH.
|
||||||
API ncblitter_e ncvisual_media_defblitter(const struct notcurses* nc, ncscale_e scale)
|
API ncblitter_e ncvisual_media_defblitter(const struct notcurses* nc, ncscale_e scale)
|
||||||
__attribute__ ((nonnull (1)));
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ visualize(struct notcurses* nc, struct ncvisual* ncv){
|
|||||||
{ NCBLIT_2x1, notcurses_canhalfblock, },
|
{ NCBLIT_2x1, notcurses_canhalfblock, },
|
||||||
{ NCBLIT_2x2, notcurses_canquadrant, },
|
{ NCBLIT_2x2, notcurses_canquadrant, },
|
||||||
{ NCBLIT_3x2, notcurses_cansextant, },
|
{ NCBLIT_3x2, notcurses_cansextant, },
|
||||||
|
{ NCBLIT_4x2, notcurses_canoctant, },
|
||||||
{ NCBLIT_PIXEL, notcurses_canpixel, },
|
{ NCBLIT_PIXEL, notcurses_canpixel, },
|
||||||
};
|
};
|
||||||
struct ncplane* stdn = notcurses_stdplane(nc);
|
struct ncplane* stdn = notcurses_stdplane(nc);
|
||||||
|
@ -463,6 +463,7 @@ tinfo_debug_styles(const notcurses* nc, struct ncplane* n, const char* indent){
|
|||||||
tinfo_debug_cap(n, "2x1", notcurses_canhalfblock(nc));
|
tinfo_debug_cap(n, "2x1", notcurses_canhalfblock(nc));
|
||||||
tinfo_debug_cap(n, "2x2", notcurses_canquadrant(nc));
|
tinfo_debug_cap(n, "2x2", notcurses_canquadrant(nc));
|
||||||
tinfo_debug_cap(n, "3x2", notcurses_cansextant(nc));
|
tinfo_debug_cap(n, "3x2", notcurses_cansextant(nc));
|
||||||
|
tinfo_debug_cap(n, "4x2", notcurses_canoctant(nc));
|
||||||
tinfo_debug_cap(n, "4x2", notcurses_canbraille(nc));
|
tinfo_debug_cap(n, "4x2", notcurses_canbraille(nc));
|
||||||
tinfo_debug_cap(n, "img", notcurses_canopen_images(nc));
|
tinfo_debug_cap(n, "img", notcurses_canopen_images(nc));
|
||||||
tinfo_debug_cap(n, "vid", notcurses_canopen_videos(nc));
|
tinfo_debug_cap(n, "vid", notcurses_canopen_videos(nc));
|
||||||
|
481
src/lib/blit.c
481
src/lib/blit.c
@ -711,6 +711,448 @@ sextant_blit(ncplane* nc, int linesize, const void* data, int leny, int lenx,
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bit is *set* where octant *is*:
|
||||||
|
// 0 1
|
||||||
|
// 2 3
|
||||||
|
// 4 5
|
||||||
|
// 6 7
|
||||||
|
// Same as NCOCTBLOCKS but as array of characters
|
||||||
|
static const char* const octant_egcs[256] = {
|
||||||
|
"\x20",
|
||||||
|
"\U0001CEA8",
|
||||||
|
"\U0001CEAB",
|
||||||
|
"\U0001FB82",
|
||||||
|
"\U0001CD00",
|
||||||
|
"\U00002598",
|
||||||
|
"\U0001CD01",
|
||||||
|
"\U0001CD02",
|
||||||
|
"\U0001CD03",
|
||||||
|
"\U0001CD04",
|
||||||
|
"\U0000259D",
|
||||||
|
"\U0001CD05",
|
||||||
|
"\U0001CD06",
|
||||||
|
"\U0001CD07",
|
||||||
|
"\U0001CD08",
|
||||||
|
"\U00002580",
|
||||||
|
"\U0001CD09",
|
||||||
|
"\U0001CD0A",
|
||||||
|
"\U0001CD0B",
|
||||||
|
"\U0001CD0C",
|
||||||
|
"\U0001FBE6",
|
||||||
|
"\U0001CD0D",
|
||||||
|
"\U0001CD0E",
|
||||||
|
"\U0001CD0F",
|
||||||
|
"\U0001CD10",
|
||||||
|
"\U0001CD11",
|
||||||
|
"\U0001CD12",
|
||||||
|
"\U0001CD13",
|
||||||
|
"\U0001CD14",
|
||||||
|
"\U0001CD15",
|
||||||
|
"\U0001CD16",
|
||||||
|
"\U0001CD17",
|
||||||
|
"\U0001CD18",
|
||||||
|
"\U0001CD19",
|
||||||
|
"\U0001CD1A",
|
||||||
|
"\U0001CD1B",
|
||||||
|
"\U0001CD1C",
|
||||||
|
"\U0001CD1D",
|
||||||
|
"\U0001CD1E",
|
||||||
|
"\U0001CD1F",
|
||||||
|
"\U0001FBE7",
|
||||||
|
"\U0001CD20",
|
||||||
|
"\U0001CD21",
|
||||||
|
"\U0001CD22",
|
||||||
|
"\U0001CD23",
|
||||||
|
"\U0001CD24",
|
||||||
|
"\U0001CD25",
|
||||||
|
"\U0001CD26",
|
||||||
|
"\U0001CD27",
|
||||||
|
"\U0001CD28",
|
||||||
|
"\U0001CD29",
|
||||||
|
"\U0001CD2A",
|
||||||
|
"\U0001CD2B",
|
||||||
|
"\U0001CD2C",
|
||||||
|
"\U0001CD2D",
|
||||||
|
"\U0001CD2E",
|
||||||
|
"\U0001CD2F",
|
||||||
|
"\U0001CD30",
|
||||||
|
"\U0001CD31",
|
||||||
|
"\U0001CD32",
|
||||||
|
"\U0001CD33",
|
||||||
|
"\U0001CD34",
|
||||||
|
"\U0001CD35",
|
||||||
|
"\U0001FB85",
|
||||||
|
"\U0001CEA3",
|
||||||
|
"\U0001CD36",
|
||||||
|
"\U0001CD37",
|
||||||
|
"\U0001CD38",
|
||||||
|
"\U0001CD39",
|
||||||
|
"\U0001CD3A",
|
||||||
|
"\U0001CD3B",
|
||||||
|
"\U0001CD3C",
|
||||||
|
"\U0001CD3D",
|
||||||
|
"\U0001CD3E",
|
||||||
|
"\U0001CD3F",
|
||||||
|
"\U0001CD40",
|
||||||
|
"\U0001CD41",
|
||||||
|
"\U0001CD42",
|
||||||
|
"\U0001CD43",
|
||||||
|
"\U0001CD44",
|
||||||
|
"\U00002596",
|
||||||
|
"\U0001CD45",
|
||||||
|
"\U0001CD46",
|
||||||
|
"\U0001CD47",
|
||||||
|
"\U0001CD48",
|
||||||
|
"\U0000258C",
|
||||||
|
"\U0001CD49",
|
||||||
|
"\U0001CD4A",
|
||||||
|
"\U0001CD4B",
|
||||||
|
"\U0001CD4C",
|
||||||
|
"\U0000259E",
|
||||||
|
"\U0001CD4D",
|
||||||
|
"\U0001CD4E",
|
||||||
|
"\U0001CD4F",
|
||||||
|
"\U0001CD50",
|
||||||
|
"\U0000259B",
|
||||||
|
"\U0001CD51",
|
||||||
|
"\U0001CD52",
|
||||||
|
"\U0001CD53",
|
||||||
|
"\U0001CD54",
|
||||||
|
"\U0001CD55",
|
||||||
|
"\U0001CD56",
|
||||||
|
"\U0001CD57",
|
||||||
|
"\U0001CD58",
|
||||||
|
"\U0001CD59",
|
||||||
|
"\U0001CD5A",
|
||||||
|
"\U0001CD5B",
|
||||||
|
"\U0001CD5C",
|
||||||
|
"\U0001CD5D",
|
||||||
|
"\U0001CD5E",
|
||||||
|
"\U0001CD5F",
|
||||||
|
"\U0001CD60",
|
||||||
|
"\U0001CD61",
|
||||||
|
"\U0001CD62",
|
||||||
|
"\U0001CD63",
|
||||||
|
"\U0001CD64",
|
||||||
|
"\U0001CD65",
|
||||||
|
"\U0001CD66",
|
||||||
|
"\U0001CD67",
|
||||||
|
"\U0001CD68",
|
||||||
|
"\U0001CD69",
|
||||||
|
"\U0001CD6A",
|
||||||
|
"\U0001CD6B",
|
||||||
|
"\U0001CD6C",
|
||||||
|
"\U0001CD6D",
|
||||||
|
"\U0001CD6E",
|
||||||
|
"\U0001CD6F",
|
||||||
|
"\U0001CD70",
|
||||||
|
"\U0001CEA0",
|
||||||
|
"\U0001CD71",
|
||||||
|
"\U0001CD72",
|
||||||
|
"\U0001CD73",
|
||||||
|
"\U0001CD74",
|
||||||
|
"\U0001CD75",
|
||||||
|
"\U0001CD76",
|
||||||
|
"\U0001CD77",
|
||||||
|
"\U0001CD78",
|
||||||
|
"\U0001CD79",
|
||||||
|
"\U0001CD7A",
|
||||||
|
"\U0001CD7B",
|
||||||
|
"\U0001CD7C",
|
||||||
|
"\U0001CD7D",
|
||||||
|
"\U0001CD7E",
|
||||||
|
"\U0001CD7F",
|
||||||
|
"\U0001CD80",
|
||||||
|
"\U0001CD81",
|
||||||
|
"\U0001CD82",
|
||||||
|
"\U0001CD83",
|
||||||
|
"\U0001CD84",
|
||||||
|
"\U0001CD85",
|
||||||
|
"\U0001CD86",
|
||||||
|
"\U0001CD87",
|
||||||
|
"\U0001CD88",
|
||||||
|
"\U0001CD89",
|
||||||
|
"\U0001CD8A",
|
||||||
|
"\U0001CD8B",
|
||||||
|
"\U0001CD8C",
|
||||||
|
"\U0001CD8D",
|
||||||
|
"\U0001CD8E",
|
||||||
|
"\U0001CD8F",
|
||||||
|
"\U00002597",
|
||||||
|
"\U0001CD90",
|
||||||
|
"\U0001CD91",
|
||||||
|
"\U0001CD92",
|
||||||
|
"\U0001CD93",
|
||||||
|
"\U0000259A",
|
||||||
|
"\U0001CD94",
|
||||||
|
"\U0001CD95",
|
||||||
|
"\U0001CD96",
|
||||||
|
"\U0001CD97",
|
||||||
|
"\U00002590",
|
||||||
|
"\U0001CD98",
|
||||||
|
"\U0001CD99",
|
||||||
|
"\U0001CD9A",
|
||||||
|
"\U0001CD9B",
|
||||||
|
"\U0000259C",
|
||||||
|
"\U0001CD9C",
|
||||||
|
"\U0001CD9D",
|
||||||
|
"\U0001CD9E",
|
||||||
|
"\U0001CD9F",
|
||||||
|
"\U0001CDA0",
|
||||||
|
"\U0001CDA1",
|
||||||
|
"\U0001CDA2",
|
||||||
|
"\U0001CDA3",
|
||||||
|
"\U0001CDA4",
|
||||||
|
"\U0001CDA5",
|
||||||
|
"\U0001CDA6",
|
||||||
|
"\U0001CDA7",
|
||||||
|
"\U0001CDA8",
|
||||||
|
"\U0001CDA9",
|
||||||
|
"\U0001CDAA",
|
||||||
|
"\U0001CDAB",
|
||||||
|
"\U00002582",
|
||||||
|
"\U0001CDAC",
|
||||||
|
"\U0001CDAD",
|
||||||
|
"\U0001CDAE",
|
||||||
|
"\U0001CDAF",
|
||||||
|
"\U0001CDB0",
|
||||||
|
"\U0001CDB1",
|
||||||
|
"\U0001CDB2",
|
||||||
|
"\U0001CDB3",
|
||||||
|
"\U0001CDB4",
|
||||||
|
"\U0001CDB5",
|
||||||
|
"\U0001CDB6",
|
||||||
|
"\U0001CDB7",
|
||||||
|
"\U0001CDB8",
|
||||||
|
"\U0001CDB9",
|
||||||
|
"\U0001CDBA",
|
||||||
|
"\U0001CDBB",
|
||||||
|
"\U0001CDBC",
|
||||||
|
"\U0001CDBD",
|
||||||
|
"\U0001CDBE",
|
||||||
|
"\U0001CDBF",
|
||||||
|
"\U0001CDC0",
|
||||||
|
"\U0001CDC1",
|
||||||
|
"\U0001CDC2",
|
||||||
|
"\U0001CDC3",
|
||||||
|
"\U0001CDC4",
|
||||||
|
"\U0001CDC5",
|
||||||
|
"\U0001CDC6",
|
||||||
|
"\U0001CDC7",
|
||||||
|
"\U0001CDC8",
|
||||||
|
"\U0001CDC9",
|
||||||
|
"\U0001CDCA",
|
||||||
|
"\U0001CDCB",
|
||||||
|
"\U0001CDCC",
|
||||||
|
"\U0001CDCD",
|
||||||
|
"\U0001CDCE",
|
||||||
|
"\U0001CDCF",
|
||||||
|
"\U0001CDD0",
|
||||||
|
"\U0001CDD1",
|
||||||
|
"\U0001CDD2",
|
||||||
|
"\U0001CDD3",
|
||||||
|
"\U0001CDD4",
|
||||||
|
"\U0001CDD5",
|
||||||
|
"\U0001CDD6",
|
||||||
|
"\U0001CDD7",
|
||||||
|
"\U0001CDD8",
|
||||||
|
"\U0001CDD9",
|
||||||
|
"\U0001CDDA",
|
||||||
|
"\U00002584",
|
||||||
|
"\U0001CDDB",
|
||||||
|
"\U0001CDDC",
|
||||||
|
"\U0001CDDD",
|
||||||
|
"\U0001CDDE",
|
||||||
|
"\U00002599",
|
||||||
|
"\U0001CDDF",
|
||||||
|
"\U0001CDE0",
|
||||||
|
"\U0001CDE1",
|
||||||
|
"\U0001CDE2",
|
||||||
|
"\U0000259F",
|
||||||
|
"\U0001CDE3",
|
||||||
|
"\U00002586",
|
||||||
|
"\U0001CDE4",
|
||||||
|
"\U0001CDE5",
|
||||||
|
"\U00002588",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Solve for the cell rendered by this 4x2 sample. None of the input pixels may
|
||||||
|
// be transparent (that ought already have been handled). We use exhaustive
|
||||||
|
// search, which might be quite computationally intensive for the worst case
|
||||||
|
// (all eight pixels are different colors). We want to solve for the 2-partition
|
||||||
|
// of pixels that minimizes total source distance from the resulting lerps.
|
||||||
|
static const char*
|
||||||
|
oct_solver(const uint32_t rgbas[8], uint64_t* channels, unsigned blendcolors,
|
||||||
|
unsigned nointerpolate){
|
||||||
|
// Each element within the set of 256 has an inverse element within
|
||||||
|
// the set, for which we would calculate the same total differences,
|
||||||
|
// so just handle the first 128.
|
||||||
|
//
|
||||||
|
// We loop over the bitstrings, dividing the pixels into two sets,
|
||||||
|
// and then taking a general lerp over each set. we then compute the
|
||||||
|
// sum of absolute differences, and see if it's the new minimum.
|
||||||
|
int best = -1;
|
||||||
|
uint32_t mindiff = UINT_MAX;
|
||||||
|
for(size_t glyph = 0; glyph < 128; ++glyph){
|
||||||
|
unsigned rsum0 = 0, rsum1 = 0;
|
||||||
|
unsigned gsum0 = 0, gsum1 = 0;
|
||||||
|
unsigned bsum0 = 0, bsum1 = 0;
|
||||||
|
int insum = 0;
|
||||||
|
int outsum = 0;
|
||||||
|
for(unsigned mask = 0 ; mask < 8 ; ++mask){
|
||||||
|
if(glyph & (1u << mask)){
|
||||||
|
if(!nointerpolate || !insum){
|
||||||
|
rsum0 += ncpixel_r(rgbas[mask]);
|
||||||
|
gsum0 += ncpixel_g(rgbas[mask]);
|
||||||
|
bsum0 += ncpixel_b(rgbas[mask]);
|
||||||
|
++insum;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if(!nointerpolate || !outsum){
|
||||||
|
rsum1 += ncpixel_r(rgbas[mask]);
|
||||||
|
gsum1 += ncpixel_g(rgbas[mask]);
|
||||||
|
bsum1 += ncpixel_b(rgbas[mask]);
|
||||||
|
++outsum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t l0 = generalerp(rsum0, gsum0, bsum0, insum);
|
||||||
|
uint32_t l1 = generalerp(rsum1, gsum1, bsum1, outsum);
|
||||||
|
uint32_t totaldiff = 0;
|
||||||
|
for(unsigned mask = 0 ; mask < 8 ; ++mask){
|
||||||
|
unsigned r, g, b;
|
||||||
|
if(glyph & (1u << mask)){
|
||||||
|
ncchannel_rgb8(l0, &r, &g, &b);
|
||||||
|
}else{
|
||||||
|
ncchannel_rgb8(l1, &r, &g, &b);
|
||||||
|
}
|
||||||
|
uint32_t rdiff = rgb_diff(ncpixel_r(rgbas[mask]), ncpixel_g(rgbas[mask]),
|
||||||
|
ncpixel_b(rgbas[mask]), r, g, b);
|
||||||
|
totaldiff += rdiff;
|
||||||
|
}
|
||||||
|
if(totaldiff < mindiff){
|
||||||
|
mindiff = totaldiff;
|
||||||
|
best = glyph;
|
||||||
|
ncchannels_set_fchannel(channels, l0);
|
||||||
|
ncchannels_set_bchannel(channels, l1);
|
||||||
|
}
|
||||||
|
if(totaldiff == 0){ // can't beat that!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(best >= 0 && best < 128);
|
||||||
|
if(blendcolors){
|
||||||
|
ncchannels_set_fg_alpha(channels, NCALPHA_BLEND);
|
||||||
|
ncchannels_set_bg_alpha(channels, NCALPHA_BLEND);
|
||||||
|
}
|
||||||
|
return octant_egcs[best];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char*
|
||||||
|
oct_trans_check(nccell* c, const uint32_t rgbas[8], unsigned blendcolors,
|
||||||
|
uint32_t transcolor, unsigned nointerpolate){
|
||||||
|
unsigned transstring = 0;
|
||||||
|
unsigned r = 0, g = 0, b = 0;
|
||||||
|
unsigned div = 0;
|
||||||
|
for(unsigned mask = 0 ; mask < 8 ; ++mask){
|
||||||
|
if(rgba_trans_p(rgbas[mask], transcolor)){
|
||||||
|
transstring |= (1u << mask);
|
||||||
|
}else if(!nointerpolate || !div){
|
||||||
|
r += ncpixel_r(rgbas[mask]);
|
||||||
|
g += ncpixel_g(rgbas[mask]);
|
||||||
|
b += ncpixel_b(rgbas[mask]);
|
||||||
|
++div;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(transstring == 0){ // there was no transparency
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nccell_set_bg_alpha(c, NCALPHA_TRANSPARENT);
|
||||||
|
// there were some transparent pixels. since they get priority, the foreground
|
||||||
|
// is just a general lerp across non-transparent pixels.
|
||||||
|
const char* egc = octant_egcs[transstring ^ 0xff];
|
||||||
|
nccell_set_bg_alpha(c, NCALPHA_TRANSPARENT);
|
||||||
|
//fprintf(stderr, "transtring: %u egc: %s\n", transtring, egc);
|
||||||
|
if(*egc == ' '){ // entirely transparent
|
||||||
|
nccell_set_fg_alpha(c, NCALPHA_TRANSPARENT);
|
||||||
|
return "";
|
||||||
|
}else{ // partially transparent, thus div >= 1
|
||||||
|
//fprintf(stderr, "div: %u r: %u g: %u b: %u\n", div, r, g, b);
|
||||||
|
cell_set_fchannel(c, generalerp(r, g, b, div));
|
||||||
|
if(blendcolors){
|
||||||
|
nccell_set_fg_alpha(c, NCALPHA_BLEND);
|
||||||
|
}
|
||||||
|
cell_set_blitquadrants(c, !(transstring & 5u), !(transstring & 10u),
|
||||||
|
!(transstring & 20u), !(transstring & 40u));
|
||||||
|
}
|
||||||
|
//fprintf(stderr, "OCT-BQ: 0x%x\n", cell_blittedquadrants(c));
|
||||||
|
return egc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// octant blitter. maps 4x2 to each cell. since we only have two colors at
|
||||||
|
// our disposal (foreground and background), we lose some fidelity.
|
||||||
|
static inline int
|
||||||
|
octant_blit(ncplane* nc, int linesize, const void* data, int leny, int lenx,
|
||||||
|
const blitterargs* bargs){
|
||||||
|
const unsigned nointerpolate = bargs->flags & NCVISUAL_OPTION_NOINTERPOLATE;
|
||||||
|
const bool blendcolors = bargs->flags & NCVISUAL_OPTION_BLEND;
|
||||||
|
unsigned dimy, dimx, x, y;
|
||||||
|
int total = 0; // number of cells written
|
||||||
|
ncplane_dim_yx(nc, &dimy, &dimx);
|
||||||
|
//fprintf(stderr, "octblitter %dx%d -> %d/%d+%d/%d\n", leny, lenx, dimy, dimx, bargs->u.cell.placey, bargs->u.cell.placex);
|
||||||
|
const unsigned char* dat = data;
|
||||||
|
int visy = bargs->begy;
|
||||||
|
for(y = bargs->u.cell.placey ; visy < (bargs->begy + leny) && y < dimy ; ++y, visy += 4){
|
||||||
|
if(ncplane_cursor_move_yx(nc, y, bargs->u.cell.placex < 0 ? 0 : bargs->u.cell.placex)){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int visx = bargs->begx;
|
||||||
|
for(x = bargs->u.cell.placex ; visx < (bargs->begx + lenx) && x < dimx ; ++x, visx += 2){
|
||||||
|
uint32_t rgbas[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
memcpy(&rgbas[0], (dat + (linesize * visy) + (visx * 4)), sizeof(*rgbas));
|
||||||
|
if(visx < bargs->begx + lenx - 1){
|
||||||
|
memcpy(&rgbas[1], (dat + (linesize * visy) + ((visx + 1) * 4)), sizeof(*rgbas));
|
||||||
|
if(visy < bargs->begy + leny - 1){
|
||||||
|
memcpy(&rgbas[3], (dat + (linesize * (visy + 1)) + ((visx + 1) * 4)), sizeof(*rgbas));
|
||||||
|
if(visy < bargs->begy + leny - 2){
|
||||||
|
memcpy(&rgbas[5], (dat + (linesize * (visy + 2)) + ((visx + 1) * 4)), sizeof(*rgbas));
|
||||||
|
if(visy < bargs->begy + leny - 3){
|
||||||
|
memcpy(&rgbas[7], (dat + (linesize * (visy + 3)) + ((visx + 1) * 4)), sizeof(*rgbas));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(visy < bargs->begy + leny - 1){
|
||||||
|
memcpy(&rgbas[2], (dat + (linesize * (visy + 1)) + (visx * 4)), sizeof(*rgbas));
|
||||||
|
if(visy < bargs->begy + leny - 2){
|
||||||
|
memcpy(&rgbas[4], (dat + (linesize * (visy + 2)) + (visx * 4)), sizeof(*rgbas));
|
||||||
|
if(visy < bargs->begy + leny - 3){
|
||||||
|
memcpy(&rgbas[6], (dat + (linesize * (visy + 3)) + (visx * 4)), sizeof(*rgbas));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nccell* c = ncplane_cell_ref_yx(nc, y, x);
|
||||||
|
c->channels = 0;
|
||||||
|
c->stylemask = 0;
|
||||||
|
const char* egc = oct_trans_check(c, rgbas, blendcolors, bargs->transcolor, nointerpolate);
|
||||||
|
if(egc == NULL){ // no transparency; run a full solver
|
||||||
|
egc = oct_solver(rgbas, &c->channels, blendcolors, nointerpolate);
|
||||||
|
cell_set_blitquadrants(c, 1, 1, 1, 1);
|
||||||
|
}
|
||||||
|
//fprintf(stderr, "oct EGC: %s channels: %016lx\n", egc, c->channels);
|
||||||
|
if(*egc){
|
||||||
|
if(pool_blit_direct(&nc->pool, c, egc, strlen(egc), 1) <= 0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
++total;
|
||||||
|
}else{
|
||||||
|
nccell_release(nc, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
// fold the r, g, and b components of the pixel into *r, *g, and *b, and
|
// fold the r, g, and b components of the pixel into *r, *g, and *b, and
|
||||||
// increment *foldcount
|
// increment *foldcount
|
||||||
static inline void
|
static inline void
|
||||||
@ -867,6 +1309,34 @@ static struct blitset notcurses_blitters[] = {
|
|||||||
{ .geom = NCBLIT_3x2, .width = 2, .height = 3,
|
{ .geom = NCBLIT_3x2, .width = 2, .height = 3,
|
||||||
.egcs = NCSEXBLOCKS, .plotegcs = L" 🬞🬦▐🬏🬭🬵🬷🬓🬱🬹🬻▌🬲🬺█",
|
.egcs = NCSEXBLOCKS, .plotegcs = L" 🬞🬦▐🬏🬭🬵🬷🬓🬱🬹🬻▌🬲🬺█",
|
||||||
.blit = sextant_blit, .name = "sex", .fill = false, },
|
.blit = sextant_blit, .name = "sex", .fill = false, },
|
||||||
|
{ .geom = NCBLIT_4x2, .width = 2, .height = 4,
|
||||||
|
.egcs = NCOCTBLOCKS,
|
||||||
|
.plotegcs = (L"\0x20"
|
||||||
|
L"\U0001cea0"
|
||||||
|
L"\U00002597"
|
||||||
|
L"\U0001CD96"
|
||||||
|
L"\U0001CD91"
|
||||||
|
L"\U0001CEA3"
|
||||||
|
L"\U00002582"
|
||||||
|
L"\U0001CDCB"
|
||||||
|
L"\U0001CDD3"
|
||||||
|
L"\U0001CDCD"
|
||||||
|
L"\U00002596"
|
||||||
|
L"\U0001CDBB"
|
||||||
|
L"\U00002584"
|
||||||
|
L"\U0001CDE1"
|
||||||
|
L"\U0001CDDC"
|
||||||
|
L"\U0001CD48"
|
||||||
|
L"\U0001CDBF"
|
||||||
|
L"\U0001CDDE"
|
||||||
|
L"\U00002586"
|
||||||
|
L"\U0001CDDF"
|
||||||
|
L"\U0000258C"
|
||||||
|
L"\U0001CDC0"
|
||||||
|
L"\U00002599"
|
||||||
|
L"\U0001CDE4"
|
||||||
|
L"\U0001CDE0"),
|
||||||
|
.blit = octant_blit, .name = "oct", .fill = false, },
|
||||||
{ .geom = NCBLIT_BRAILLE, .width = 2, .height = 4,
|
{ .geom = NCBLIT_BRAILLE, .width = 2, .height = 4,
|
||||||
.egcs = NCBRAILLEEGCS,
|
.egcs = NCBRAILLEEGCS,
|
||||||
.plotegcs = L"⠀⢀⢠⢰⢸⡀⣀⣠⣰⣸⡄⣄⣤⣴⣼⡆⣆⣦⣶⣾⡇⣇⣧⣷⣿",
|
.plotegcs = L"⠀⢀⢠⢰⢸⡀⣀⣠⣰⣸⡄⣄⣤⣴⣼⡆⣆⣦⣶⣾⡇⣇⣧⣷⣿",
|
||||||
@ -898,13 +1368,22 @@ const struct blitset* lookup_blitset(const tinfo* tcache, ncblitter_e setid,
|
|||||||
if(setid == NCBLIT_DEFAULT){ // ought have resolved NCBLIT_DEFAULT before now
|
if(setid == NCBLIT_DEFAULT){ // ought have resolved NCBLIT_DEFAULT before now
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// without braille support, NCBLIT_BRAILLE decays to NCBLIT_3x2
|
// without braille support, NCBLIT_BRAILLE decays to NCBLIT_4x2
|
||||||
if(setid == NCBLIT_BRAILLE){
|
if(setid == NCBLIT_BRAILLE){
|
||||||
if(tcache->caps.braille){
|
if(tcache->caps.braille){
|
||||||
return ¬curses_blitters[setid - 1];
|
return ¬curses_blitters[setid - 1];
|
||||||
}else if(!may_degrade){
|
}else if(!may_degrade){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
setid = NCBLIT_4x2;
|
||||||
|
}
|
||||||
|
// without octant support, NCBLIT_4x2 decays to NCBLIT_3x2
|
||||||
|
if(setid == NCBLIT_4x2){
|
||||||
|
if(tcache->caps.octants){
|
||||||
|
return ¬curses_blitters[setid - 1];
|
||||||
|
}else if(!may_degrade){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
setid = NCBLIT_3x2;
|
setid = NCBLIT_3x2;
|
||||||
}
|
}
|
||||||
// without bitmap support, NCBLIT_PIXEL decays to NCBLIT_3x2
|
// without bitmap support, NCBLIT_PIXEL decays to NCBLIT_3x2
|
||||||
|
@ -32,6 +32,9 @@ rgba_blitter_default(const tinfo* tcache, ncscale_e scale){
|
|||||||
if(!tcache->caps.utf8){
|
if(!tcache->caps.utf8){
|
||||||
return NCBLIT_1x1; // only one that works in ASCII
|
return NCBLIT_1x1; // only one that works in ASCII
|
||||||
}
|
}
|
||||||
|
if(tcache->caps.octants){
|
||||||
|
return NCBLIT_4x2;
|
||||||
|
}
|
||||||
if(scale == NCSCALE_NONE || scale == NCSCALE_SCALE){
|
if(scale == NCSCALE_NONE || scale == NCSCALE_SCALE){
|
||||||
return NCBLIT_2x1;
|
return NCBLIT_2x1;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ int main(int argc, char** argv){
|
|||||||
NCBLIT_2x1, // full/(upper|left) blocks
|
NCBLIT_2x1, // full/(upper|left) blocks
|
||||||
NCBLIT_2x2, // quadrants
|
NCBLIT_2x2, // quadrants
|
||||||
NCBLIT_3x2, // sextants
|
NCBLIT_3x2, // sextants
|
||||||
|
NCBLIT_4x2, // octants
|
||||||
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille)
|
NCBLIT_BRAILLE, // 4 rows, 2 cols (braille)
|
||||||
NCBLIT_PIXEL, // pixel graphics
|
NCBLIT_PIXEL, // pixel graphics
|
||||||
-1,
|
-1,
|
||||||
|
@ -10,6 +10,7 @@ TEST_CASE("Blit") {
|
|||||||
|
|
||||||
SUBCASE("BlitterStrings") {
|
SUBCASE("BlitterStrings") {
|
||||||
CHECK(0 == strcmp("pixel", notcurses_str_blitter(NCBLIT_PIXEL)));
|
CHECK(0 == strcmp("pixel", notcurses_str_blitter(NCBLIT_PIXEL)));
|
||||||
|
CHECK(0 == strcmp("oct", notcurses_str_blitter(NCBLIT_4x2)));
|
||||||
CHECK(0 == strcmp("sex", notcurses_str_blitter(NCBLIT_3x2)));
|
CHECK(0 == strcmp("sex", notcurses_str_blitter(NCBLIT_3x2)));
|
||||||
CHECK(0 == strcmp("quad", notcurses_str_blitter(NCBLIT_2x2)));
|
CHECK(0 == strcmp("quad", notcurses_str_blitter(NCBLIT_2x2)));
|
||||||
CHECK(0 == strcmp("half", notcurses_str_blitter(NCBLIT_2x1)));
|
CHECK(0 == strcmp("half", notcurses_str_blitter(NCBLIT_2x1)));
|
||||||
|
@ -256,6 +256,33 @@ TEST_CASE("Plot") {
|
|||||||
ncuplot_destroy(p);
|
ncuplot_destroy(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("Octantlot1Row") {
|
||||||
|
ncplane_options nopts = {
|
||||||
|
.y = 1, .x = 1, .rows = 1, .cols = 25,
|
||||||
|
.userptr = nullptr, .name = "plot", .resizecb = nullptr, .flags = 0,
|
||||||
|
.margin_b = 0, .margin_r = 0,
|
||||||
|
};
|
||||||
|
auto ncp = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(ncp);
|
||||||
|
ncplot_options popts;
|
||||||
|
memset(&popts, 0, sizeof(popts));
|
||||||
|
popts.maxchannels = NCCHANNELS_INITIALIZER(0xff, 0xff, 0xff, 0, 0, 0);
|
||||||
|
popts.minchannels = NCCHANNELS_INITIALIZER(0, 0xff, 0, 0, 0, 0);
|
||||||
|
ncchannels_set_bg_alpha(&popts.minchannels, NCALPHA_BLEND);
|
||||||
|
ncchannels_set_fg_alpha(&popts.minchannels, NCALPHA_BLEND);
|
||||||
|
popts.gridtype = NCBLIT_4x2;
|
||||||
|
auto p = ncuplot_create(ncp, &popts, 0, 0);
|
||||||
|
REQUIRE(p);
|
||||||
|
for(auto i = 0 ; i < 5 ; ++i){
|
||||||
|
for(auto j = 0 ; j < 5 ; ++j){
|
||||||
|
CHECK(0 == ncuplot_add_sample(p, i * 10 + j * 2, i));
|
||||||
|
CHECK(0 == ncuplot_add_sample(p, i * 10 + j * 2 + 1, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK(0 == notcurses_render(nc_));
|
||||||
|
ncuplot_destroy(p);
|
||||||
|
}
|
||||||
|
|
||||||
SUBCASE("BraillePlot1Row") {
|
SUBCASE("BraillePlot1Row") {
|
||||||
ncplane_options nopts = {
|
ncplane_options nopts = {
|
||||||
.y = 1, .x = 1, .rows = 1, .cols = 25,
|
.y = 1, .x = 1, .rows = 1, .cols = 25,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user