diff --git a/examples/termbox2-demo/CMakeLists.txt b/examples/termbox2-demo/CMakeLists.txt index 4dbbb3d..1418be9 100644 --- a/examples/termbox2-demo/CMakeLists.txt +++ b/examples/termbox2-demo/CMakeLists.txt @@ -8,16 +8,26 @@ set(FETCHCONTENT_QUIET FALSE) FetchContent_Declare( termbox2 GIT_REPOSITORY "https://github.com/termbox/termbox2.git" - GIT_TAG "8ee9dc17e1ca61c630f91db0aa7f81fa29a32040" + GIT_TAG "9c9281a9a4c971a2be57f8645e828ec99fd555e8" GIT_PROGRESS TRUE GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(termbox2) +FetchContent_Declare( + stb + GIT_REPOSITORY "https://github.com/nothings/stb.git" + GIT_TAG "f58f558c120e9b32c217290b80bad1a0729fbb2c" + GIT_PROGRESS TRUE + GIT_SHALLOW TRUE +) +FetchContent_MakeAvailable(stb) + add_executable(clay_examples_termbox2_demo main.c) target_compile_options(clay_examples_termbox2_demo PUBLIC) -target_include_directories(clay_examples_termbox2_demo PUBLIC . PRIVATE ${termbox2_SOURCE_DIR}) +target_include_directories(clay_examples_termbox2_demo PUBLIC . PRIVATE ${termbox2_SOURCE_DIR} PRIVATE ${stb_SOURCE_DIR}) +target_link_libraries(clay_examples_termbox2_demo PRIVATE m) # Used by stb_image.h add_custom_command( TARGET clay_examples_termbox2_demo POST_BUILD diff --git a/examples/termbox2-demo/main.c b/examples/termbox2-demo/main.c index 4300f9c..a4ac094 100644 --- a/examples/termbox2-demo/main.c +++ b/examples/termbox2-demo/main.c @@ -36,14 +36,11 @@ #define TB_IMPL #include "termbox2.h" +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" -// ------------------------------------------------------------------------------------------------- -// -- Data structures - -typedef struct { - unsigned char *data; - long size; -} image; +#define STB_IMAGE_RESIZE_IMPLEMENTATION +#include "stb_image_resize2.h" // ------------------------------------------------------------------------------------------------- @@ -56,94 +53,6 @@ bool end_loop = false; bool debugMode = false; -// ------------------------------------------------------------------------------------------------- -// -- Internal utility functions - -/** - Load an image into memory as bytes - - \param filename Filepath to image to be loaded - */ -image load_image(const char *filename) -{ - image rv = { .data = NULL, .size = 0 }; - - if (NULL == filename) { - return rv; - } - - FILE *image_file = NULL; - - image_file = fopen(filename, "r"); - if (NULL == image_file) { - fprintf(stderr, "Failed to open image %s: %s\n", filename, strerror(errno)); - return rv; - } - - int err = fseek(image_file, 0, SEEK_END); - if (-1 == err) { - fprintf(stderr, "Failed to seek image %s: %s\n", filename, strerror(errno)); - goto done; - } - - long image_size = ftell(image_file); - if (-1 == image_size) { - fprintf(stderr, "Failed to get filesize for image %s: %s\n", filename, strerror(errno)); - goto done; - } - rewind(image_file); - - unsigned char *image_data = malloc(image_size); - if (NULL == image_data) { - fprintf(stderr, "Failed to allocate memory for image %s: %s\n", filename, strerror(errno)); - goto done; - } - - size_t written = fread(image_data, image_size, 1, image_file); - if (1 != written) { - fprintf(stderr, "Failed to load image %s into memory: %s\n", filename, strerror(errno)); - goto error_read; - } - - rv.data = image_data; - rv.size = image_size; - goto done; - -error_read: - free(image_data); -done: - fclose(image_file); - return rv; -} - -/** - Free an image from memory - - \param image Image to free - */ -void free_image(image image) -{ - free(image.data); - image.data = NULL; - image.size = 0; -} - -/** - Block until an event is received for termbox - */ -void termbox_waitfor_event(void) -{ - int termbox_ttyfd, termbox_resizefd; - tb_get_fds(&termbox_ttyfd, &termbox_resizefd); - int nfds = CLAY__MAX(termbox_ttyfd, termbox_resizefd) + 1; - fd_set monitor_set; - FD_ZERO(&monitor_set); - FD_SET(termbox_ttyfd, &monitor_set); - FD_SET(termbox_resizefd, &monitor_set); - select(nfds, &monitor_set, NULL, NULL, NULL); -} - - // ------------------------------------------------------------------------------------------------- // -- Clay components @@ -166,7 +75,7 @@ void component_text_pair(const char *key, const char *value) .sizing = { .width = { .size.minMax = { - .min = strlen("Border chars CLAY_TB_BORDER_CHARS_UNICODE") * Clay_Termbox_Cell_Width(), + .min = strlen("Border chars CLAY_TB_IMAGE_MODE_UNICODE_FAST") * Clay_Termbox_Cell_Width(), } }, } @@ -247,7 +156,7 @@ void component_termbox_settings(void) break; } default: { - color_mode = "INVALID"; + border_mode = "INVALID"; break; } } @@ -274,6 +183,45 @@ void component_termbox_settings(void) break; } } + const char *image_mode = NULL; + switch (clay_tb_image_mode) { + case CLAY_TB_IMAGE_MODE_PLACEHOLDER: { + image_mode = "CLAY_TB_IMAGE_MODE_PLACEHOLDER"; + break; + } + case CLAY_TB_IMAGE_MODE_BG: { + image_mode = "CLAY_TB_IMAGE_MODE_BG"; + break; + } + case CLAY_TB_IMAGE_MODE_ASCII_FG: { + image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FG"; + break; + } + case CLAY_TB_IMAGE_MODE_ASCII_FG_FAST: { + image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FG_FAST"; + break; + } + case CLAY_TB_IMAGE_MODE_ASCII: { + image_mode = "CLAY_TB_IMAGE_MODE_ASCII"; + break; + } + case CLAY_TB_IMAGE_MODE_ASCII_FAST: { + image_mode = "CLAY_TB_IMAGE_MODE_ASCII_FAST"; + break; + } + case CLAY_TB_IMAGE_MODE_UNICODE: { + image_mode = "CLAY_TB_IMAGE_MODE_UNICODE"; + break; + } + case CLAY_TB_IMAGE_MODE_UNICODE_FAST: { + image_mode = "CLAY_TB_IMAGE_MODE_UNICODE_FAST"; + break; + } + default: { + image_mode = "INVALID"; + break; + } + } const char *transparency = NULL; if (clay_tb_transparency) { transparency = "true"; @@ -287,6 +235,7 @@ void component_termbox_settings(void) component_text_pair("Color mode", color_mode); component_text_pair("Border mode", border_mode); component_text_pair("Border chars", border_chars); + component_text_pair("Image mode", image_mode); component_text_pair("Transparency", transparency); } } @@ -448,6 +397,7 @@ void component_keybinds(void) " c/C - Cycle through color modes\n" " b/B - Cycle through border modes\n" " h/H - Cycle through border characters\n" + " i/I - Cycle through image modes\n" " t/T - Toggle transparency\n" " d/D - Toggle debug mode\n" " q/Q - Quit\n" @@ -457,19 +407,18 @@ void component_keybinds(void) } } -void component_image(image image) +void component_image(clay_tb_image *image, int width) { CLAY({ .layout = { .sizing = { - .width = CLAY_SIZING_FIXED(200), - .height = CLAY_SIZING_FIXED(200), + .width = (0 == width) ? CLAY_SIZING_GROW() : CLAY_SIZING_FIXED(width), }, }, .image = { - .imageData = &image, - .sourceDimensions = { 512, 512 } - } + .imageData = image, + }, + .aspectRatio = { 512.0 / 406.0 } }) { } } @@ -477,7 +426,6 @@ void component_mouse_data(void) { CLAY({ .layout = { - //.layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { .width = CLAY_SIZING_GROW(), }, @@ -557,7 +505,7 @@ void component_bordered_text(void) } } -Clay_RenderCommandArray CreateLayout(image image) +Clay_RenderCommandArray CreateLayout(clay_tb_image *image1, clay_tb_image *image2) { Clay_BeginLayout(); CLAY({ @@ -594,8 +542,8 @@ Clay_RenderCommandArray CreateLayout(image image) }, }) { component_termbox_settings(); - component_image(image); - component_image(image); + component_image(image1, 150); + component_image(image2, 0); component_mouse_data(); component_bordered_text(); } @@ -627,7 +575,7 @@ void handle_termbox_events(void) // responsiveness (but will of course prevent other code from running on this thread while it's // waiting) struct tb_event evt; - int ms_to_wait = 100; + int ms_to_wait = 0; int err = tb_peek_event(&evt, ms_to_wait); switch (err) { @@ -714,6 +662,23 @@ void handle_termbox_events(void) Clay_Termbox_Set_Border_Chars(new_chars); break; } + case 'i': { + enum image_mode new_mode = clay_tb_image_mode - 1; + new_mode = (CLAY_TB_IMAGE_MODE_DEFAULT < new_mode) + ? new_mode + : CLAY_TB_IMAGE_MODE_UNICODE_FAST; + Clay_Termbox_Set_Image_Mode(new_mode); + break; + } + case 'I': { + enum image_mode new_mode = (clay_tb_image_mode + 1) + % (CLAY_TB_IMAGE_MODE_UNICODE_FAST + 1); + new_mode = (CLAY_TB_IMAGE_MODE_DEFAULT < new_mode) + ? new_mode + : CLAY_TB_IMAGE_MODE_PLACEHOLDER; + Clay_Termbox_Set_Image_Mode(new_mode); + break; + } case 't': case 'T': { Clay_Termbox_Set_Transparency(!clay_tb_transparency); @@ -775,8 +740,10 @@ void handle_termbox_events(void) int main(void) { - image shark_image = load_image("resources/512px-Shark_antwerp_zoo.jpeg"); - if (NULL == shark_image.data) { exit(1); } + clay_tb_image shark_image1 = Clay_Termbox_Image_Load_File("resources/512px-Shark_antwerp_zoo.jpeg"); + clay_tb_image shark_image2 = Clay_Termbox_Image_Load_File("resources/512px-Shark_antwerp_zoo.jpeg"); + if (NULL == shark_image1.pixel_data) { exit(1); } + if (NULL == shark_image2.pixel_data) { exit(1); } int num_elements = 3 * 8192; Clay_SetMaxElementCount(num_elements); @@ -788,7 +755,7 @@ int main(void) Clay_Arena clay_arena = Clay_CreateArenaWithCapacityAndMemory(size, memory); Clay_Termbox_Initialize( - TB_OUTPUT_256, CLAY_TB_BORDER_MODE_DEFAULT, CLAY_TB_BORDER_CHARS_DEFAULT, false); + TB_OUTPUT_256, CLAY_TB_BORDER_MODE_DEFAULT, CLAY_TB_BORDER_CHARS_DEFAULT, CLAY_TB_IMAGE_MODE_DEFAULT, false); Clay_Initialize(clay_arena, (Clay_Dimensions) { Clay_Termbox_Width(), Clay_Termbox_Height() }, (Clay_ErrorHandler) { handle_clay_errors, NULL }); @@ -796,18 +763,18 @@ int main(void) Clay_SetMeasureTextFunction(Clay_Termbox_MeasureText, NULL); // Initial render before waiting for events - Clay_RenderCommandArray commands = CreateLayout(shark_image); + Clay_RenderCommandArray commands = CreateLayout(&shark_image1, &shark_image2); Clay_Termbox_Render(commands); tb_present(); while (!end_loop) { // Block until event is available. Optional, but reduces load since this demo is purely // synchronous to user input. - termbox_waitfor_event(); + Clay_Termbox_Waitfor_Event(); handle_termbox_events(); - commands = CreateLayout(shark_image); + commands = CreateLayout(&shark_image1, &shark_image2); tb_clear(); Clay_Termbox_Render(commands); @@ -815,7 +782,8 @@ int main(void) } Clay_Termbox_Close(); - free_image(shark_image); + Clay_Termbox_Image_Free(&shark_image1); + Clay_Termbox_Image_Free(&shark_image2); free(memory); return 0; } diff --git a/examples/termbox2-demo/readme.md b/examples/termbox2-demo/readme.md index 4a8f305..0c1ecd6 100644 --- a/examples/termbox2-demo/readme.md +++ b/examples/termbox2-demo/readme.md @@ -11,6 +11,7 @@ Keybinds: c/C - Cycle through color modes b/B - Cycle through border modes h/H - Cycle through border characters +i/I - Cycle through image modes t/T - Toggle transparency d/D - Toggle debug mode q/Q - Quit @@ -29,6 +30,16 @@ Configuration can be also be overriden by environment variables: - `ASCII` - `UNICODE` - `NONE` +- `CLAY_TB_IMAGE_MODE` + - `DEFAULT` + - `PLACEHOLDER` + - `BG` + - `ASCII_FG` + - `ASCII` + - `UNICODE` + - `ASCII_FG_FAST` + - `ASCII_FAST` + - `UNICODE_FAST` - `CLAY_TB_TRANSPARENCY` - `1` - `0` diff --git a/renderers/termbox2/clay_renderer_termbox2.c b/renderers/termbox2/clay_renderer_termbox2.c index 6e36d29..338b88b 100644 --- a/renderers/termbox2/clay_renderer_termbox2.c +++ b/renderers/termbox2/clay_renderer_termbox2.c @@ -25,9 +25,13 @@ #include "../../clay.h" +#include "image_character_masks.h" + #define TB_OPT_ATTR_W 32 // Required for truecolor support #include "termbox2.h" +#include "stb_image.h" +#include "stb_image_resize2.h" // ------------------------------------------------------------------------------------------------- // -- Data structures @@ -48,7 +52,7 @@ typedef struct { typedef struct { Clay_Color clay; uintattr_t termbox; -} color_pair; +} clay_tb_color_pair; enum border_mode { CLAY_TB_BORDER_MODE_DEFAULT, @@ -64,6 +68,45 @@ enum border_chars { CLAY_TB_BORDER_CHARS_NONE, }; +enum image_mode { + CLAY_TB_IMAGE_MODE_DEFAULT, + CLAY_TB_IMAGE_MODE_PLACEHOLDER, + CLAY_TB_IMAGE_MODE_BG, + CLAY_TB_IMAGE_MODE_ASCII_FG, + CLAY_TB_IMAGE_MODE_ASCII_FG_FAST, + CLAY_TB_IMAGE_MODE_ASCII, + CLAY_TB_IMAGE_MODE_ASCII_FAST, + CLAY_TB_IMAGE_MODE_UNICODE, + CLAY_TB_IMAGE_MODE_UNICODE_FAST, +}; + +typedef struct { + // Stores information about image loaded from stb + int pixel_width, pixel_height; + unsigned char *pixel_data; + + // Internal cached data from previous renders + struct { + enum image_mode last_image_mode; + int width, height; + size_t size_max; + uint32_t *characters; + Clay_Color *foreground; + Clay_Color *background; + + // Data storing progress of partially complete image conversions that take multiple renders + struct clay_tb_partial_render { + bool in_progress; + unsigned char *resized_pixel_data; + int cursor_x, cursor_y; + int cursor_mask; + int min_difference_squared_sum; + int best_mask; + Clay_Color best_foreground, best_background; + } partial_render; + } internal; +} clay_tb_image; + // Truecolor is only enabled if TB_OPT_ATTR_W is set to 32 or 64. The default is 16, so it must be // defined to reference the constant #ifndef TB_OUTPUT_TRUECOLOR @@ -139,6 +182,49 @@ void Clay_Termbox_Set_Border_Mode(enum border_mode border_mode); */ void Clay_Termbox_Set_Border_Chars(enum border_chars border_chars); +/** + Sets the method for drawing images + + \param image_mode Method for adjusting border sizes to fit terminal cells + - CLAY_TB_IMAGE_MODE_DEFAULT - same as CLAY_TB_IMAGE_MODE_UNICODE + - CLAY_TB_IMAGE_MODE_PLACEHOLDER - Draw a placeholder pattern in place of + images + - CLAY_TB_IMAGE_MODE_BG - Draw image by setting the background color + for space characters + - CLAY_TB_IMAGE_MODE_ASCII_FG - Draw image by setting the foreground color + for ascii characters + - CLAY_TB_IMAGE_MODE_ASCII - Draw image by setting the foreground and + background colors for ascii characters + - CLAY_TB_IMAGE_MODE_UNICODE - Draw image by setting the foreground and + background colors for unicode characters + - CLAY_TB_IMAGE_MODE_ASCII_FG_FAST - Draw image by setting the foreground color + for ascii characters. Checks fewer + characters to draw faster + - CLAY_TB_IMAGE_MODE_ASCII_FAST - Draw image by setting the foreground and + background colors for ascii characters. + Checks fewer characters to draw faster + - CLAY_TB_IMAGE_MODE_UNICODE_FAST - Draw image by setting the foreground and + background colors for unicode characters. + Checks fewer characters to draw faster + */ +void Clay_Termbox_Set_Image_Mode(enum image_mode image_mode); + +/** + Fuel corresponds to the amount of time spent per render on drawing images. Increasing this has + the image render faster, but the program will be less responsive until it finishes + + Cost to draw one cell (lengths of arrays in image_character_masks.h): + - 1 : CLAY_TB_IMAGE_MODE_BG + - 15 : CLAY_TB_IMAGE_MODE_UNICODE_FAST, CLAY_TB_IMAGE_MODE_ASCII_FAST, + CLAY_TB_IMAGE_MODE_ASCII_FG_FAST + - 52 : CLAY_TB_IMAGE_MODE_UNICODE + - 95 : CLAY_TB_IMAGE_MODE_ASCII, CLAY_TB_IMAGE_MODE_ASCII_FG + + \param fuel_max Maximum amount of fuel used per render (shared between all images) + \param fuel_per_image Maximum amount of fuel used per render per image + */ +void Clay_Termbox_Set_Image_Fuel(int fuel_max, int fuel_per_image); + /** Enables or disables emulated transparency @@ -178,6 +264,40 @@ float Clay_Termbox_Cell_Height(void); static inline Clay_Dimensions Clay_Termbox_MeasureText( Clay_StringSlice text, Clay_TextElementConfig *config, void *userData); +/** + Load an image from a file into a format usable with this renderer + + Supports image formats from stb_image (JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC) + + Note that rendered characters are cached in the returned `clay_tb_image`. If the same image is + used in multiple places, load it a separate time for each use to reduce unecessary reprocessing + every render. + + \param filename File to load image from + */ +clay_tb_image Clay_Termbox_Image_Load_File(const char *filename); + +/** + Load an image from memory into a format usable with this renderer + + Supports image formats from stb_image (JPG, PNG, TGA, BMP, PSD, GIF, HDR, PIC) + + Note that rendered characters are cached in the returned `clay_tb_image`. If the same image is + used in multiple places, load it a separate time for each use to reduce unecessary reprocessing + every render. + + \param image Image to load. Should be the whole file copied into memory + \param size Size of the image in bytes + */ +clay_tb_image Clay_Termbox_Image_Load_Memory(const void *image, int size); + +/** + Free an image + + \param image Image to free + */ +void Clay_Termbox_Image_Free(clay_tb_image *image); + /** Set up configuration, start termbox2, and allocate internal structures. @@ -195,6 +315,16 @@ static inline Clay_Dimensions Clay_Termbox_MeasureText( - UNICODE - BLANK - NONE + - CLAY_TB_IMAGE_MODE + - DEFAULT + - PLACEHOLDER + - BG + - ASCII_FG + - ASCII + - UNICODE + - ASCII_FG_FAST + - ASCII_FAST + - UNICODE_FAST - CLAY_TB_TRANSPARENCY - 1 - 0 @@ -206,10 +336,11 @@ static inline Clay_Dimensions Clay_Termbox_MeasureText( \param color_mode Termbox output mode as defined in termbox2.h, excluding truecolor \param border_mode Method for adjusting border sizes to fit terminal cells \param border_chars Characters used for rendering borders + \param image_mode Method for drawing images \param transparency Emulate transparency using background colors */ void Clay_Termbox_Initialize(int color_mode, enum border_mode border_mode, - enum border_chars border_chars, bool transparency); + enum border_chars border_chars, enum image_mode image_mode, bool transparency); /** Stop termbox2 and release internal structures @@ -223,6 +354,11 @@ void Clay_Termbox_Close(void); */ void Clay_Termbox_Render(Clay_RenderCommandArray commands); +/** + Convenience function to block until an event is received from termbox. If an image is only + partially rendered, this returns immediately. + */ +void Clay_Termbox_Waitfor_Event(void); // ------------------------------------------------------------------------------------------------- @@ -234,6 +370,7 @@ static int clay_tb_color_mode = TB_OUTPUT_NORMAL; static bool clay_tb_transparency = false; static enum border_mode clay_tb_border_mode = CLAY_TB_BORDER_MODE_DEFAULT; static enum border_chars clay_tb_border_chars = CLAY_TB_BORDER_CHARS_DEFAULT; +static enum image_mode clay_tb_image_mode = CLAY_TB_IMAGE_MODE_DEFAULT; // Dimensions of a cell are specified in pixels // Default dimensions were measured from the default terminal on Debian 12: @@ -246,6 +383,17 @@ static clay_tb_pixel_dimensions clay_tb_cell_size = { .width = 9, .height = 21 } static bool clay_tb_scissor_enabled = false; clay_tb_cell_bounding_box clay_tb_scissor_box; +// Images may be drawn across multiple renders to improve responsiveness. The initial draw will be +// approximate, then further partial draws will replace characters with more accurate ones +static bool clay_tb_partial_image_drawn = false; + + +// Maximum fuel used per render across all images +static int clay_tb_image_fuel_max = 200 * 1024; +// Maximum fuel used per render per image +static int clay_tb_image_fuel_per_image = 100 * 1024; +// Fuel used this render +static int clay_tb_image_fuel_used = 0; // ----------------------------------------------- // -- Color buffer @@ -463,6 +611,25 @@ static inline clay_tb_cell_bounding_box cell_snap_bounding_box(Clay_BoundingBox }; } +/** + Snap pixel values from Clay to nearest cell values without considering x and y position when + calculating width/height. + + Width/height ignores offset from x/y, so a box at x=(1.2 * cell_width) and + width=(1.4 * cell_width) is snapped to x=1 and width=1. + + \param box Bounding box with pixel measurements to convert + */ +static inline clay_tb_cell_bounding_box cell_snap_pos_ind_bounding_box(Clay_BoundingBox box) +{ + return (clay_tb_cell_bounding_box) { + .x = clay_tb_roundf(box.x / clay_tb_cell_size.width), + .y = clay_tb_roundf(box.y / clay_tb_cell_size.height), + .width = clay_tb_roundf(box.width / clay_tb_cell_size.width), + .height = clay_tb_roundf(box.height / clay_tb_cell_size.height), + }; +} + /** Get stored clay color for a position from the internal color buffer @@ -607,6 +774,325 @@ static int clay_tb_set_cell( return -1; } +/** + Convert a pixel-based image to a cell-based image of the specified width and height. Stores the + converted/resized result in the cache of the input image. + + If the image has not changed size or image mode since the last convert it is returned unchanged + + \param image Image to convert/resize + \param width Target width in cells for the converted image + \param height Target height in cells for the converted image + */ +bool clay_tb_image_convert(clay_tb_image *image, int width, int height) +{ + clay_tb_assert(NULL != image->pixel_data, "Image must be loaded"); + + bool image_unchanged = (width == image->internal.width && height == image->internal.height + && (clay_tb_image_mode == image->internal.last_image_mode)); + + if (image_unchanged && !image->internal.partial_render.in_progress) { + return true; + } + if (!image_unchanged) { + free(image->internal.partial_render.resized_pixel_data); + image->internal.partial_render = (struct clay_tb_partial_render) { + .in_progress = false, + .resized_pixel_data = NULL, + .cursor_x = 0, + .cursor_y = 0, + .cursor_mask = 0, + .min_difference_squared_sum = INT_MAX, + .best_mask = 0, + .best_foreground = { 0, 0, 0, 0 }, + .best_background = { 0, 0, 0, 0 } + }; + } + + const size_t size = (size_t)width * height; + + // Allocate/resize internal cache data + if (size > image->internal.size_max) { + uint32_t *tmp_characters = realloc(image->internal.characters, size * sizeof(uint32_t)); + Clay_Color *tmp_foreground = realloc(image->internal.foreground, size * sizeof(Clay_Color)); + Clay_Color *tmp_background = realloc(image->internal.background, size * sizeof(Clay_Color)); + + if (NULL == tmp_characters || NULL == tmp_foreground || NULL == tmp_background) { + image->internal.size_max = 0; + free(tmp_characters); + free(tmp_foreground); + free(tmp_background); + image->internal.characters = NULL; + image->internal.foreground = NULL; + image->internal.background = NULL; + return false; + } + image->internal.characters = tmp_characters; + image->internal.foreground = tmp_foreground; + image->internal.background = tmp_background; + image->internal.size_max = size; + } + + image->internal.width = width; + image->internal.height = height; + + // Resize image using the same width/height in cells, but with the pixel sizes of the character + // masks instead of the cell size. The pixel data for each character mask will be compared to + // the pixel data of a small section of the image under the mask. The closest mask to the image + // data is chosen as the character to draw. + const int character_mask_pixel_width = 6; + const int character_mask_pixel_height = 12; + const int pixel_width = width * character_mask_pixel_width; + const int pixel_height = height * character_mask_pixel_height; + + unsigned char *resized_pixel_data; + if (image->internal.partial_render.in_progress) { + resized_pixel_data = image->internal.partial_render.resized_pixel_data; + } else { + resized_pixel_data = stbir_resize_uint8_linear(image->pixel_data, image->pixel_width, + image->pixel_height, 0, NULL, pixel_width, pixel_height, 0, STBIR_RGB); + image->internal.partial_render.resized_pixel_data = resized_pixel_data; + } + + int num_character_masks = 1; + const clay_tb_character_mask *character_masks = NULL; + switch (clay_tb_image_mode) { + case CLAY_TB_IMAGE_MODE_BG: { + num_character_masks = 1; + character_masks = &clay_tb_image_shapes_ascii_fast[0]; + break; + } + case CLAY_TB_IMAGE_MODE_ASCII: + case CLAY_TB_IMAGE_MODE_ASCII_FG: { + num_character_masks = CLAY_TB_IMAGE_SHAPES_ASCII_BEST_COUNT; + character_masks = &clay_tb_image_shapes_ascii_best[0]; + break; + } + case CLAY_TB_IMAGE_MODE_UNICODE: { + num_character_masks = CLAY_TB_IMAGE_SHAPES_UNICODE_BEST_COUNT; + character_masks = &clay_tb_image_shapes_unicode_best[0]; + break; + } + case CLAY_TB_IMAGE_MODE_ASCII_FAST: + case CLAY_TB_IMAGE_MODE_ASCII_FG_FAST: { + num_character_masks = CLAY_TB_IMAGE_SHAPES_ASCII_FAST_COUNT; + character_masks = &clay_tb_image_shapes_ascii_fast[0]; + break; + } + case CLAY_TB_IMAGE_MODE_UNICODE_FAST: { + num_character_masks = CLAY_TB_IMAGE_SHAPES_UNICODE_FAST_COUNT; + character_masks = &clay_tb_image_shapes_unicode_fast[0]; + break; + } + }; + + // The number of character masks to check before exiting the render for this step + // Used to improve responsiveness by splitting renders across multiple frames + const int fuel_amount_initial + = CLAY__MIN(clay_tb_image_fuel_per_image, clay_tb_image_fuel_max - clay_tb_image_fuel_used); + int fuel_remaining = fuel_amount_initial; + bool partial_character_render = false; + + // Do a quick initial render to set the background + if (!image->internal.partial_render.in_progress) { + image->internal.last_image_mode = clay_tb_image_mode; + for (int y = image->internal.partial_render.cursor_y; y < height; ++y) { + for (int x = image->internal.partial_render.cursor_x; x < width; ++x) { + const int cell_top_left_pixel_x = x * character_mask_pixel_width; + const int cell_top_left_pixel_y = y * character_mask_pixel_height; + const int image_index = 3 + * (((cell_top_left_pixel_y + character_mask_pixel_height / 2) * pixel_width) + + (cell_top_left_pixel_x + character_mask_pixel_width / 2)); + Clay_Color pixel_color = { + (float)resized_pixel_data[image_index], + (float)resized_pixel_data[image_index + 1], + (float)resized_pixel_data[image_index + 2], + }; + + const int cell_index = y * width + x; + image->internal.characters[cell_index] = '.'; + image->internal.foreground[cell_index] = pixel_color; + image->internal.background[cell_index] = pixel_color; + + fuel_remaining = CLAY__MAX(0, fuel_remaining - 1); + } + } + } + + if (0 == fuel_remaining) { + image->internal.partial_render.in_progress = true; + clay_tb_partial_image_drawn = true; + goto done; + } + + for (int y = image->internal.partial_render.cursor_y; y < height; ++y) { + for (int x = image->internal.partial_render.cursor_x; x < width; ++x) { + const int cell_top_left_pixel_x = x * character_mask_pixel_width; + const int cell_top_left_pixel_y = y * character_mask_pixel_height; + + // For each possible cell character, use the mask to find the average color for the + // foreground ('1's) and background ('0's). + int min_difference_squared_sum + = image->internal.partial_render.min_difference_squared_sum; + int best_mask = image->internal.partial_render.best_mask; + Clay_Color best_foreground = image->internal.partial_render.best_foreground; + Clay_Color best_background = image->internal.partial_render.best_background; + + for (int i = image->internal.partial_render.cursor_mask; i < num_character_masks; ++i) { + int color_avg_background_r = 0; + int color_avg_background_g = 0; + int color_avg_background_b = 0; + int color_avg_foreground_r = 0; + int color_avg_foreground_g = 0; + int color_avg_foreground_b = 0; + int foreground_count = 0; + int background_count = 0; + + for (int cell_pixel_y = 0; cell_pixel_y < character_mask_pixel_height; + ++cell_pixel_y) { + for (int cell_pixel_x = 0; cell_pixel_x < character_mask_pixel_width; + ++cell_pixel_x) { + const int index = 3 + * (((cell_top_left_pixel_y + cell_pixel_y) * pixel_width) + + (cell_top_left_pixel_x + cell_pixel_x)); + + const int mask_index + = (cell_pixel_y * character_mask_pixel_width) + cell_pixel_x; + if (0 == character_masks[i].data[mask_index]) { + if (CLAY_TB_IMAGE_MODE_ASCII_FG != clay_tb_image_mode + && CLAY_TB_IMAGE_MODE_ASCII_FG_FAST != clay_tb_image_mode) { + color_avg_background_r += resized_pixel_data[index]; + color_avg_background_g += resized_pixel_data[index + 1]; + color_avg_background_b += resized_pixel_data[index + 2]; + background_count += 1; + } + } else { + color_avg_foreground_r += resized_pixel_data[index]; + color_avg_foreground_g += resized_pixel_data[index + 1]; + color_avg_foreground_b += resized_pixel_data[index + 2]; + foreground_count += 1; + } + } + } + + if (CLAY_TB_IMAGE_MODE_ASCII_FG != clay_tb_image_mode + && CLAY_TB_IMAGE_MODE_ASCII_FG_FAST != clay_tb_image_mode) { + color_avg_background_r /= CLAY__MAX(1, background_count); + color_avg_background_g /= CLAY__MAX(1, background_count); + color_avg_background_b /= CLAY__MAX(1, background_count); + } else { + color_avg_background_r = 0; + color_avg_background_g = 0; + color_avg_background_b = 0; + } + + color_avg_foreground_r /= CLAY__MAX(1, foreground_count); + color_avg_foreground_g /= CLAY__MAX(1, foreground_count); + color_avg_foreground_b /= CLAY__MAX(1, foreground_count); + + // Determine the difference between the mask with colors and the actual pixel data + int difference_squared_sum = 0; + for (int cell_pixel_y = 0; cell_pixel_y < character_mask_pixel_height; + ++cell_pixel_y) { + for (int cell_pixel_x = 0; cell_pixel_x < character_mask_pixel_width; + ++cell_pixel_x) { + const int index = 3 + * (((cell_top_left_pixel_y + cell_pixel_y) * pixel_width) + + (cell_top_left_pixel_x + cell_pixel_x)); + int rdiff, gdiff, bdiff, adiff; + + const int mask_index + = (cell_pixel_y * character_mask_pixel_width) + cell_pixel_x; + if (0 == character_masks[i].data[mask_index]) { + rdiff = (color_avg_background_r - resized_pixel_data[index]); + gdiff = (color_avg_background_g - resized_pixel_data[index + 1]); + bdiff = (color_avg_background_b - resized_pixel_data[index + 2]); + } else { + rdiff = (color_avg_foreground_r - resized_pixel_data[index]); + gdiff = (color_avg_foreground_g - resized_pixel_data[index + 1]); + bdiff = (color_avg_foreground_b - resized_pixel_data[index + 2]); + } + + difference_squared_sum += ( + (rdiff * rdiff) + + (gdiff * gdiff) + + (bdiff * bdiff)); + } + } + + // Choose the closest character mask to the image data + if (difference_squared_sum < min_difference_squared_sum) { + min_difference_squared_sum = difference_squared_sum; + best_mask = i; + best_background = (Clay_Color) { + .r = (float)color_avg_background_r, + .g = (float)color_avg_background_g, + .b = (float)color_avg_background_b, + .a = 255 + }; + best_foreground = (Clay_Color) { + .r = (float)color_avg_foreground_r, + .g = (float)color_avg_foreground_g, + .b = (float)color_avg_foreground_b, + .a = 255 + }; + } + + fuel_remaining -= 1; + if (0 == fuel_remaining) { + // Set progress for partial render + image->internal.partial_render = (struct clay_tb_partial_render) { + .in_progress = true, + .resized_pixel_data = resized_pixel_data, + .cursor_x = x, + .cursor_y = y, + .cursor_mask = i + 1, + .min_difference_squared_sum = min_difference_squared_sum, + .best_mask = best_mask, + .best_foreground = best_foreground, + .best_background = best_background + }; + partial_character_render = true; + clay_tb_partial_image_drawn = true; + goto done; + } + } + image->internal.partial_render.cursor_mask = 0; + + // Set data in cache for this character + const int index = y * width + x; + image->internal.characters[index] = character_masks[best_mask].character; + image->internal.foreground[index] = best_foreground; + image->internal.background[index] = best_background; + + image->internal.partial_render = (struct clay_tb_partial_render) { + .in_progress = true, + .resized_pixel_data = resized_pixel_data, + .cursor_x = x + 1, + .cursor_y = y, + .cursor_mask = 0, + .min_difference_squared_sum = INT_MAX, + .best_mask = 0, + .best_foreground = { 0, 0, 0, 0 }, + .best_background = { 0, 0, 0, 0 }, + }; + if (0 == fuel_remaining) { + clay_tb_partial_image_drawn = true; + goto done; + } + } + image->internal.partial_render.cursor_x = 0; + } + image->internal.partial_render.cursor_y = 0; + image->internal.partial_render.in_progress = false; + free(resized_pixel_data); + image->internal.partial_render.resized_pixel_data = NULL; + +done: + clay_tb_image_fuel_used += fuel_amount_initial - fuel_remaining; + return true; +} + // ------------------------------------------------------------------------------------------------- // -- Public API implementation @@ -663,6 +1149,26 @@ void Clay_Termbox_Set_Border_Chars(enum border_chars border_chars) } } +void Clay_Termbox_Set_Image_Mode(enum image_mode image_mode) +{ + clay_tb_assert(CLAY_TB_IMAGE_MODE_DEFAULT <= image_mode + && image_mode <= CLAY_TB_IMAGE_MODE_UNICODE_FAST, + "Image mode invalid (%d)", image_mode); + if (CLAY_TB_IMAGE_MODE_DEFAULT == image_mode) { + clay_tb_image_mode = CLAY_TB_IMAGE_MODE_UNICODE; + } else { + clay_tb_image_mode = image_mode; + } +} + +void Clay_Termbox_Set_Image_Fuel(int fuel_max, int fuel_per_image) +{ + clay_tb_assert(0 < fuel_max && 0 < fuel_per_image, + "Fuel must be positive (%d, %d)", fuel_max, fuel_per_image); + clay_tb_image_fuel_max = fuel_max; + clay_tb_image_fuel_per_image = fuel_per_image; +} + void Clay_Termbox_Set_Transparency(bool transparency) { clay_tb_transparency = transparency; @@ -726,12 +1232,62 @@ static inline Clay_Dimensions Clay_Termbox_MeasureText( }; } -void Clay_Termbox_Initialize( - int color_mode, enum border_mode border_mode, enum border_chars border_chars, bool transparency) +clay_tb_image Clay_Termbox_Image_Load_File(const char *filename) +{ + clay_tb_assert(NULL != filename, "Filename cannot be null"); + + clay_tb_image rv = { 0 }; + + FILE *image_file = NULL; + + image_file = fopen(filename, "r"); + if (NULL == image_file) { + fprintf(stderr, "Failed to open image %s: %s\n", filename, strerror(errno)); + return rv; + } + + int channels_in_file; + const int desired_color_channels = 3; + rv.pixel_data = stbi_load_from_file( + image_file, &rv.pixel_width, &rv.pixel_height, &channels_in_file, desired_color_channels); + + fclose(image_file); + + return rv; +} + +clay_tb_image Clay_Termbox_Image_Load_Memory(const void *image, int size) +{ + clay_tb_assert(NULL != image, "Image cannot be null"); + clay_tb_assert(0 < size, "Image size must be > 0"); + + clay_tb_image rv = { 0 }; + + int channels_in_file; + const int desired_color_channels = 3; + rv.pixel_data = stbi_load_from_memory( + image, size, &rv.pixel_width, &rv.pixel_height, &channels_in_file, desired_color_channels); + + return rv; +} + +void Clay_Termbox_Image_Free(clay_tb_image *image) +{ + free(image->pixel_data); + free(image->internal.partial_render.resized_pixel_data); + free(image->internal.characters); + free(image->internal.foreground); + free(image->internal.background); + *image = (clay_tb_image) { 0 }; +} + +void Clay_Termbox_Initialize(int color_mode, enum border_mode border_mode, + enum border_chars border_chars, enum image_mode image_mode, bool transparency) { int new_color_mode = color_mode; int new_border_mode = border_mode; int new_border_chars = border_chars; + int new_image_mode = image_mode; int new_transparency = transparency; clay_tb_pixel_dimensions new_pixel_size = clay_tb_cell_size; @@ -769,6 +1325,29 @@ void Clay_Termbox_Initialize( } } + const char *env_image_mode = getenv("CLAY_TB_IMAGE_MODE"); + if (NULL != env_image_mode) { + if (0 == strcmp("DEFAULT", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_DEFAULT; + } else if (0 == strcmp("PLACEHOLDER", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_PLACEHOLDER; + } else if (0 == strcmp("BG", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_BG; + } else if (0 == strcmp("ASCII_FG", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_ASCII_FG; + } else if (0 == strcmp("ASCII", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_ASCII; + } else if (0 == strcmp("UNICODE", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_UNICODE; + } else if (0 == strcmp("ASCII_FG_FAST", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_ASCII_FG_FAST; + } else if (0 == strcmp("ASCII_FAST", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_ASCII_FAST; + } else if (0 == strcmp("UNICODE_FAST", env_image_mode)) { + new_image_mode = CLAY_TB_IMAGE_MODE_UNICODE_FAST; + } + } + const char *env_transparency = getenv("CLAY_TB_TRANSPARENCY"); if (NULL != env_transparency) { if (0 == strcmp("1", env_transparency)) { @@ -821,6 +1400,7 @@ void Clay_Termbox_Initialize( Clay_Termbox_Set_Color_Mode(new_color_mode); Clay_Termbox_Set_Border_Mode(new_border_mode); Clay_Termbox_Set_Border_Chars(new_border_chars); + Clay_Termbox_Set_Image_Mode(new_image_mode); Clay_Termbox_Set_Transparency(new_transparency); Clay_Termbox_Set_Cell_Pixel_Size(new_pixel_size.width, new_pixel_size.height); @@ -848,6 +1428,9 @@ void Clay_Termbox_Render(Clay_RenderCommandArray commands) clay_tb_assert(clay_tb_initialized, "Clay_Termbox_Initialize must be run first"); clay_tb_resize_buffer(); + clay_tb_partial_image_drawn = false; + clay_tb_image_fuel_used = 0; + for (int32_t i = 0; i < commands.length; ++i) { const Clay_RenderCommand *command = Clay_RenderCommandArray_Get(&commands, i); const clay_tb_cell_bounding_box cell_box = cell_snap_bounding_box(command->boundingBox); @@ -1079,32 +1662,79 @@ void Clay_Termbox_Render(Clay_RenderCommandArray commands) color_tb_bg = clay_tb_color_convert(color_bg); } - const char *placeholder_text = "[Image]"; + bool use_placeholder = true; - int i = 0; - unsigned long len = strlen(placeholder_text); - for (int y = box_begin_y; y < box_end_y; ++y) { - float percent_y = (float)(y - box_begin_y) / (float)cell_box.height; + clay_tb_image *image = (clay_tb_image *)render_data.imageData; - for (int x = box_begin_x; x < box_end_x; ++x) { - char ch = ' '; - if (i < len) { - ch = placeholder_text[i++]; - } + if (!(CLAY_TB_IMAGE_MODE_PLACEHOLDER == clay_tb_image_mode + || CLAY_TB_OUTPUT_NOCOLOR == clay_tb_color_mode)) { + bool convert_success = (NULL != image) + ? clay_tb_image_convert(image, cell_box.width, cell_box.height) + : false; + if (convert_success) { + use_placeholder = false; + } + } - if (!color_specified) { - // Use a placeholder pattern for the image - float percent_x = (float)(cell_box.width - (x - box_begin_x)) - / (float)cell_box.width; - if (percent_x > percent_y) { - color_bg = (Clay_Color) { 0x94, 0xb4, 0xff, 0xff }; - color_tb_bg = clay_tb_color_convert(color_bg); - } else { - color_bg = (Clay_Color) { 0x3f, 0xcc, 0x45, 0xff }; - color_tb_bg = clay_tb_color_convert(color_bg); + if (!use_placeholder) { + // Render image + for (int y = box_begin_y; y < box_end_y; ++y) { + int y_offset = y - cell_box.y; + for (int x = box_begin_x; x < box_end_x; ++x) { + int x_offset = x - cell_box.x; + // Fetch cells from the image's cache + if (!color_specified) { + if (CLAY_TB_IMAGE_MODE_ASCII_FG == clay_tb_image_mode + || CLAY_TB_IMAGE_MODE_ASCII_FG_FAST == clay_tb_image_mode) { + color_bg = (Clay_Color) { 0, 0, 0, 0 }; + color_tb_bg = TB_DEFAULT; + } else { + color_bg + = image->internal + .background[y_offset * cell_box.width + x_offset]; + color_tb_bg = clay_tb_color_convert(color_bg); + } } + color_tb_fg = clay_tb_color_convert( + image->internal.foreground[y_offset * cell_box.width + x_offset]); + uint32_t ch + = image->internal.characters[y_offset * cell_box.width + x_offset]; + if (CLAY_TB_IMAGE_MODE_BG == clay_tb_image_mode) { + ch = ' '; + } + + clay_tb_set_cell(x, y, ch, color_tb_fg, color_tb_bg, color_bg); + } + } + } else { + // Render a placeholder pattern + const char *placeholder_text = "[Image]"; + + int i = 0; + unsigned long len = strlen(placeholder_text); + for (int y = box_begin_y; y < box_end_y; ++y) { + float percent_y = (float)(y - box_begin_y) / (float)cell_box.height; + + for (int x = box_begin_x; x < box_end_x; ++x) { + char ch = ' '; + if (i < len) { + ch = placeholder_text[i++]; + } + + if (!color_specified) { + // Use a placeholder pattern for the image + float percent_x = (float)(cell_box.width - (x - box_begin_x)) + / (float)cell_box.width; + if (percent_x > percent_y) { + color_bg = (Clay_Color) { 0x94, 0xb4, 0xff, 0xff }; + color_tb_bg = clay_tb_color_convert(color_bg); + } else { + color_bg = (Clay_Color) { 0x3f, 0xcc, 0x45, 0xff }; + color_tb_bg = clay_tb_color_convert(color_bg); + } + } + clay_tb_set_cell(x, y, ch, color_tb_fg, color_tb_bg, color_bg); } - clay_tb_set_cell(x, y, ch, color_tb_fg, color_tb_bg, color_bg); } } break; @@ -1129,3 +1759,18 @@ void Clay_Termbox_Render(Clay_RenderCommandArray commands) } } } + +void Clay_Termbox_Waitfor_Event(void) +{ + if (clay_tb_partial_image_drawn) { + return; + } + int termbox_ttyfd, termbox_resizefd; + tb_get_fds(&termbox_ttyfd, &termbox_resizefd); + int nfds = CLAY__MAX(termbox_ttyfd, termbox_resizefd) + 1; + fd_set monitor_set; + FD_ZERO(&monitor_set); + FD_SET(termbox_ttyfd, &monitor_set); + FD_SET(termbox_resizefd, &monitor_set); + select(nfds, &monitor_set, NULL, NULL, NULL); +} diff --git a/renderers/termbox2/image_character_masks.h b/renderers/termbox2/image_character_masks.h new file mode 100644 index 0000000..46258f1 --- /dev/null +++ b/renderers/termbox2/image_character_masks.h @@ -0,0 +1,2863 @@ +#ifndef CLAY_TB_IMAGE_H +#define CLAY_TB_IMAGE_H +#include + +typedef struct { + uint32_t character; + int data[6 * 12]; +} clay_tb_character_mask; + +// Ascii bitmap data from the Terminus 4.49 font (https://terminus-font.sourceforge.net/) +// Licensed under the SIL Open Font License, Version 1.1 (https://scripts.sil.org/OFL) +#define CLAY_TB_IMAGE_SHAPES_ASCII_BEST_COUNT 95 +const clay_tb_character_mask clay_tb_image_shapes_ascii_best[CLAY_TB_IMAGE_SHAPES_ASCII_BEST_COUNT] = { + { + .character = ' ', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '!', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '"', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '#', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '$', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '%', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, 1, + 0, 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '&', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 0, 1, 0, + 1, 0, 0, 1, 0, 0, + 1, 0, 0, 1, 0, 0, + 0, 1, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '\'', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '(', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = ')', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '*', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '+', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = ',', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '-', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '.', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '/', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '0', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 1, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '1', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '2', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '3', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '4', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 1, 0, + 0, 1, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '5', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '6', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '7', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '8', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '9', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = ':', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = ';', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '<', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '=', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '>', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '?', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '@', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 0, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'A', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'B', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'C', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'D', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 1, 0, 0, + 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'E', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'F', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'G', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'H', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'I', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'J', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 1, 0, 0, 1, 0, 0, + 1, 0, 0, 1, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'K', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 1, 0, 0, + 1, 0, 1, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 1, 0, 0, 0, + 1, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'L', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'M', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 0, 1, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'N', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 0, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'O', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'P', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'Q', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'R', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 1, 0, 0, 0, + 1, 0, 0, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'S', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'T', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'U', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'V', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'W', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 1, 0, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'X', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'Y', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'Z', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '[', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '\\', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = ']', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '^', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '_', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '`', + .data = + { 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'a', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'b', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'c', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'd', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'e', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'f', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'g', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0 }, + }, + { + .character = 'h', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'i', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'j', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 1, 0, + 0, 0, 1, 1, 0, 0 }, + }, + { + .character = 'k', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'l', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'm', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'n', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'o', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'p', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0 }, + }, + { + .character = 'q', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0 }, + }, + { + .character = 'r', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 's', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 't', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'u', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'v', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'w', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'x', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'y', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0 }, + }, + { + .character = 'z', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '{', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '|', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '}', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '~', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, +}; + + +#define CLAY_TB_IMAGE_SHAPES_ASCII_FAST_COUNT 15 +const clay_tb_character_mask clay_tb_image_shapes_ascii_fast[CLAY_TB_IMAGE_SHAPES_ASCII_FAST_COUNT] = { + { + .character = ' ', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '"', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '#', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 1, 0, 1, 0, 0, + 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '-', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '.', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '@', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 1, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 0, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'B', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'F', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'L', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '_', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = '`', + .data = + { 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'g', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0 }, + }, + { + .character = 'r', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = 'y', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 1, 0, + 0, 1, 1, 1, 0, 0 }, + }, + { + .character = '~', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 1, 0, + 1, 0, 1, 0, 1, 0, + 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, +}; + +#define CLAY_TB_IMAGE_SHAPES_UNICODE_BEST_COUNT 52 +const clay_tb_character_mask clay_tb_image_shapes_unicode_best[CLAY_TB_IMAGE_SHAPES_UNICODE_BEST_COUNT] = { + { + .character = ' ', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2580', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2581', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2582', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2583', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2584', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2585', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2586', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2587', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2588', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2589', + .data = + { 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0 }, + }, + { + .character = U'\u258a', + .data = + { 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0 }, + }, + { + .character = U'\u258c', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\u258e', + .data = + { 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0 }, + }, + { + .character = U'\u258f', + .data = + { 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2590', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\u2594', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2595', + .data = + { 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1 }, + }, + { + .character = U'\u2596', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\u2597', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\u2598', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2599', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u259a', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\u259b', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\u259c', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\u259d', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u259e', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\u259f', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + // TODO: END HERE + { + .character = U'\u25e2', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u25e3', + .data = + { 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u25e4', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u25e5', + .data = + { 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0 }, + }, + + { + .character = U'\U0001fb3c', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\U0001fb3d', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\U0001fb3e', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\U0001fb3f', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\U0001fb40', + .data = + { 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\U0001fb47', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\U0001fb48', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, + 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\U0001fb49', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\U0001fb4a', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\U0001fb4b', + .data = + { 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\U0001fb57', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb58', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, + 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb59', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb5a', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb59', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 1, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb62', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb63', + .data = + { 1, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb64', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb65', + .data = + { 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\U0001fb66', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 1 }, + }, +}; + +#define CLAY_TB_IMAGE_SHAPES_UNICODE_FAST_COUNT 15 +const clay_tb_character_mask clay_tb_image_shapes_unicode_fast[CLAY_TB_IMAGE_SHAPES_UNICODE_FAST_COUNT] = { + { + .character = ' ', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2580', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2581', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2586', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2587', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1 }, + }, + { + .character = U'\u2589', + .data = + { 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 0 }, + }, + { + .character = U'\u258c', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\u258f', + .data = + { 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2594', + .data = + { 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u2596', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, + { + .character = U'\u2597', + .data = + { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\u2598', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u259a', + .data = + { 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1 }, + }, + { + .character = U'\u259d', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }, + }, + { + .character = U'\u259e', + .data = + { 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, 1, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0 }, + }, +}; + +#endif // CLAY_TB_IMAGE_H