From 8d22f4618fe546d8ac22f3a27289aa4c6bd8c921 Mon Sep 17 00:00:00 2001 From: nick black Date: Thu, 3 Jun 2021 07:16:43 -0400 Subject: [PATCH] lookup_blitset: replace O(N) loop with O(1) access --- include/notcurses/notcurses.h | 3 ++- src/lib/blit.c | 37 +++++++++++++++++++++-------------- src/lib/internal.h | 2 ++ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index 3672543dd..54ed00b4a 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -59,7 +59,8 @@ struct nctab; // grouped item within an nctabbed struct nctabbed; // widget with one tab visible at a time // we never blit full blocks, but instead spaces (more efficient) with the -// background set to the desired foreground. +// background set to the desired foreground. these need be kept in the same +// order as the blitters[] definition in lib/blit.c. typedef enum { NCBLIT_DEFAULT, // let the ncvisual pick NCBLIT_1x1, // space, compatible with ASCII diff --git a/src/lib/blit.c b/src/lib/blit.c index c19beb77b..2f00bafb3 100644 --- a/src/lib/blit.c +++ b/src/lib/blit.c @@ -853,11 +853,9 @@ braille_blit(ncplane* nc, int linesize, const void* data, // The order of contents is critical for 'egcs': ncplane_as_rgba() uses these // arrays to map cells to source pixels. Map the upper-left logical bit to // 1, and increase to the right, followed by down. The first egc ought thus -// always be space, to indicate an empty cell (all zeroes). +// always be space, to indicate an empty cell (all zeroes). These need be +// kept in the same order as the enums! static struct blitset notcurses_blitters[] = { - { .geom = NCBLIT_8x1, .width = 1, .height = 8, - .egcs = NULL, .plotegcs = L" ▁▂▃▄▅▆▇█", - .blit = tria_blit, .name = "eightstep", .fill = false, }, { .geom = NCBLIT_1x1, .width = 1, .height = 1, .egcs = L" █", .plotegcs = L" █", .blit = tria_blit_ascii,.name = "ascii", .fill = false, }, @@ -871,20 +869,35 @@ static struct blitset notcurses_blitters[] = { .egcs = L" 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓▌🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻█", .plotegcs = L" 🬞🬦▐🬏🬭🬵🬷🬓🬱🬹🬻▌🬲🬺█", .blit = sextant_blit, .name = "sex", .fill = false, }, - { .geom = NCBLIT_4x1, .width = 1, .height = 4, - .egcs = NULL, .plotegcs = L" ▂▄▆█", - .blit = tria_blit, .name = "fourstep", .fill = false, }, { .geom = NCBLIT_BRAILLE, .width = 2, .height = 4, .egcs = NULL, .plotegcs = L"⠀⢀⢠⢰⢸⡀⣀⣠⣰⣸⡄⣄⣤⣴⣼⡆⣆⣦⣶⣾⡇⣇⣧⣷⣿", // FIXME .blit = braille_blit, .name = "braille", .fill = true, }, { .geom = NCBLIT_PIXEL, .width = 1, .height = 1, .egcs = L"", .plotegcs = NULL, .blit = sixel_blit, .name = "pixel", .fill = true, }, + { .geom = NCBLIT_4x1, .width = 1, .height = 4, + .egcs = NULL, .plotegcs = L" ▂▄▆█", + .blit = tria_blit, .name = "fourstep", .fill = false, }, + { .geom = NCBLIT_8x1, .width = 1, .height = 8, + .egcs = NULL, .plotegcs = L" ▁▂▃▄▅▆▇█", + .blit = tria_blit, .name = "eightstep", .fill = false, }, { .geom = 0, .width = 0, .height = 0, .egcs = NULL, .plotegcs = NULL, .blit = NULL, .name = NULL, .fill = false, }, }; +const wchar_t* +get_blitter_egcs(ncblitter_e id){ + if(id == NCBLIT_DEFAULT){ + return NULL; + } + // prefer the egcs set, but return plotegcs otherwise + if(notcurses_blitters[id - 1].egcs){ + return notcurses_blitters[id - 1].egcs; + } + return notcurses_blitters[id - 1].plotegcs; +} + void set_pixel_blitter(ncblitter blitfxn){ struct blitset* b = notcurses_blitters; while(b->geom != NCBLIT_PIXEL){ @@ -937,14 +950,8 @@ const struct blitset* lookup_blitset(const tinfo* tcache, ncblitter_e setid, boo return NULL; } } - const struct blitset* bset = notcurses_blitters; - while(bset->geom){ - if(bset->geom == setid){ - return bset; - } - ++bset; - } - return NULL; + assert(setid == notcurses_blitters[setid - 1].geom); + return ¬curses_blitters[setid - 1]; } int notcurses_lex_blitter(const char* op, ncblitter_e* blitfxn){ diff --git a/src/lib/internal.h b/src/lib/internal.h index d79697ddc..098a25eab 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -1594,6 +1594,8 @@ rgba_blitter_low(const tinfo* tcache, ncscale_e scale, bool maydegrade, return lookup_blitset(tcache, blitrec, maydegrade); } +const wchar_t* get_blitter_egcs(ncblitter_e id); + // RGBA visuals all use NCBLIT_2x1 by default (or NCBLIT_1x1 if not in // UTF-8 mode), but an alternative can be specified. static inline const struct blitset*