/****************************************************************************** * This file is part of TinTin++ * * * * Copyright 2004-2020 Igor van den Hoven * * * * TinTin++ is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with TinTin++. If not, see https://www.gnu.org/licenses. * ******************************************************************************/ /****************************************************************************** * T I N T I N + + * * * * coded by Igor van den Hoven 2019 * ******************************************************************************/ static char draw_buf[100][10]; static int draw_cnt; #include "tintin.h" #define DRAW_FLAG_NONE 0 #define DRAW_FLAG_ASCII BV01 #define DRAW_FLAG_BLANKED BV02 #define DRAW_FLAG_BOT BV03 #define DRAW_FLAG_BOXED BV04 #define DRAW_FLAG_BUMP BV05 #define DRAW_FLAG_CIRCLED BV06 #define DRAW_FLAG_COLOR1 BV07 #define DRAW_FLAG_COLOR2 BV08 #define DRAW_FLAG_CONVERT BV09 #define DRAW_FLAG_CORNERED BV10 #define DRAW_FLAG_CROSSED BV11 #define DRAW_FLAG_FILLED BV12 #define DRAW_FLAG_FOREGROUND BV13 #define DRAW_FLAG_GRID BV14 #define DRAW_FLAG_HOR BV15 #define DRAW_FLAG_HUGE BV16 #define DRAW_FLAG_JEWELED BV17 #define DRAW_FLAG_LEFT BV18 //#define DRAW_FLAG_LINED BV19 unused / obsolete #define DRAW_FLAG_NUMBERED BV20 #define DRAW_FLAG_PRUNED BV21 #define DRAW_FLAG_RIGHT BV22 #define DRAW_FLAG_ROUNDED BV23 #define DRAW_FLAG_SCALED BV24 #define DRAW_FLAG_SCROLL BV25 #define DRAW_FLAG_SHADOWED BV26 #define DRAW_FLAG_TEED BV27 #define DRAW_FLAG_TOP BV28 #define DRAW_FLAG_TRACED BV29 #define DRAW_FLAG_TUBED BV30 #define DRAW_FLAG_UTF8 BV31 #define DRAW_FLAG_VER BV32 #define DRAW_FLAG_CURSIVE BV33 #define DRAW_FLAG_FAT BV34 #define DRAW_FLAG_SANSSERIF BV35 #define DRAW_FLAG_CALIGN BV36 #define DRAW_FLAG_LALIGN BV37 #define DRAW_FLAG_RALIGN BV38 #define DRAW_FLAG_TALIGN BV39 #define DRAW_FLAG_UALIGN BV40 #define DRAW_FLAG_BALIGN BV41 #define DRAW_FLAG_APPENDIX DRAW_FLAG_CIRCLED|DRAW_FLAG_CORNERED|DRAW_FLAG_CROSSED|DRAW_FLAG_JEWELED|DRAW_FLAG_PRUNED|DRAW_FLAG_ROUNDED|DRAW_FLAG_TEED #define DO_DRAW(draw) void draw (struct session *ses, int top_row, int top_col, int bot_row, int bot_col, int rows, int cols, long long flags, char *box_color, char *txt_color, char *arg, char *arg1, char *arg2, char *arg3) extern DO_DRAW(draw_blank); extern DO_DRAW(draw_bot_side); //extern DO_DRAW(draw_arg); extern DO_DRAW(draw_box); extern DO_DRAW(draw_buffer); extern DO_DRAW(draw_corner); extern DO_DRAW(draw_left_side); extern DO_DRAW(draw_line); extern DO_DRAW(draw_map); extern DO_DRAW(draw_right_side); extern DO_DRAW(draw_side); extern DO_DRAW(draw_square); extern DO_DRAW(draw_rain); extern DO_DRAW(draw_hbar); extern DO_DRAW(draw_table_grid); extern DO_DRAW(draw_text); extern DO_DRAW(draw_top_side); extern DO_DRAW(draw_vertical_lines); typedef void DRAW(struct session *ses, int top_row, int top_col, int bot_row, int bot_col, int rows, int cols, long long flags, char *box_color, char *txt_color, char *arg, char *arg1, char *arg2, char *arg3); struct draw_type { char * name; char * desc; int flags; DRAW * fun; }; struct draw_type draw_table[] = { { "BAR", "Draw a bar.", DRAW_FLAG_NONE, draw_hbar }, { "BOX", "Draw four sides of a box.", DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT, draw_box }, { "BUFFER", "Draw the scrollback buffer.", DRAW_FLAG_NONE, draw_buffer }, { "CORNER", "Draw a corner", DRAW_FLAG_CORNERED, draw_corner }, { "LINE", "Draw a line.", DRAW_FLAG_NONE, draw_line }, { "MAP", "Draw the map.", DRAW_FLAG_NONE, draw_map }, { "RAIN", "Draw digital rain.", DRAW_FLAG_NONE, draw_rain }, { "SIDE", "Draw a line with corners.", DRAW_FLAG_CORNERED, draw_side }, { "TABLE", "Draw a table.", DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT, draw_table_grid }, { "TILE", "Draw a tile.", DRAW_FLAG_NONE, draw_square }, { "", "", DRAW_FLAG_NONE, NULL } }; void scale_drawing(struct session *ses, int *top_row, int *top_col, int *bot_row, int *bot_col, int *rows, int *cols, int index, long long flags, char *arg); DO_COMMAND(do_draw) { char *box_color, *txt_color, *code1, *code2, *input; long long flags; int index, top_row, top_col, bot_row, bot_col, rows, cols; input = str_alloc_stack(0); substitute(ses, arg, input, SUB_VAR|SUB_FUN); arg = input; draw_cnt = 0; if (*arg == 0) { tintin_header(ses, 80, " DRAW OPTIONS "); for (index = 0 ; *draw_table[index].fun ; index++) { if (*draw_table[index].name) { tintin_printf2(ses, " [%-24s] %s", draw_table[index].name, draw_table[index].desc); } } tintin_header(ses, 80, ""); return ses; } arg4 = str_alloc_stack(0); box_color = str_alloc_stack(0); txt_color = str_alloc_stack(0); code1 = str_alloc_stack(0); code2 = str_alloc_stack(0); flags = HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) ? DRAW_FLAG_UTF8 : 0; while (*arg) { arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); if (!HAS_BIT(flags, DRAW_FLAG_COLOR1) && translate_color_names(ses, arg1, code1)) { get_color_names(ses, arg1, box_color); SET_BIT(flags, DRAW_FLAG_COLOR1); continue; } if (!HAS_BIT(flags, DRAW_FLAG_COLOR2) && translate_color_names(ses, arg1, code2)) { get_color_names(ses, arg1, txt_color); SET_BIT(flags, DRAW_FLAG_COLOR2); continue; } switch (*arg1 % 32) { case CTRL_A: if (is_abbrev(arg1, "ASCII")) { DEL_BIT(flags, DRAW_FLAG_UTF8); } else { goto option; } continue; case CTRL_B: if (is_abbrev(arg1, "BALIGN")) { SET_BIT(flags, DRAW_FLAG_BALIGN); } else if (is_abbrev(arg1, "BLANKED")) { SET_BIT(flags, DRAW_FLAG_BLANKED); } else if (is_abbrev(arg1, "BOTTOM")) { SET_BIT(flags, DRAW_FLAG_BOT); } else if (!strcasecmp(arg1, "BOXED")) { SET_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT); } else if (is_abbrev(arg1, "BUMPED")) { SET_BIT(flags, DRAW_FLAG_BUMP); } else { goto option; } continue; case CTRL_C: if (is_abbrev(arg1, "CALIGN")) { SET_BIT(flags, DRAW_FLAG_CALIGN); } else if (is_abbrev(arg1, "CIRCLED")) { SET_BIT(flags, DRAW_FLAG_CIRCLED); } else if (is_abbrev(arg1, "CONVERT")) { SET_BIT(flags, DRAW_FLAG_CONVERT); } else if (is_abbrev(arg1, "CROSSED")) { SET_BIT(flags, DRAW_FLAG_CROSSED); } else if (is_abbrev(arg1, "CURSIVE")) { SET_BIT(flags, DRAW_FLAG_CURSIVE); } else { goto option; } continue; case CTRL_F: if (is_abbrev(arg1, "FAT")) { SET_BIT(flags, DRAW_FLAG_FAT); } else if (is_abbrev(arg1, "FILLED")) { SET_BIT(flags, DRAW_FLAG_FILLED); } else if (is_abbrev(arg1, "FOREGROUND")) { SET_BIT(flags, DRAW_FLAG_FOREGROUND); } else { goto option; } continue; case CTRL_G: if (is_abbrev(arg1, "GRID")) { SET_BIT(flags, DRAW_FLAG_GRID); } else { goto option; } continue; case CTRL_H: if (is_abbrev(arg1, "HORIZONTAL")) { SET_BIT(flags, DRAW_FLAG_HOR); } else if (is_abbrev(arg1, "HUGE")) { SET_BIT(flags, DRAW_FLAG_HUGE); } else { goto option; } continue; case CTRL_J: if (is_abbrev(arg1, "JEWELED")) { SET_BIT(flags, DRAW_FLAG_JEWELED); } else if (is_abbrev(arg1, "JOINTED")) { SET_BIT(flags, DRAW_FLAG_CORNERED); } else { goto option; } continue; case CTRL_L: if (is_abbrev(arg1, "LALIGN")) { SET_BIT(flags, DRAW_FLAG_LALIGN); } else if (is_abbrev(arg1, "LEFT")) { SET_BIT(flags, DRAW_FLAG_LEFT); } else { goto option; } continue; case CTRL_N: if (is_abbrev(arg1, "NUMBERED")) { SET_BIT(flags, DRAW_FLAG_NUMBERED); } else { goto option; } continue; case CTRL_P: if (is_abbrev(arg1, "PRUNED")) { SET_BIT(flags, DRAW_FLAG_PRUNED); } else { goto option; } continue; case CTRL_R: if (is_abbrev(arg1, "RALIGN")) { SET_BIT(flags, DRAW_FLAG_RALIGN); } else if (is_abbrev(arg1, "RIGHT")) { SET_BIT(flags, DRAW_FLAG_RIGHT); } else if (is_abbrev(arg1, "ROUNDED")) { SET_BIT(flags, DRAW_FLAG_ROUNDED); } else { goto option; } continue; case CTRL_S: if (is_abbrev(arg1, "SANSSERIF")) { SET_BIT(flags, DRAW_FLAG_SANSSERIF); } else if (is_abbrev(arg1, "SCALED")) { SET_BIT(flags, DRAW_FLAG_SCALED); } else if (is_abbrev(arg1, "SCROLL")) { SET_BIT(flags, DRAW_FLAG_SCROLL); } else if (is_abbrev(arg1, "SHADOWED")) { SET_BIT(flags, DRAW_FLAG_SHADOWED); } else { goto option; } continue; case CTRL_T: if (is_abbrev(arg1, "TALIGN")) { SET_BIT(flags, DRAW_FLAG_TALIGN); } else if (is_abbrev(arg1, "TEED")) { SET_BIT(flags, DRAW_FLAG_TEED); } else if (is_abbrev(arg1, "TOP")) { SET_BIT(flags, DRAW_FLAG_TOP); } else if (is_abbrev(arg1, "TRACED")) { SET_BIT(flags, DRAW_FLAG_TRACED); } else if (is_abbrev(arg1, "TUBED")) { SET_BIT(flags, DRAW_FLAG_TUBED); } else { goto option; } continue; case CTRL_U: if (is_abbrev(arg1, "UALIGN")) { SET_BIT(flags, DRAW_FLAG_UALIGN); } else if (is_abbrev(arg1, "UNICODE")) { SET_BIT(flags, DRAW_FLAG_UTF8); } else { goto option; } continue; case CTRL_V: if (is_abbrev(arg1, "VERTICAL")) { SET_BIT(flags, DRAW_FLAG_VER); } else { break; } continue; default: goto option; continue; } } option: for (index = 0 ; *draw_table[index].name ; index++) { if (is_abbrev(arg1, draw_table[index].name)) { arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); arg = get_arg_in_braces(ses, arg, arg2, GET_ONE); arg = get_arg_in_braces(ses, arg, arg3, GET_ONE); arg = get_arg_in_braces(ses, arg, arg4, GET_ONE); top_row = get_row_index_arg(ses, arg1); top_col = get_col_index_arg(ses, arg2); bot_row = get_row_index_arg(ses, arg3); bot_col = get_col_index_arg(ses, arg4); if (!is_math(ses, arg1) || !is_math(ses, arg2) || !is_math(ses, arg3) || !is_math(ses, arg4)) { show_error(ses, LIST_COMMAND, "#ERROR: #DRAW: NON-NUMERIC SQUARE: %s {%s %s %s %s}", draw_table[index].name, is_math(ses, arg1) ? ntos(top_row) : arg1, is_math(ses, arg2) ? ntos(top_col) : arg2, is_math(ses, arg3) ? ntos(bot_row) : arg3, is_math(ses, arg4) ? ntos(bot_col) : arg4); return ses; } if (top_row == 0 && top_col == 0) { show_error(ses, LIST_COMMAND, "#SYNTAX: #DRAW [COLOR] [OPTIONS] {%s} [TEXT]", draw_table[index].name); return ses; } if (top_row == 0) { top_row = 1; SET_BIT(flags, DRAW_FLAG_SCROLL); } else { if (!HAS_BIT(flags, DRAW_FLAG_SCROLL) && !HAS_BIT(flags, DRAW_FLAG_FOREGROUND) && ses != gtd->ses) { show_message(ses, LIST_COMMAND, "#WARNING: #DRAW %s %d %d %d %d: SESSION IS IN THE BACKGROUND.", draw_table[index].name, top_row, top_col, bot_row, bot_col); return ses; } } if (top_col == 0) { top_col = 1; } if (bot_row == 0) { bot_row = 1; } if (bot_col == 0) { bot_col = 1; } if (top_row > bot_row || top_col > bot_col) { show_error(ses, LIST_COMMAND, "#ERROR: #DRAW: INVALID SQUARE: %s {%d %d %d %d} ROWS: %d COLS: %d", draw_table[index].name, top_row, top_col, bot_row, bot_col, 1 + bot_row - top_row, 1 + bot_col - top_col); return ses; } rows = URANGE(1, 1 + bot_row - top_row, gtd->screen->rows); cols = URANGE(1, 1 + bot_col - top_col, gtd->screen->cols); if (HAS_BIT(flags, DRAW_FLAG_SCALED)) { scale_drawing(ses, &top_row, &top_col, &bot_row, &bot_col, &rows, &cols, index, draw_table[index].flags | flags, arg); } *arg1 = 0; *arg2 = 0; *arg3 = 0; // *arg4 = 0; // forgot why I did this originally /* if (*arg == 0) { arg = arg4; } */ save_pos(ses); if (HAS_BIT(flags, DRAW_FLAG_BUMP)) { tintin_printf2(ses, ""); } str_cpy(&arg2, code1); str_cpy(&arg3, code2); draw_table[index].fun(ses, top_row, top_col, bot_row, bot_col, rows, cols, draw_table[index].flags | flags, box_color, txt_color, arg, arg1, arg2, arg3); print_stdout(0, 0, "\e[0m"); restore_pos(ses); return ses; } } show_error(ses, LIST_COMMAND, "#ERROR: #DRAW {%s} IS NOT A VALID OPTION.", capitalize(arg1)); return ses; } // utilities void string_to_stamp(struct session *ses, long long flags, char *in, char *out); void scale_drawing(struct session *ses, int *top_row, int *top_col, int *bot_row, int *bot_col, int *rows, int *cols, int index, long long flags, char *arg) { char *buf, *out, *tmp, *swap; int inside; int height, bor_height, tot_height, max_height; int width, bor_width, tot_width, max_width; if (*arg == 0) { return; } push_call("scale_drawing(%p,%p,%p,%p,%p,%p,%p,%p,%d,%lld,%p",ses,top_row,top_col,bot_row,bot_col,rows,cols,index,flags,arg); buf = str_alloc_stack(0); out = str_alloc_stack(0); tmp = str_alloc_stack(0); height = bor_height = tot_height = max_height = 0; width = bor_width = tot_width = max_width = 0; if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { inside = TRUE; } else { inside = inside_scroll_region(ses, *top_row, *top_col); } if (inside) { max_height = 0 + ses->split->bot_row - ses->split->top_row; max_width = 1 + ses->split->bot_col - ses->split->top_col; } else { max_height = gtd->screen->rows; max_width = gtd->screen->cols; } if (HAS_BIT(flags, DRAW_FLAG_VER)) { max_width = 1 + *bot_col - *top_col; } if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { max_height = gtd->screen->rows * 10; } bor_height += HAS_BIT(flags, DRAW_FLAG_TOP) ? 1 : 0; bor_height += HAS_BIT(flags, DRAW_FLAG_BOT) ? 1 : 0; bor_width += HAS_BIT(flags, DRAW_FLAG_LEFT) ? 1 : 0; bor_width += HAS_BIT(flags, DRAW_FLAG_RIGHT) ? 1 : 0; if (HAS_BIT(flags, DRAW_FLAG_UALIGN)) { ualign(ses, arg, tmp, max_width - bor_width); strcpy(arg, tmp); } if (HAS_BIT(flags, DRAW_FLAG_HUGE)) { string_to_stamp(ses, flags, arg, tmp); swap = arg; arg = tmp; tmp = swap; if (*arg) { arg[strlen(arg) - 1] = 0; } } while (*arg) { arg = sub_arg_in_braces(ses, arg, buf, GET_ALL, SUB_COL|SUB_LIT|SUB_ESC); word_wrap_split(ses, buf, out, max_width - bor_width, 0, 0, WRAP_FLAG_NONE, &height, &width); tot_width = UMAX(tot_width, width); tot_height += height; if (*arg == COMMAND_SEPARATOR) { arg++; } } tot_height += bor_height; tot_width += bor_width; if (tot_height > max_height) { tot_height = max_height; } if (tot_height > *rows) { *bot_row = get_row_index(ses, *top_row + tot_height - 1); if (inside) { if (*bot_row > ses->split->bot_row - 1) { *bot_row = ses->split->bot_row - 1; } } *rows = URANGE(1, 1 + *bot_row - *top_row, gtd->screen->rows); } while (tot_height > *rows) { (*top_row)--; *rows = 1 + *bot_row - *top_row; } // tintin_printf2(ses, "debug4: rows %d top_row: %d bot_row %d", *rows, *top_row, *bot_row); if (tot_width > max_width) { tot_width = max_width; } if (tot_width > *cols) { *bot_col = get_col_index(ses, *top_col + tot_width - 1); if (inside) { if (*bot_col > ses->split->bot_col) { *bot_col = ses->split->bot_col; } } *cols = URANGE(1, 1 + *bot_col - *top_col, gtd->screen->cols); } while (tot_width > *cols) { (*top_col)--; *cols = 1 + *bot_col - *top_col; } // tintin_printf2(ses, "debug4: cols %d top_col: %d bot_col %d", *cols, *top_col, *bot_col); if (HAS_BIT(flags, DRAW_FLAG_HUGE)) { arg = tmp; } pop_call(); return; } char *alnum_normal[] = { "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x20", "\x21", "\x22", "\x23", "\x24", "\x25", "\x26", "\x27", "\x28", "\x29", "\x30", "\x31", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "\x7F" }; char *alnum_normal_fat[] = { "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x20", "\x21", "\x22", "\x23", "\x24", "\x25", "\x26", "\x27", "\x28", "\x29", "\x30", "\x31", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "๐ŸŽ", "๐Ÿ", "๐Ÿ", "๐Ÿ‘", "๐Ÿ’", "๐Ÿ“", "๐Ÿ”", "๐Ÿ•", "๐Ÿ–", "๐Ÿ—", ":", ";", "<", "=", ">", "?", "@", "๐€", "๐", "๐‚", "๐ƒ", "๐„", "๐…", "๐†", "๐‡", "๐ˆ", "๐‰", "๐Š", "๐‹", "๐Œ", "๐", "๐Ž", "๐", "๐", "๐‘", "๐’", "๐“", "๐”", "๐•", "๐–", "๐—", "๐˜", "Z", "๐™", "\\", "]", "^", "_", "`", "๐š", "๐›", "๐œ", "๐", "๐ž", "๐Ÿ", "๐ ", "๐ก", "๐ข", "๐ฃ", "๐ค", "๐ฅ", "๐ฆ", "๐ง", "๐จ", "๐ฉ", "๐ช", "๐ซ", "๐ฌ", "๐ญ", "๐ฎ", "๐ฏ", "๐ฐ", "๐ฑ", "๐ฒ", "๐ณ", "{", "|", "}", "~", "\x7F" }; char *alnum_cursive[] = { "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x20", "\x21", "\x22", "\x23", "\x24", "\x25", "\x26", "\x27", "\x28", "\x29", "\x30", "\x31", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "๐’œ", "โ„ฌ", "๐’ž", "๐’Ÿ", "โ„ฐ", "โ„ฑ", "๐’ข", "โ„‹", "โ„", "๐’ฅ", "๐’ฆ", "โ„’", "โ„ณ", "๐’ฉ", "๐’ช", "๐’ซ", "๐’ฌ", "โ„›", "๐’ฎ", "๐’ฏ", "๐’ฐ", "๐’ฑ", "๐’ฒ", "๐’ณ", "๐’ด", "๐’ต", "[", "\\", "]", "^", "_", "`", "๐’ถ", "๐’ท", "๐’ธ", "๐’น", "โ„ฏ", "๐’ป", "โ„Š", "๐’ฝ", "๐’พ", "๐’ฟ", "๐“€", "๐“", "๐“‚", "๐“ƒ", "โ„ด", "๐“…", "๐“†", "๐“‡", "๐“ˆ", "๐“‰", "๐“Š", "๐“‹", "๐“Œ", "๐“", "๐“Ž", "๐“", "{", "|", "}", "~", "\x7F" }; char *alnum_sansserif[] = { "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09", "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", "\x18", "\x19", "\x20", "\x21", "\x22", "\x23", "\x24", "\x25", "\x26", "\x27", "\x28", "\x29", "\x30", "\x31", " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "๐Ÿข", "๐Ÿฃ", "๐Ÿค", "๐Ÿฅ", "๐Ÿฆ", "๐Ÿง", "๐Ÿจ", "๐Ÿฉ", "๐Ÿช", "๐Ÿซ", ":", ";", "<", "=", ">", "?", "@", "๐– ", "๐–ก", "๐–ข", "๐–ฃ", "๐–ค", "๐–ฅ", "๐–ฆ", "๐–ง", "๐–จ", "๐–ฉ", "๐–ช", "๐–ซ", "๐–ฌ", "๐–ญ", "๐–ฎ", "๐–ฏ", "๐–ฐ", "๐–ฑ", "๐–ฒ", "๐–ณ", "๐–ด", "๐–ต", "๐–ถ", "๐–ท", "๐–ธ", "๐–น", "[", "\\", "]", "^", "_", "`", "๐–บ", "๐–ป", "๐–ผ", "๐–ฝ", "๐–พ", "๐–ฟ", "๐—€", "๐—", "๐—‚", "๐—ƒ", "๐—„", "๐—…", "๐—†", "๐—‡", "๐—ˆ", "๐—‰", "๐—Š", "๐—‹", "๐—Œ", "๐—", "๐—Ž", "๐—", "๐—", "๐—‘", "๐—’", "๐—“", "{", "|", "}", "~", "\x7F" }; void string_to_font(struct session *ses, long long flags, char *in, char *out) { char buf[BUFFER_SIZE]; char *pti, *pto; int skip; push_call("string_to_font(%p,%d,%p,%p)",ses,flags,in,out); // DRAW_FLAG_FAT, DRAW_FLAG_ITALIC, DRAW_FLAG_SERIF, DRAW_FLAG_CURSIVE, DRAW_FLAG_GOTHIC, DRAW_FLAG_TRACED, DRAW_FLAG_MONO strcpy(buf, in); pti = buf; pto = out; while (*pti) { skip = skip_vt102_codes(pti); if (skip) { pto += sprintf(pto, "%.*s", skip, pti); pti += skip; continue; } if (*pti >= 32) { switch (HAS_BIT(flags, DRAW_FLAG_FAT|DRAW_FLAG_CURSIVE|DRAW_FLAG_SANSSERIF)) { case DRAW_FLAG_CURSIVE: pto += sprintf(pto, "%s", alnum_cursive[(int) *pti]); break; case DRAW_FLAG_FAT: pto += sprintf(pto, "%s", alnum_normal_fat[(int) *pti]); break; case DRAW_FLAG_SANSSERIF: pto += sprintf(pto, "%s", alnum_sansserif[(int) *pti]); break; default: *pto++ = *pti; break; } pti++; } else { *pto++ = *pti++; } } *pto++ = 0; pop_call(); return; } int find_stamp(char *in, char *out) { int cnt; for (cnt = 0 ; huge_stamp_table[cnt].name != NULL ; cnt++) { if (!strcmp(in, huge_stamp_table[cnt].name)) { strcpy(out, huge_stamp_table[cnt].desc); return huge_stamp_table[cnt].length; } } tintin_printf2(gtd->ses, "debug: didn't find stamp {%s}", in); return 0; } void stamp_cat(char *color, long long flags, char *str, char *cat, char *out) { char *pts = str; char *ptc = cat; char *pto = out; while (*pts || *ptc) { while (*pts && *pts != '\n') { *pto++ = *pts++; } pto += sprintf(pto, "%s", color); while (*ptc && *ptc != '\n') { if (HAS_BIT(flags, DRAW_FLAG_SHADOWED)) { *pto++ = *ptc++; } else if (HAS_BIT(flags, DRAW_FLAG_TRACED)) { if (!strncmp(ptc, "โ•—", 3)) { pto += sprintf(pto, "โ”"); ptc += strlen("โ•—"); } else if (!strncmp(ptc, "โ•‘", 3)) { pto += sprintf(pto, "โ”‚"); ptc += strlen("โ•‘"); } else if (!strncmp(ptc, "โ•", 3)) { pto += sprintf(pto, "โ”˜"); ptc += strlen("โ•"); } else if (!strncmp(ptc, "โ•š", 3)) { pto += sprintf(pto, "โ””"); ptc += strlen("โ•š"); } else if (!strncmp(ptc, "โ•”", 3)) { pto += sprintf(pto, "โ”Œ"); ptc += strlen("โ•”"); } else if (!strncmp(ptc, "โ•", 3)) { pto += sprintf(pto, "โ”€"); ptc += strlen("โ•"); } else { *pto++ = *ptc++; } } else { if (!strncmp(ptc, "โ•—", 3)) { pto += sprintf(pto, " "); ptc += strlen("โ•—"); } else if (!strncmp(ptc, "โ•‘", 3)) { pto += sprintf(pto, " "); ptc += strlen("โ•‘"); } else if (!strncmp(ptc, "โ•", 3)) { pto += sprintf(pto, " "); ptc += strlen("โ•"); } else if (!strncmp(ptc, "โ•š", 3)) { pto += sprintf(pto, " "); ptc += strlen("โ•š"); } else if (!strncmp(ptc, "โ•”", 3)) { pto += sprintf(pto, " "); ptc += strlen("โ•”"); } else if (!strncmp(ptc, "โ•", 3)) { pto += sprintf(pto, " "); ptc += strlen("โ•"); } else { *pto++ = *ptc++; } } } if (*pts == '\n' && *ptc == '\n') { *pto++ = *pts++; ptc++; } else if (*ptc == '\n') { *pto++ = *ptc++; } } *pto = 0; } void string_to_stamp(struct session *ses, long long flags, char *in, char *out) { char *pti, *buf1, *buf2, *buf3, chr1[CHAR_SIZE], color[COLOR_SIZE] = { 0 }; int skip; push_call("string_to_stamp(%p,%d,%p,%p)",ses,flags,in,out); buf1 = str_alloc_stack(0); buf2 = str_alloc_stack(0); buf3 = str_alloc_stack(0); sub_arg_in_braces(ses, in, buf1, GET_ALL, SUB_COL|SUB_LIT|SUB_ESC); pti = buf1; buf3[0] = 0; while (*pti) { skip = skip_vt102_codes(pti); if (skip) { get_color_codes(color, pti, color, GET_ONE); pti += skip; continue; } pti = get_char(ses, pti, chr1); find_stamp(chr1, buf2); stamp_cat(color, flags, buf3, buf2, out); strcpy(buf3, out); } strcat(out, "\n"); pop_call(); return; } char *get_draw_corner(long long flags, char *str) { draw_cnt = (draw_cnt + 1) % 100; if (HAS_BIT(flags, DRAW_FLAG_NUMBERED)) { sprintf(draw_buf[draw_cnt], "%d", draw_cnt % 10); } else if (HAS_BIT(flags, DRAW_FLAG_PRUNED)) { if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { strcpy(draw_buf[draw_cnt], " "); } else { strcpy(draw_buf[draw_cnt], "\e[C"); } } else if (HAS_BIT(flags, DRAW_FLAG_BLANKED)) { strcpy(draw_buf[draw_cnt], " "); } else if (HAS_BIT(flags, DRAW_FLAG_UTF8)) { if (HAS_BIT(flags, DRAW_FLAG_CIRCLED)) { if (HAS_BIT(flags, DRAW_FLAG_CROSSED)) { strcpy(draw_buf[draw_cnt], "ฯด"); } else if (HAS_BIT(flags, DRAW_FLAG_FILLED)) { strcpy(draw_buf[draw_cnt], "โฌค"); } else if (HAS_BIT(flags, DRAW_FLAG_VER)) { strcpy(draw_buf[draw_cnt], "O"); } else { strcpy(draw_buf[draw_cnt], "โ—‹"); } } else if (HAS_BIT(flags, DRAW_FLAG_CROSSED)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•ฌ"); } else { strcpy(draw_buf[draw_cnt], "โ”ผ"); } } else if (HAS_BIT(flags, DRAW_FLAG_JEWELED)) { if (HAS_BIT(flags, DRAW_FLAG_FILLED)) { strcpy(draw_buf[draw_cnt], "โงซ"); } else { strcpy(draw_buf[draw_cnt], "โ—Š"); } } else if (HAS_BIT(flags, DRAW_FLAG_TEED)) { if (HAS_BIT(flags, DRAW_FLAG_HOR)) { if (HAS_BIT(flags, DRAW_FLAG_LEFT)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ• "); } else { strcpy(draw_buf[draw_cnt], "โ”œ"); } } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•ฃ"); } else { strcpy(draw_buf[draw_cnt], "โ”ค"); } } } else { if (HAS_BIT(flags, DRAW_FLAG_TOP)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•ฆ"); } else { strcpy(draw_buf[draw_cnt], "โ”ฌ"); } } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•ฉ"); } else { strcpy(draw_buf[draw_cnt], "โ”ด"); } } } } else if (HAS_BIT(flags, DRAW_FLAG_BOXED) || HAS_BIT(flags, DRAW_FLAG_CORNERED)) { if (HAS_BIT(flags, DRAW_FLAG_LEFT)) { if (HAS_BIT(flags, DRAW_FLAG_TOP)) { if (HAS_BIT(flags, DRAW_FLAG_ROUNDED)) { strcpy(draw_buf[draw_cnt], "โ•ญ"); } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•”"); } else { strcpy(draw_buf[draw_cnt], "โ”Œ"); } } } else if (HAS_BIT(flags, DRAW_FLAG_BOT)) { if (HAS_BIT(flags, DRAW_FLAG_ROUNDED)) { strcpy(draw_buf[draw_cnt], "โ•ฐ"); } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•š"); } else { strcpy(draw_buf[draw_cnt], "โ””"); } } } else { if (HAS_BIT(flags, DRAW_FLAG_HOR)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•"); } else { strcpy(draw_buf[draw_cnt], "โ”€"); } } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•‘"); } else { strcpy(draw_buf[draw_cnt], "โ”‚"); } } } } else if (HAS_BIT(flags, DRAW_FLAG_RIGHT)) { if (HAS_BIT(flags, DRAW_FLAG_TOP)) { if (HAS_BIT(flags, DRAW_FLAG_ROUNDED)) { strcpy(draw_buf[draw_cnt], "โ•ฎ"); } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•—"); } else { strcpy(draw_buf[draw_cnt], "โ”"); } } } else if (HAS_BIT(flags, DRAW_FLAG_BOT)) { if (HAS_BIT(flags, DRAW_FLAG_ROUNDED)) { strcpy(draw_buf[draw_cnt], "โ•ฏ"); } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•"); } else { strcpy(draw_buf[draw_cnt], "โ”˜"); } } } else { if (HAS_BIT(flags, DRAW_FLAG_HOR)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•"); } else { strcpy(draw_buf[draw_cnt], "โ”€"); } } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•‘"); } else { strcpy(draw_buf[draw_cnt], "โ”‚"); } } } } else { if (HAS_BIT(flags, DRAW_FLAG_HOR)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•"); } else { strcpy(draw_buf[draw_cnt], "โ”€"); } } else { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•‘"); } else { strcpy(draw_buf[draw_cnt], "โ”‚"); } } } } else { if (HAS_BIT(flags, DRAW_FLAG_HOR)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•"); } else { strcpy(draw_buf[draw_cnt], "โ”€"); } } else if (HAS_BIT(flags, DRAW_FLAG_VER)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•‘"); } else { strcpy(draw_buf[draw_cnt], "โ”‚"); } } else { strcpy(draw_buf[draw_cnt], "?"); } } } else { if (HAS_BIT(flags, DRAW_FLAG_CIRCLED) || HAS_BIT(flags, DRAW_FLAG_ROUNDED)) { strcpy(draw_buf[draw_cnt], "o"); } else if (HAS_BIT(flags, DRAW_FLAG_CROSSED)) { strcpy(draw_buf[draw_cnt], "+"); } else if (HAS_BIT(flags, DRAW_FLAG_VER)) { strcpy(draw_buf[draw_cnt], "|"); } else if (HAS_BIT(flags, DRAW_FLAG_HOR)) { strcpy(draw_buf[draw_cnt], "-"); } else { strcpy(draw_buf[draw_cnt], "+"); } } return draw_buf[draw_cnt]; } char *draw_horizontal(long long flags, char *str) { draw_cnt = (draw_cnt + 1) % 100; if (HAS_BIT(flags, DRAW_FLAG_BLANKED)) { if (HAS_BIT(flags, DRAW_FLAG_PRUNED) && !HAS_BIT(flags, DRAW_FLAG_SCROLL)) { strcpy(draw_buf[draw_cnt], "\e[C"); } else { strcpy(draw_buf[draw_cnt], " "); } } else if (HAS_BIT(flags, DRAW_FLAG_NUMBERED)) { sprintf(draw_buf[draw_cnt], "%d", draw_cnt % 10); } else if (HAS_BIT(flags, DRAW_FLAG_UTF8)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•"); } else { strcpy(draw_buf[draw_cnt], "โ”€"); } } else { strcpy(draw_buf[draw_cnt], "-"); } return draw_buf[draw_cnt]; } char *draw_vertical(long long flags, char *str) { draw_cnt = (draw_cnt + 1) % 100; if (!HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_HOR|DRAW_FLAG_VER|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT) || HAS_BIT(flags, DRAW_FLAG_BLANKED)) { if (HAS_BIT(flags, DRAW_FLAG_PRUNED) && !HAS_BIT(flags, DRAW_FLAG_SCROLL)) { strcpy(draw_buf[draw_cnt], "\e[C"); } else { strcpy(draw_buf[draw_cnt], " "); } } else if (HAS_BIT(flags, DRAW_FLAG_NUMBERED)) { sprintf(draw_buf[draw_cnt], "%d", draw_cnt % 10); } else if (HAS_BIT(flags, DRAW_FLAG_UTF8)) { if (HAS_BIT(flags, DRAW_FLAG_TUBED)) { strcpy(draw_buf[draw_cnt], "โ•‘"); } else { strcpy(draw_buf[draw_cnt], "โ”‚"); } } else { strcpy(draw_buf[draw_cnt], "|"); } return draw_buf[draw_cnt]; } // options DO_DRAW(draw_bot_side) { int col, corner; if (!HAS_BIT(flags, DRAW_FLAG_LEFT) && !HAS_BIT(flags, DRAW_FLAG_RIGHT) && !HAS_BIT(flags, DRAW_FLAG_BOT)) { return; } SET_BIT(flags, HAS_BIT(flags, DRAW_FLAG_VER) ? DRAW_FLAG_VER : DRAW_FLAG_HOR); corner = flags; DEL_BIT(corner, DRAW_FLAG_RIGHT|DRAW_FLAG_TOP); arg = arg1; if (HAS_BIT(flags, DRAW_FLAG_LEFT) || HAS_BIT(flags, DRAW_FLAG_BOT)) { SET_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_BOT); arg1 += sprintf(arg1, "%s%s", box_color, get_draw_corner(corner, "โ””")); } if (cols - 2 >= 0) { if (HAS_BIT(flags, DRAW_FLAG_BOT)) { for (col = top_col + 1 ; col < bot_col ; col++) { arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "โ”€")); } } else if (HAS_BIT(flags, DRAW_FLAG_RIGHT) && cols - 2 > 0) { arg1 += sprintf(arg1, "\e[%dC", cols - 2); } corner = flags; DEL_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_TOP); if (HAS_BIT(flags, DRAW_FLAG_RIGHT) || HAS_BIT(flags, DRAW_FLAG_BOT)) { SET_BIT(corner, DRAW_FLAG_RIGHT|DRAW_FLAG_BOT); arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "โ”˜")); } } if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { tintin_printf2(ses, "%s%s", indent_one(top_col - 1), arg); } else { goto_pos(ses, bot_row, top_col); print_stdout(bot_row, top_col, "%s", arg); } } /* DO_DRAW(draw_arg) { arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); top_row = get_row_index_arg(ses, arg1); arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); top_col = get_col_index_arg(ses, arg1); arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); bot_row = get_row_index_arg(ses, arg1); arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); bot_col = get_col_index_arg(ses, arg1); rows = URANGE(1, 1 + bot_row - top_row, gtd->screen->rows); cols = URANGE(1, 1 + bot_col - top_col, gtd->screen->cols); save_pos(ses); draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, arg2, arg1, arg, arg3); restore_pos(ses); } */ DO_DRAW(draw_box) { if (HAS_BIT(flags, DRAW_FLAG_TOP)) { draw_top_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); } draw_vertical_lines(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); if (HAS_BIT(flags, DRAW_FLAG_BOT)) { draw_bot_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); } } DO_DRAW(draw_buffer) { char *buf; int cnt, line; push_call("draw_buffer(%p,...)",ses); buf = str_alloc_stack(0); if (ses->scroll->line == -1) { line = ses->scroll->used - 1; } else { line = ses->scroll->line; } for (cnt = rows ; cnt >= 0 ; cnt--) { if (line - cnt >= 0) { str_cat_printf(&buf, "{%s}", ses->scroll->buffer[line - cnt]->str); } } tintin_printf2(gtd->ses, "[%d] (%d) (%s)", line, rows, buf); draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, buf, arg1, arg2, arg3); pop_call(); return; } DO_DRAW(draw_corner) { if (*arg) { strcpy(arg1, arg); } else { strcpy(arg1, get_draw_corner(flags, " ")); } if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { tintin_printf2(ses, "%s%s%s", indent_one(top_col - 1), box_color, arg1); } else { goto_pos(ses, top_row, top_col); print_stdout(top_row, top_col, "%s%s", box_color, arg1); } } DO_DRAW(draw_line_horizontal) { int col, corner, ins_len; char *line; if (!HAS_BIT(flags, DRAW_FLAG_VER)) { SET_BIT(flags, DRAW_FLAG_HOR); } if (HAS_BIT(flags, DRAW_FLAG_APPENDIX)) { if (!HAS_BIT(flags, DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT)) { SET_BIT(flags, DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT); } } corner = flags; sub_arg_in_braces(ses, arg, arg2, GET_ALL, SUB_COL|SUB_LIT|SUB_ESC); arg = arg2; line = arg1; arg1 += sprintf(arg1, "%s", box_color); if (HAS_BIT(flags, DRAW_FLAG_LEFT)) { DEL_BIT(corner, DRAW_FLAG_RIGHT); arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "โ”Œ")); } else { arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "โ”€")); } if (cols - 2 > 0) { for (col = top_col + 1 ; col < bot_col ; col++) { arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "โ”€")); } } if (HAS_BIT(flags, DRAW_FLAG_RIGHT) && cols - 2 > 0) { SET_BIT(corner, DRAW_FLAG_RIGHT); DEL_BIT(corner, DRAW_FLAG_LEFT); arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "โ”")); } else { arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "โ”€")); } if (*arg) { str_fix(line); if (*txt_color) { str_cpy_printf(&arg, "%s%s", txt_color, arg); } ins_len = UMIN(cols, strip_vt102_strlen(ses, arg)); if (HAS_BIT(flags, DRAW_FLAG_RALIGN)) { str_ins_str(ses, &line, arg, cols - ins_len, cols); } else if (HAS_BIT(flags, DRAW_FLAG_CALIGN)) { str_ins_str(ses, &line, arg, cols / 2 - ins_len / 2, -1); } else { str_ins_str(ses, &line, arg, 0, ins_len); } } if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { tintin_printf2(ses, "%*s%s", top_col - 1, "", line); } else { goto_pos(ses, top_row, top_col); print_stdout(top_row, top_col, "%s", line); } } DO_DRAW(draw_line_vertical) { int row, corner; if (!HAS_BIT(flags, DRAW_FLAG_HOR)) { SET_BIT(flags, DRAW_FLAG_VER); } if (HAS_BIT(flags, DRAW_FLAG_APPENDIX)) { if (!HAS_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT)) { SET_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT); } } corner = flags; arg = arg1; if (HAS_BIT(flags, DRAW_FLAG_TOP)) { DEL_BIT(corner, DRAW_FLAG_BOT); arg1 += sprintf(arg1, "{%s}", get_draw_corner(corner, "โ”ฌ")); } else { arg1 += sprintf(arg1, "{%s}", draw_vertical(flags, "โ”‚")); } if (rows - 2 > 0) { for (row = top_row + 1 ; row < bot_row ; row++) { arg1 += sprintf(arg1, "{%s}", draw_vertical(flags, "โ”‚")); } } if (HAS_BIT(flags, DRAW_FLAG_BOT)) { SET_BIT(corner, DRAW_FLAG_BOT); DEL_BIT(corner, DRAW_FLAG_TOP); arg1 += sprintf(arg1, "{%s}", get_draw_corner(corner, "โ”ด")); } else { arg1 += sprintf(arg1, "{%s}", draw_vertical(flags, "โ”‚")); } row = top_row; while (*arg) { arg = get_arg_in_braces(ses, arg, arg2, GET_ONE); if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { tintin_printf2(ses, "%*s%s%s", top_col - 1, "", box_color, arg2); } else { goto_pos(ses, row, top_col); print_stdout(row, top_col, "%s%s", box_color, arg2); } row++; } return; } DO_DRAW(draw_line) { if (top_row == bot_row) { draw_line_horizontal(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); return; } if (top_col == bot_col) { draw_line_vertical(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); return; } draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); } DO_DRAW(draw_map) { int map_rows = rows; int map_cols = cols; if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_TOP|DRAW_FLAG_PRUNED)) { map_rows--; } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_BOT|DRAW_FLAG_PRUNED)) { map_rows--; } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_PRUNED)) { map_cols--; } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_RIGHT|DRAW_FLAG_PRUNED)) { map_cols--; } if (ses->map && ses->map->in_room) { sprintf(arg, "{%d} {%d} {SAVE}", map_rows, map_cols); map_map(ses, arg, arg1, arg2, arg3); } else { str_cpy(>d->buf, "{}"); } if (HAS_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT)) { draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3); } else { draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3); } } // ideas // 0 use color gradients // 1 use inverse color so text can be added to solid blocks. // 2 use ralign for raligned bar // 3 use calign for centered bar // 4 use box drawing modifiers if no box is specified. // 4.1 rounded = (###) // 4.2 teed = [---] // 4.3 jeweled = <###> // 4.4 crossed = +++++ // 4.5 circled = OOOOO // 4.6 pruned = no rounding // hpbar {val;max;color} DO_DRAW(draw_hbar) { char *nest, *buf, *ptb, *col1; int cnt, val, bar; long double min, max; bar = cols; bar -= HAS_BIT(flags, DRAW_FLAG_LEFT) ? 1 : 0; bar -= HAS_BIT(flags, DRAW_FLAG_RIGHT) ? 1 : 0; if (bar <= 0) { show_error(ses, LIST_COMMAND, "#ERROR: #DRAW BAR %d %d %d %d: DRAWING WIDTH (%d) MUST BE GREATER THAN 0.", top_row, top_col, bot_row, bot_col, bar); return; } buf = str_alloc_stack(0); col1 = str_alloc_stack(0); str_cpy(>d->buf, ""); bar *= 8; start: arg = get_arg_in_braces(ses, arg, buf, GET_ALL); nest = buf; nest = get_arg_in_braces(ses, nest, arg1, GET_ALL); if (*nest == COMMAND_SEPARATOR) nest++; nest = get_arg_in_braces(ses, nest, arg2, GET_ALL); if (*nest == COMMAND_SEPARATOR) nest++; nest = get_arg_in_braces(ses, nest, arg3, GET_ALL); min = get_number(ses, arg1); max = get_number(ses, arg2); if (max <= 0) { show_error(ses, LIST_COMMAND, "#ERROR: #DRAW BAR {%s;%s;%s}: MAX (%Lg) MUST BE GREATER THAN 0.", arg1, arg2, arg3, max); return; } if (min > max) { min = max; } color_gradient(arg3, min, max); translate_color_names(ses, arg3, col1); // printf("debug: min %d max %d bar %d\n", (int) min, (int) max, bar); ptb = buf; ptb += sprintf(ptb, "{%s", col1); val = bar * min / max; for (cnt = 8 ; cnt <= bar + 8 ; cnt += 8) { // printf("debug: cnt %3d - val = %3d\n", cnt, val); if (cnt > val) { break; } ptb += sprintf(ptb, "โ–ˆ"); } // printf("debug: val - lst = %d - %d\n", val, lst); if (cnt <= bar) { switch (val + 8 - cnt) { case 0: ptb += sprintf(ptb, " "); break; case 1: ptb += sprintf(ptb, "โ–"); break; case 2: ptb += sprintf(ptb, "โ–Ž"); break; case 3: ptb += sprintf(ptb, "โ–"); break; case 4: ptb += sprintf(ptb, "โ–Œ"); break; case 5: ptb += sprintf(ptb, "โ–‹"); break; case 6: ptb += sprintf(ptb, "โ–Š"); break; case 7: ptb += sprintf(ptb, "โ–‰"); break; case 8: ptb += sprintf(ptb, "โ–ˆ"); break; } ptb += snprintf(ptb, BUFFER_SIZE, "%*s%s}", (bar - cnt) / 8, "", box_color); } else { ptb += sprintf(ptb, "%s}", box_color); } str_cat(>d->buf, buf); // printf("debug (%s) bar: %d cnt %d val %d\n", gtd->buf, bar, cnt, val); if (*arg) { goto start; } *arg1 = 0; *arg2 = 0; *arg3 = 0; if (HAS_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT)) { draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3); } else { draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3); } } char *rain_symbols = "๏พ›๏ฝฆ๏ฝฑ๏ฝณ๏ฝด๏ฝต๏ฝถ๏ฝท๏ฝน๏ฝบ๏ฝป๏ฝผ๏ฝฝ๏ฝพ๏ฝฟ๏พ€๏พ‚๏พƒ๏พ…๏พ†๏พ‡๏พˆ๏พŠ๏พ‹๏พŽ๏พ๏พ๏พ‘๏พ’๏พ“๏พ”๏พ•๏พ—๏พ˜๏พœ01Sิ45789Z=*+-ยฆ|_สบโ•Œ"; char *braille_symbols = "โ โ ‚โ ƒโ „โ …โ †โ ‡โ ˆโ Šโ Œโ Žโ โ ‘โ ”โ •โ ˜โ œโ  โ กโ ขโ ฃโ จโ ชโ ฐโ ฑโ ธโก€โกโก‚โกƒโก„โก…โก†โก‡โกˆโกŠโกŒโกŽโกโก‘โก”โก•โก˜โกœโก โกกโกขโกฃโกจโกชโกฐโกฑโกธโข€โขโข‚โขƒโข„โข…โข†โข‡โขˆโข‰โขŠโขŒโขŽโขโข‘โข”โข•โข˜โขœโข โขกโขขโขฃโขจโขชโขฐโขฑ"; DO_DRAW(draw_rain) { char code[BUFFER_SIZE], arg4[BUFFER_SIZE], *rain[400]; struct listnode *node; int row, col, len, rand, cnt, size, max, utfs[400]; long double density, fade; strcpy(code, arg2); arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); if (!valid_variable(ses, arg1)) { show_error(ses, LIST_COMMAND, "#SYNTAX: #DRAW RAIN %d %d %d %d [SPAWN] [FADE] [LEGEND]", top_row, top_col, bot_row, bot_col); return; } node = search_nest_node_ses(ses, arg1); if (node == NULL || node->root == NULL) { node = set_nest_node(ses->list[LIST_VARIABLE], arg1, "{0}{}"); } arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); if (*arg1 == 0) { density = 1; } else { density = URANGE(0.01, get_number(ses, arg1), 100); } arg = get_arg_in_braces(ses, arg, arg1, GET_ONE); if (*arg1 == 0) { fade = 10; } else { fade = URANGE(1, get_number(ses, arg1), 100); } arg = get_arg_in_braces(ses, arg, arg4, GET_ONE); if (*arg4 == 0) { if (HAS_BIT(ses->config_flags, CONFIG_FLAG_SCREENREADER)) { for (max = len = 0 ; braille_symbols[len] ; max++) { rain[max] = &braille_symbols[len]; utfs[max] = get_utf8_size(&braille_symbols[len]); len += utfs[max]; } } else { for (max = len = 0 ; rain_symbols[len] ; max++) { rain[max] = &rain_symbols[len]; utfs[max] = get_utf8_size(&rain_symbols[len]); len += utfs[max]; } } } else { for (max = len = 0 ; arg4[len] && max < 400 ; max++) { rain[max] = &arg4[len]; utfs[max] = get_utf8_size(&arg4[len]); len += utfs[max]; } } // tintin_printf2(ses, "debug: [%s] (%s) <%s>", code, fuzzy_color_code(ses, code), dim_color_code(ses, code, 20)); for (col = 0 ; col < 1 + bot_col - top_col ; col++) { if (node->root->used <= col) { set_nest_node(node->root, ntos(col), ""); } if (node->root->list[col]->val16[0] == 0) { if (generate_rand(ses) % 10000 / (long double) 100 < density) { rand = generate_rand(ses) % rows; node->root->list[col]->val16[0] = 1; node->root->list[col]->val16[1] = rand; node->root->list[col]->val16[2] = rand < rows / 2 ? 2 : 0; node->root->list[col]->val16[3] = 0; str_cpy_printf(&node->root->list[col]->arg2, "%*s", rand, ""); } continue; } else if (node->root->list[col]->val16[0] == 1) { if (node->root->list[col]->val16[2]) { node->root->list[col]->val16[3]++; if (node->root->list[col]->val16[3] % 2) { rand = generate_rand(ses) % max; snprintf(arg2, BUFFER_SIZE, "%s%.*s", lit_color_code(ses, code, 10), utfs[rand], rain[rand]); substitute(ses, arg2, arg3, SUB_COL); goto_pos(ses, top_row + node->root->list[col]->val16[1], top_col + col); print_stdout(0, 0, "%s", arg3); continue; } } rand = generate_rand(ses) % max; str_cat_printf(&node->root->list[col]->arg2, "%.*s", utfs[rand], rain[rand]); node->root->list[col]->val16[1]++; if (generate_rand(ses) % 10000 / (long double) 100 < fade) { node->root->list[col]->val16[0] = 2; } else if (node->root->list[col]->val16[1] > rows - generate_rand(ses) % 8) { node->root->list[col]->val16[0] = 2; } } else { node->root->list[col]->val16[0]++; } len = str_len(node->root->list[col]->arg2); row = 0; cnt = 0; if (node->root->list[col]->val16[0] == 1) { while (row < len) { if (node->root->list[col]->arg2[row] == ' ') { cnt++; row++; continue; } goto_pos(ses, top_row + cnt, top_col + col); cnt++; size = get_utf8_size(&node->root->list[col]->arg2[row]); if (cnt == node->root->list[col]->val16[1]) { snprintf(arg2, BUFFER_SIZE, "%s%.*s", lit_color_code(ses, code, 5), size, &node->root->list[col]->arg2[row]); } else { if (node->root->list[col]->val16[1] % 2 == 0) { row += size; continue; } snprintf(arg2, BUFFER_SIZE, "%s%.*s", fuzzy_color_code(ses, code), size, &node->root->list[col]->arg2[row]); } substitute(ses, arg2, arg3, SUB_COL); print_stdout(0, 0, "%s", arg3); row += size; } } else if (node->root->list[col]->val16[0] > 1) { while (row < len) { if (node->root->list[col]->arg2[row] == ' ') { cnt++; row++; continue; } goto_pos(ses, top_row + cnt, top_col + col); cnt++; size = get_utf8_size(&node->root->list[col]->arg2[row]); if (node->root->list[col]->val16[0] - cnt > 15) { sprintf(arg2, "%s ", dim_color_code(ses, code, node->root->list[col]->val16[0] - cnt)); substitute(ses, arg2, arg3, SUB_COL); print_stdout(0, 0, "%s", arg3); print_stdout(0, 0, " "); } else if (node->root->list[col]->val16[0] - cnt < 0) { snprintf(arg2, BUFFER_SIZE, "%s%.*s", fuzzy_color_code(ses, code), size, &node->root->list[col]->arg2[row]); substitute(ses, arg2, arg3, SUB_COL); print_stdout(0, 0, "%s", arg3); } else { snprintf(arg2, BUFFER_SIZE, "%s%.*s", dim_color_code(ses, code, node->root->list[col]->val16[0] - cnt), size, &node->root->list[col]->arg2[row]); substitute(ses, arg2, arg3, SUB_COL); print_stdout(0, 0, "%s", arg3); } row += size; } if (node->root->list[col]->val16[0] - cnt > 16) { node->root->list[col]->val16[0] = 0; node->root->list[col]->val16[1] = 0; str_cpy(&node->root->list[col]->arg2, ""); } } else { tintin_printf2(ses, "debug: problemo"); } } } DO_DRAW(draw_side) { push_call("draw_side()"); draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); pop_call(); return; } DO_DRAW(draw_square) { if (HAS_BIT(flags, DRAW_FLAG_TOP)) { draw_top_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); } draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); if (HAS_BIT(flags, DRAW_FLAG_BOT)) { draw_bot_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); } } DO_DRAW(draw_table_grid) { char buf1[BUFFER_SIZE], *str, buf2[BUFFER_SIZE], buf3[BUFFER_SIZE], row_color[COLOR_SIZE]; int corner, blank, row, col, max_r, max_c, r, c, top_r, top_c, bot_r, bot_c, tot_r, tot_c; row = cnt_arg_all(ses, arg, GET_ALL); row = URANGE(0, row, (rows - 1) / 2); get_arg_in_braces(ses, arg, buf1, GET_ALL); col = cnt_arg_all(ses, buf1, GET_ALL); if (row == 0 || col == 0) { tintin_printf2(ses, "#ERROR: #DRAW TABLE: NEED AT LEAST 1 ROW AND 1 COLUMN."); return; } if (*arg3) { substitute(ses, arg3, row_color, SUB_COL|SUB_LIT|SUB_ESC); } else { row_color[0] = 0; } corner = flags; DEL_BIT(corner, DRAW_FLAG_LEFT | DRAW_FLAG_RIGHT | DRAW_FLAG_TOP | DRAW_FLAG_BOT); if (HAS_BIT(flags, DRAW_FLAG_GRID)) { max_r = (rows - 1) / row; max_c = (cols - 1) / col; tot_r = 1 + max_r * row; tot_c = 1 + max_c * col; if (max_r <= 0) { tintin_printf2(ses, "#ERROR: #DRAW TABLE: ROW SIZE TOO SMALL."); return; } if (max_c <= 0) { tintin_printf2(ses, "#ERROR: #DRAW TABLE: COLUMN SIZE TOO SMALL."); return; } for (r = 0 ; r < tot_r ; r++) { buf3[0] = 0; if (r % max_r == 0) { arg = get_arg_in_braces(ses, arg, buf1, GET_ALL); str = buf1; if (*arg == COMMAND_SEPARATOR) { arg++; } } else { str = buf1; } for (c = 0 ; c < tot_c ; c++) { if (r == 0) { if (c == 0) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_LEFT | DRAW_FLAG_TOP, "โ”Œ")); } else if (c == tot_c - 1) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_RIGHT | DRAW_FLAG_TOP, "โ”")); } else if (c % max_c == 0) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_TOP, "โ”ฌ")); } else { strcat(buf3, draw_horizontal(flags, "?")); } } else if (r == tot_r - 1) { if (c == 0) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_LEFT | DRAW_FLAG_BOT, "?")); } else if (c == tot_c - 1) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_RIGHT | DRAW_FLAG_BOT, "?")); } else if (c % max_c == 0) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_BOT, "โ”ฌ")); } else { strcat(buf3, draw_horizontal(flags, "?")); } } else if (r % max_r == 0) { if (c == 0) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_HOR | DRAW_FLAG_LEFT, "?")); } else if (c == tot_c - 1) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_HOR | DRAW_FLAG_RIGHT, "?")); } else if (c % max_c == 0) { strcat(buf3, get_draw_corner(corner | DRAW_FLAG_CROSSED, "?")); } else { strcat(buf3, draw_horizontal(flags, "?")); } } else if (r % max_r == 1) { if (c == tot_c - 1) { if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { cat_sprintf(buf3, "%s", draw_vertical(flags, "โ”‚")); } else { goto_pos(ses, top_row + r, top_col + c); print_stdout(top_row + r, top_col + c, "%s%s", box_color, draw_vertical(flags, "โ”‚")); } } else if (c == 0 || c % max_c == 0) { strcpy(buf2, row_color); str = sub_arg_in_braces(ses, str, buf2 + strlen(buf2), GET_ALL, SUB_LIT|SUB_ESC|SUB_COL); // get_color_codes(row_color, buf2, row_color, GET_ALL); top_r = top_row + r - 1; top_c = top_col + c; bot_r = top_row + r - 1 + max_r; bot_c = top_col + c + max_c; draw_vertical_lines(ses, top_r, top_c, top_r, bot_c, 1 + max_r, 1 + max_c, corner | DRAW_FLAG_LEFT, box_color, txt_color, buf2, arg1, arg2, arg3); if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { strcat(buf3, arg2); } if (*str == COMMAND_SEPARATOR) { str++; } } } else { if (c == tot_c - 1) { if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { cat_sprintf(buf3, "%s", draw_vertical(flags, "โ”‚")); } else { goto_pos(ses, top_row + r, top_col + c); print_stdout(top_row + r, top_col + c, "%s%s", box_color, draw_vertical(flags, "โ”‚")); } } } } if (*buf3) { if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { tintin_printf2(ses, "%s%s%s", indent_one(top_col - 1), box_color, buf3); } else { goto_pos(ses, top_row + r, top_col); print_stdout(top_row + r, top_col, "%s%s", box_color, buf3); } } } return; } blank = flags; DEL_BIT(blank, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT); max_r = rows / row; max_c = cols / col; for (r = 0 ; r < row ; r++) { top_r = top_row + r * max_r; bot_r = top_row + r * max_r + max_r - 1; arg = get_arg_in_braces(ses, arg, buf1, GET_ALL); str = buf1; for (c = 0 ; c < col ; c++) { str = get_arg_in_braces(ses, str, buf2, GET_ALL); top_c = top_col + c * max_c; bot_c = top_col + c * max_c + max_c - 1; draw_box(ses, top_r, top_c, bot_r, bot_c, 1 + bot_r - top_r, 1 + bot_c - top_c, flags, box_color, txt_color, buf2, arg1, arg2, arg3); // tintin_printf2(ses, "#draw box %d %d %d %d %s", top_row + r * max_r, top_col + c * max_c, top_row + r * max_r + max_r, top_col + c * max_c + max_c, buf1); if (*str == COMMAND_SEPARATOR) { str++; } } if (cols > max_c * col) { top_c = top_col + c * max_c; bot_c = bot_col; draw_text(ses, top_r, top_c, bot_r, bot_c, 1 + bot_r - top_r, 1 + bot_c - top_c, blank, box_color, txt_color, "", arg1, arg2, arg3); } if (*arg == COMMAND_SEPARATOR) { arg++; } } } DO_DRAW(draw_text) { char *txt, *buf1, *buf2, *buf3, side1[100], side2[100]; int row, col, height, width; push_call("draw_text(%p,%d,%p,%p,%p)",ses,flags,arg,arg1,arg2); buf1 = str_alloc_stack(0); buf2 = str_alloc_stack(0); buf3 = str_alloc_stack(0); side1[0] = side2[0] = arg2[0] = 0; txt = buf2; if (*arg3) { txt += substitute(ses, arg3, txt, SUB_COL|SUB_LIT|SUB_ESC); } if (HAS_BIT(flags, DRAW_FLAG_HUGE)) { string_to_stamp(ses, flags, arg, txt); } else { while (*arg) { arg = sub_arg_in_braces(ses, arg, buf1, GET_ALL, SUB_COL|SUB_LIT|SUB_ESC); txt += sprintf(txt, "%s\n", buf1); if (*arg == COMMAND_SEPARATOR) { arg++; } } if (HAS_BIT(flags, DRAW_FLAG_FAT|DRAW_FLAG_CURSIVE|DRAW_FLAG_SANSSERIF)) { string_to_font(ses, flags, buf2, buf2); } } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_TOP|DRAW_FLAG_BLANKED|DRAW_FLAG_PRUNED)) { top_row++; rows--; } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_BOT|DRAW_FLAG_BLANKED|DRAW_FLAG_PRUNED)) { bot_row--; rows--; } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_BLANKED|DRAW_FLAG_PRUNED)) { cols--; } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_RIGHT|DRAW_FLAG_BLANKED|DRAW_FLAG_PRUNED)) { cols--; } if (HAS_BIT(flags, DRAW_FLAG_UALIGN)) { ualign(ses, buf2, buf3, cols); word_wrap_split(ses, buf3, buf1, cols, 0, 0, FLAG_NONE, &height, &width); } else { word_wrap_split(ses, buf2, buf1, cols, 0, 0, FLAG_NONE, &height, &width); } height--; txt = buf1; if (HAS_BIT(flags, DRAW_FLAG_BALIGN)) { str_fix(buf1); if (HAS_BIT(flags, DRAW_FLAG_TALIGN)) { while (height < rows - 1) { str_ins(&buf1, 0, "\n"); str_cat(&buf1, "\n"); height += 2; } } else { while (height < rows) { str_ins(&buf1, 0, "\n"); height++; } } } if (HAS_BIT(flags, DRAW_FLAG_TALIGN)) { height = 0; while (*txt && height < rows) { txt = strchr(txt, '\n'); txt++; height++; } *txt = 0; txt = buf1; } else { while (*txt && height && height > rows) { txt = strchr(txt, '\n'); txt++; height--; } } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_BLANKED|DRAW_FLAG_PRUNED)) { strcpy(side1, draw_vertical(flags, "โ”‚")); } if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_RIGHT|DRAW_FLAG_BLANKED|DRAW_FLAG_PRUNED)) { strcpy(side2, draw_vertical(flags, "โ”‚")); } row = top_row; col = top_col; arg = txt; while (*arg) { arg = strchr(arg, '\n'); if (arg) { *arg++ = 0; } else { break; } if (HAS_BIT(flags, DRAW_FLAG_CONVERT)) { convert_meta(txt, buf3, FALSE); justify_string(ses, buf3, buf2, 0 - cols, cols); } else if (HAS_BIT(flags, DRAW_FLAG_CALIGN|DRAW_FLAG_LALIGN|DRAW_FLAG_RALIGN)) { if (HAS_BIT(flags, DRAW_FLAG_CALIGN) || HAS_BIT(flags, DRAW_FLAG_LALIGN|DRAW_FLAG_RALIGN) == DRAW_FLAG_LALIGN+DRAW_FLAG_RALIGN) { calign(ses, txt, buf3, cols); } else if (HAS_BIT(flags, DRAW_FLAG_LALIGN)) { lalign(ses, txt, buf3, cols); } else { ralign(ses, txt, buf3, cols); } justify_string(ses, buf3, buf2, 0 - cols, cols); } else { justify_string(ses, txt, buf2, 0 - cols, cols); } if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { if (HAS_BIT(flags, DRAW_FLAG_GRID)) { cat_sprintf(arg2, "%s%s%s%s%s", box_color, side1, buf2, box_color, side2); } else { tintin_printf2(ses, "%s%s%s%s%s%s", indent_one(top_col - 1), box_color, side1, buf2, box_color, side2); } } else { goto_pos(ses, row, col); print_stdout(row, col, "%s%s%s%s%s", box_color, side1, buf2, box_color, side2); } row++; txt = arg; } while (height < rows) { if (HAS_BIT(flags, DRAW_FLAG_LEFT)) { strcpy(side1, draw_vertical(flags, "โ”‚")); } if (HAS_BIT(flags, DRAW_FLAG_RIGHT)) { strcpy(side2, draw_vertical(flags, "โ”‚")); } if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { if (HAS_BIT(flags, DRAW_FLAG_GRID)) { cat_sprintf(arg2, "%s%s%*s%s%s", box_color, side1, cols, "", box_color, side2); } else { tintin_printf2(ses, "%s%s%s%-*s%s%s", indent_one(top_col - 1), box_color, side1, cols, "", box_color, side2); } } else { goto_pos(ses, row, col); print_stdout(row, col, "%s%s%*s%s%s", box_color, side1, cols, "", box_color, side2); row++; } height++; } pop_call(); return; } DO_DRAW(draw_top_side) { int col, corner; SET_BIT(flags, HAS_BIT(flags, DRAW_FLAG_VER) ? DRAW_FLAG_VER : DRAW_FLAG_HOR); corner = flags; DEL_BIT(corner, DRAW_FLAG_RIGHT|DRAW_FLAG_BOT); arg = arg1; if (HAS_BIT(flags, DRAW_FLAG_LEFT) || HAS_BIT(flags, DRAW_FLAG_TOP)) { SET_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_TOP); arg1 += sprintf(arg1, "%s%s", box_color, get_draw_corner(corner, "โ”Œ")); } if (cols - 2 >= 0) { if (HAS_BIT(flags, DRAW_FLAG_TOP)) { for (col = top_col + 1 ; col < bot_col ; col++) { arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "โ”€")); } } else if (HAS_BIT(flags, DRAW_FLAG_RIGHT) && cols - 2 > 0) { arg1 += sprintf(arg1, "\e[%dC", cols - 2); } corner = flags; DEL_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_BOT); if (HAS_BIT(flags, DRAW_FLAG_TOP) || HAS_BIT(flags, DRAW_FLAG_RIGHT)) { SET_BIT(corner, DRAW_FLAG_RIGHT|DRAW_FLAG_TOP); arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "โ”")); } } if (HAS_BIT(flags, DRAW_FLAG_SCROLL)) { tintin_printf2(ses, "%*s%s", top_col - 1, "", arg); } else { goto_pos(ses, top_row, top_col); print_stdout(top_row, top_col, "%s", arg); } } DO_DRAW(draw_vertical_lines) { int row; push_call("draw_vertical_lines(%p,%d,%p,%p,%p)",ses,flags,arg,arg1,arg2); if (HAS_BIT(flags, DRAW_FLAG_SCROLL) || *arg) { draw_text(ses, top_row, top_col, bot_row, top_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3); pop_call(); return; } arg1[0] = arg2[0] = 0; if (HAS_BIT(flags, DRAW_FLAG_BOXED) || HAS_BIT(flags, DRAW_FLAG_TOP)) { top_row++; rows--; } if (HAS_BIT(flags, DRAW_FLAG_BOXED) || HAS_BIT(flags, DRAW_FLAG_BOT)) { bot_row--; rows--; } if (HAS_BIT(flags, DRAW_FLAG_LEFT)) { strcpy(arg1, draw_vertical(flags, "โ”‚")); cols--; } if (HAS_BIT(flags, DRAW_FLAG_RIGHT)) { strcpy(arg2, draw_vertical(flags, "โ”‚")); cols--; } // tintin_printf2(ses, "debug: rows = %d", rows); if (*arg1) { row = top_row; while (row <= bot_row) { goto_pos(ses, row, top_col); print_stdout(row, top_col, "%s%s", box_color, arg1); row++; } } if (*arg2) { row = top_row; while (row <= bot_row) { goto_pos(ses, row, bot_col); print_stdout(row, bot_col, "%s%s", box_color, arg2); row++; } } pop_call(); return; }