1 /******************************************************************************
2 * This file is part of TinTin++ *
3 * *
4 * Copyright 2004-2020 Igor van den Hoven *
5 * *
6 * TinTin++ is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with TinTin++. If not, see https://www.gnu.org/licenses. *
18 ******************************************************************************/
19
20 /******************************************************************************
21 * T I N T I N + + *
22 * *
23 * coded by Igor van den Hoven 2019 *
24 ******************************************************************************/
25
26 static char draw_buf[100][10];
27 static int draw_cnt;
28
29 #include "tintin.h"
30
31 #define DRAW_FLAG_NONE 0
32 #define DRAW_FLAG_ASCII BV01
33 #define DRAW_FLAG_BLANKED BV02
34 #define DRAW_FLAG_BOT BV03
35 #define DRAW_FLAG_BOXED BV04
36 #define DRAW_FLAG_BUMP BV05
37 #define DRAW_FLAG_CIRCLED BV06
38 #define DRAW_FLAG_COLOR1 BV07
39 #define DRAW_FLAG_COLOR2 BV08
40 #define DRAW_FLAG_CONVERT BV09
41 #define DRAW_FLAG_CORNERED BV10
42 #define DRAW_FLAG_CROSSED BV11
43 #define DRAW_FLAG_FILLED BV12
44 #define DRAW_FLAG_FOREGROUND BV13
45 #define DRAW_FLAG_GRID BV14
46 #define DRAW_FLAG_HOR BV15
47 #define DRAW_FLAG_HUGE BV16
48 #define DRAW_FLAG_JEWELED BV17
49 #define DRAW_FLAG_LEFT BV18
50 //#define DRAW_FLAG_LINED BV19 unused / obsolete
51 #define DRAW_FLAG_NUMBERED BV20
52 #define DRAW_FLAG_PRUNED BV21
53 #define DRAW_FLAG_RIGHT BV22
54 #define DRAW_FLAG_ROUNDED BV23
55 #define DRAW_FLAG_SCALED BV24
56 #define DRAW_FLAG_SCROLL BV25
57 #define DRAW_FLAG_SHADOWED BV26
58 #define DRAW_FLAG_TEED BV27
59 #define DRAW_FLAG_TOP BV28
60 #define DRAW_FLAG_TRACED BV29
61 #define DRAW_FLAG_TUBED BV30
62 #define DRAW_FLAG_UTF8 BV31
63 #define DRAW_FLAG_VER BV32
64
65 #define DRAW_FLAG_CURSIVE BV33
66 #define DRAW_FLAG_FAT BV34
67 #define DRAW_FLAG_SANSSERIF BV35
68 #define DRAW_FLAG_CALIGN BV36
69 #define DRAW_FLAG_LALIGN BV37
70 #define DRAW_FLAG_RALIGN BV38
71 #define DRAW_FLAG_TALIGN BV39
72 #define DRAW_FLAG_UALIGN BV40
73 #define DRAW_FLAG_BALIGN BV41
74
75 #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
76
77
78
79 #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)
80
81 extern DO_DRAW(draw_blank);
82 extern DO_DRAW(draw_bot_side);
83 //extern DO_DRAW(draw_arg);
84 extern DO_DRAW(draw_box);
85 extern DO_DRAW(draw_buffer);
86 extern DO_DRAW(draw_corner);
87 extern DO_DRAW(draw_horizontal_line);
88 extern DO_DRAW(draw_left_side);
89 extern DO_DRAW(draw_line);
90 extern DO_DRAW(draw_map);
91 extern DO_DRAW(draw_right_side);
92 extern DO_DRAW(draw_side);
93 extern DO_DRAW(draw_square);
94 extern DO_DRAW(draw_rain);
95 extern DO_DRAW(draw_hbar);
96 extern DO_DRAW(draw_table_grid);
97 extern DO_DRAW(draw_text);
98 extern DO_DRAW(draw_top_side);
99 extern DO_DRAW(draw_vertical_lines);
100
101 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);
102
103 struct draw_type
104 {
105 char * name;
106 char * desc;
107 int flags;
108 DRAW * fun;
109 };
110
111 struct draw_type draw_table[] =
112 {
113 { "BAR", "Draw a bar.", DRAW_FLAG_NONE, draw_hbar },
114 { "BOX", "Draw four sides of a box.", DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT, draw_box },
115 { "BUFFER", "Draw the scrollback buffer.", DRAW_FLAG_NONE, draw_buffer },
116 { "CORNER", "Draw a corner", DRAW_FLAG_CORNERED, draw_corner },
117 { "LINE", "Draw a line.", DRAW_FLAG_NONE, draw_line },
118 { "MAP", "Draw the map.", DRAW_FLAG_NONE, draw_map },
119 { "RAIN", "Draw digital rain.", DRAW_FLAG_NONE, draw_rain },
120 { "SIDE", "Draw a line with corners.", DRAW_FLAG_CORNERED, draw_side },
121 { "TABLE", "Draw a table.", DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT, draw_table_grid },
122 { "TILE", "Draw a tile.", DRAW_FLAG_NONE, draw_square },
123 { "", "", DRAW_FLAG_NONE, NULL }
124 };
125
126
127 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);
128
DO_COMMAND(do_draw)129 DO_COMMAND(do_draw)
130 {
131 char *box_color, *txt_color, *code1, *code2, *input;
132 long long flags;
133 int index, top_row, top_col, bot_row, bot_col, rows, cols;
134
135 input = str_alloc_stack(0);
136
137 substitute(ses, arg, input, SUB_VAR|SUB_FUN);
138
139 arg = input;
140
141 draw_cnt = 0;
142
143 if (*arg == 0)
144 {
145 tintin_header(ses, 80, " DRAW OPTIONS ");
146
147 for (index = 0 ; *draw_table[index].fun ; index++)
148 {
149 if (*draw_table[index].name)
150 {
151 tintin_printf2(ses, " [%-24s] %s", draw_table[index].name, draw_table[index].desc);
152 }
153 }
154 tintin_header(ses, 80, "");
155
156 return ses;
157 }
158
159 box_color = str_alloc_stack(0);
160 txt_color = str_alloc_stack(0);
161
162 code1 = str_alloc_stack(0);
163 code2 = str_alloc_stack(0);
164
165 flags = HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) ? DRAW_FLAG_UTF8 : 0;
166
167 while (*arg)
168 {
169 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
170
171 if (!HAS_BIT(flags, DRAW_FLAG_COLOR1) && translate_color_names(ses, arg1, code1))
172 {
173 get_color_names(ses, arg1, box_color);
174
175 SET_BIT(flags, DRAW_FLAG_COLOR1);
176
177 continue;
178 }
179
180 if (!HAS_BIT(flags, DRAW_FLAG_COLOR2) && translate_color_names(ses, arg1, code2))
181 {
182 get_color_names(ses, arg1, txt_color);
183
184 SET_BIT(flags, DRAW_FLAG_COLOR2);
185
186 continue;
187 }
188
189 switch (*arg1 % 32)
190 {
191 case CTRL_A:
192 if (is_abbrev(arg1, "ASCII"))
193 {
194 DEL_BIT(flags, DRAW_FLAG_UTF8);
195 }
196 else
197 {
198 goto option;
199 }
200 continue;
201 case CTRL_B:
202 if (is_abbrev(arg1, "BALIGN"))
203 {
204 SET_BIT(flags, DRAW_FLAG_BALIGN);
205 }
206 else if (is_abbrev(arg1, "BLANKED"))
207 {
208 SET_BIT(flags, DRAW_FLAG_BLANKED);
209 }
210 else if (is_abbrev(arg1, "BOTTOM"))
211 {
212 SET_BIT(flags, DRAW_FLAG_BOT);
213 }
214 else if (!strcasecmp(arg1, "BOXED"))
215 {
216 SET_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT);
217 }
218 else if (is_abbrev(arg1, "BUMPED"))
219 {
220 SET_BIT(flags, DRAW_FLAG_BUMP);
221 }
222 else
223 {
224 goto option;
225 }
226 continue;
227 case CTRL_C:
228 if (is_abbrev(arg1, "CALIGN"))
229 {
230 SET_BIT(flags, DRAW_FLAG_CALIGN);
231 }
232 else if (is_abbrev(arg1, "CIRCLED"))
233 {
234 SET_BIT(flags, DRAW_FLAG_CIRCLED);
235 }
236 else if (is_abbrev(arg1, "CONVERT"))
237 {
238 SET_BIT(flags, DRAW_FLAG_CONVERT);
239 }
240 else if (is_abbrev(arg1, "CROSSED"))
241 {
242 SET_BIT(flags, DRAW_FLAG_CROSSED);
243 }
244 else if (is_abbrev(arg1, "CURSIVE"))
245 {
246 SET_BIT(flags, DRAW_FLAG_CURSIVE);
247 }
248 else
249 {
250 goto option;
251 }
252 continue;
253 case CTRL_F:
254 if (is_abbrev(arg1, "FAT"))
255 {
256 SET_BIT(flags, DRAW_FLAG_FAT);
257 }
258 else if (is_abbrev(arg1, "FILLED"))
259 {
260 SET_BIT(flags, DRAW_FLAG_FILLED);
261 }
262 else if (is_abbrev(arg1, "FOREGROUND"))
263 {
264 SET_BIT(flags, DRAW_FLAG_FOREGROUND);
265 }
266 else
267 {
268 goto option;
269 }
270 continue;
271 case CTRL_G:
272 if (is_abbrev(arg1, "GRID"))
273 {
274 SET_BIT(flags, DRAW_FLAG_GRID);
275 }
276 else
277 {
278 goto option;
279 }
280 continue;
281 case CTRL_H:
282 if (is_abbrev(arg1, "HORIZONTAL"))
283 {
284 SET_BIT(flags, DRAW_FLAG_HOR);
285 }
286 else if (is_abbrev(arg1, "HUGE"))
287 {
288 SET_BIT(flags, DRAW_FLAG_HUGE);
289 }
290 else
291 {
292 goto option;
293 }
294 continue;
295 case CTRL_J:
296 if (is_abbrev(arg1, "JEWELED"))
297 {
298 SET_BIT(flags, DRAW_FLAG_JEWELED);
299 }
300 else if (is_abbrev(arg1, "JOINTED"))
301 {
302 SET_BIT(flags, DRAW_FLAG_CORNERED);
303 }
304 else
305 {
306 goto option;
307 }
308 continue;
309 case CTRL_L:
310 if (is_abbrev(arg1, "LALIGN"))
311 {
312 SET_BIT(flags, DRAW_FLAG_LALIGN);
313 }
314 else if (is_abbrev(arg1, "LEFT"))
315 {
316 SET_BIT(flags, DRAW_FLAG_LEFT);
317 }
318 else
319 {
320 goto option;
321 }
322 continue;
323
324 case CTRL_N:
325 if (is_abbrev(arg1, "NUMBERED"))
326 {
327 SET_BIT(flags, DRAW_FLAG_NUMBERED);
328 }
329 else
330 {
331 goto option;
332 }
333 continue;
334 case CTRL_P:
335 if (is_abbrev(arg1, "PRUNED"))
336 {
337 SET_BIT(flags, DRAW_FLAG_PRUNED);
338 }
339 else
340 {
341 goto option;
342 }
343 continue;
344 case CTRL_R:
345 if (is_abbrev(arg1, "RALIGN"))
346 {
347 SET_BIT(flags, DRAW_FLAG_RALIGN);
348 }
349 else if (is_abbrev(arg1, "RIGHT"))
350 {
351 SET_BIT(flags, DRAW_FLAG_RIGHT);
352 }
353 else if (is_abbrev(arg1, "ROUNDED"))
354 {
355 SET_BIT(flags, DRAW_FLAG_ROUNDED);
356 }
357 else
358 {
359 goto option;
360 }
361 continue;
362 case CTRL_S:
363 if (is_abbrev(arg1, "SANSSERIF"))
364 {
365 SET_BIT(flags, DRAW_FLAG_SANSSERIF);
366 }
367 else if (is_abbrev(arg1, "SCALED"))
368 {
369 SET_BIT(flags, DRAW_FLAG_SCALED);
370 }
371 else if (is_abbrev(arg1, "SCROLL"))
372 {
373 SET_BIT(flags, DRAW_FLAG_SCROLL);
374 }
375 else if (is_abbrev(arg1, "SHADOWED"))
376 {
377 SET_BIT(flags, DRAW_FLAG_SHADOWED);
378 }
379 else
380 {
381 goto option;
382 }
383 continue;
384 case CTRL_T:
385 if (is_abbrev(arg1, "TALIGN"))
386 {
387 SET_BIT(flags, DRAW_FLAG_TALIGN);
388 }
389 else if (is_abbrev(arg1, "TEED"))
390 {
391 SET_BIT(flags, DRAW_FLAG_TEED);
392 }
393 else if (is_abbrev(arg1, "TOP"))
394 {
395 SET_BIT(flags, DRAW_FLAG_TOP);
396 }
397 else if (is_abbrev(arg1, "TRACED"))
398 {
399 SET_BIT(flags, DRAW_FLAG_TRACED);
400 }
401 else if (is_abbrev(arg1, "TUBED"))
402 {
403 SET_BIT(flags, DRAW_FLAG_TUBED);
404 }
405 else
406 {
407 goto option;
408 }
409 continue;
410 case CTRL_U:
411 if (is_abbrev(arg1, "UALIGN"))
412 {
413 SET_BIT(flags, DRAW_FLAG_UALIGN);
414 }
415 else if (is_abbrev(arg1, "UNICODE"))
416 {
417 SET_BIT(flags, DRAW_FLAG_UTF8);
418 }
419 else
420 {
421 goto option;
422 }
423 continue;
424 case CTRL_V:
425 if (is_abbrev(arg1, "VERTICAL"))
426 {
427 SET_BIT(flags, DRAW_FLAG_VER);
428 }
429 else
430 {
431 break;
432 }
433 continue;
434
435 default:
436 goto option;
437 continue;
438 }
439 }
440
441 option:
442
443 for (index = 0 ; *draw_table[index].name ; index++)
444 {
445 if (is_abbrev(arg1, draw_table[index].name))
446 {
447 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
448 arg = get_arg_in_braces(ses, arg, arg2, GET_ONE);
449 // arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
450 // arg = sub_arg_in_braces(ses, arg, arg2, GET_ONE, SUB_VAR|SUB_FUN);
451
452 top_row = get_row_index_arg(ses, arg1);
453 top_col = get_col_index_arg(ses, arg2);
454
455 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
456 arg = get_arg_in_braces(ses, arg, arg2, GET_ONE);
457
458 bot_row = get_row_index_arg(ses, arg1);
459 bot_col = get_col_index_arg(ses, arg2);
460
461 if (top_row == 0 && top_col == 0)
462 {
463 show_error(ses, LIST_COMMAND, "#SYNTAX: #DRAW [COLOR] [OPTIONS] {%s} <TOP_ROW> <TOP_COL> <BOT_ROW> <BOT_COL> [TEXT]", draw_table[index].name);
464
465 return ses;
466 }
467
468 if (top_row == 0)
469 {
470 top_row = 1;
471
472 SET_BIT(flags, DRAW_FLAG_SCROLL);
473 }
474 else
475 {
476 if (!HAS_BIT(flags, DRAW_FLAG_SCROLL) && !HAS_BIT(flags, DRAW_FLAG_FOREGROUND) && ses != gtd->ses)
477 {
478 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);
479
480 return ses;
481 }
482 }
483
484 if (top_col == 0)
485 {
486 top_col = 1;
487 }
488
489 if (bot_row == 0)
490 {
491 bot_row = 1;
492 }
493
494 if (bot_col == 0)
495 {
496 bot_col = 1;
497 }
498
499 if (top_row > bot_row || top_col > bot_col)
500 {
501 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);
502
503 return ses;
504 }
505
506 rows = URANGE(1, 1 + bot_row - top_row, gtd->screen->rows);
507 cols = URANGE(1, 1 + bot_col - top_col, gtd->screen->cols);
508
509 if (HAS_BIT(flags, DRAW_FLAG_SCALED))
510 {
511 scale_drawing(ses, &top_row, &top_col, &bot_row, &bot_col, &rows, &cols, index, draw_table[index].flags | flags, arg);
512 }
513
514 *arg1 = 0;
515 *arg2 = 0;
516 *arg3 = 0;
517 // *arg4 = 0;
518
519 // forgot why I did this originally
520 /*
521 if (*arg == 0)
522 {
523 arg = arg4;
524 }
525 */
526 save_pos(ses);
527
528 if (HAS_BIT(flags, DRAW_FLAG_BUMP))
529 {
530 tintin_printf2(ses, "");
531 }
532
533 str_cpy(&arg2, code1);
534 str_cpy(&arg3, code2);
535
536 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);
537
538 print_stdout(0, 0, "\e[0m");
539
540 restore_pos(ses);
541
542 return ses;
543 }
544 }
545 show_error(ses, LIST_COMMAND, "#ERROR: #DRAW {%s} IS NOT A VALID OPTION.", capitalize(arg1));
546
547 return ses;
548 }
549
550 // utilities
551
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)552 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)
553 {
554 char *buf, *out, *tmp;
555 int inside;
556 int height, bor_height, tot_height, max_height;
557 int width, bor_width, tot_width, max_width;
558
559 if (*arg == 0)
560 {
561 return;
562 }
563
564 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);
565
566 buf = str_alloc_stack(0);
567 out = str_alloc_stack(0);
568 tmp = str_alloc_stack(0);
569
570 height = bor_height = tot_height = max_height = 0;
571 width = bor_width = tot_width = max_width = 0;
572
573 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
574 {
575 inside = TRUE;
576 }
577 else
578 {
579 inside = inside_scroll_region(ses, *top_row, *top_col);
580 }
581
582 if (inside)
583 {
584 max_height = 0 + ses->split->bot_row - ses->split->top_row;
585 max_width = 1 + ses->split->bot_col - ses->split->top_col;
586 }
587 else
588 {
589 max_height = gtd->screen->rows;
590 max_width = gtd->screen->cols;
591 }
592
593 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
594 {
595 max_height = gtd->screen->rows * 10;
596 }
597
598 bor_height += HAS_BIT(flags, DRAW_FLAG_TOP) ? 1 : 0;
599 bor_height += HAS_BIT(flags, DRAW_FLAG_BOT) ? 1 : 0;
600
601 bor_width += HAS_BIT(flags, DRAW_FLAG_LEFT) ? 1 : 0;
602 bor_width += HAS_BIT(flags, DRAW_FLAG_RIGHT) ? 1 : 0;
603
604 if (HAS_BIT(flags, DRAW_FLAG_UALIGN))
605 {
606 ualign(ses, arg, tmp, max_width - bor_width);
607
608 arg = tmp;
609 }
610
611 while (*arg)
612 {
613 arg = sub_arg_in_braces(ses, arg, buf, GET_ALL, SUB_VAR|SUB_FUN|SUB_COL|SUB_LIT|SUB_ESC);
614
615 word_wrap_split(ses, buf, out, max_width - bor_width, 0, 0, WRAP_FLAG_NONE, &height, &width);
616
617 tot_width = UMAX(tot_width, width);
618 tot_height += height;
619
620 if (*arg == COMMAND_SEPARATOR)
621 {
622 arg++;
623 }
624 }
625
626 tot_height += bor_height;
627 tot_width += bor_width;
628
629 if (tot_height > max_height)
630 {
631 tot_height = max_height;
632 }
633
634 if (tot_height > *rows)
635 {
636 *bot_row = get_row_index(ses, *top_row + tot_height - 1);
637
638 if (inside)
639 {
640 if (*bot_row > ses->split->bot_row - 1)
641 {
642 *bot_row = ses->split->bot_row - 1;
643 }
644 }
645 *rows = URANGE(1, 1 + *bot_row - *top_row, gtd->screen->rows);
646 }
647
648 while (tot_height > *rows)
649 {
650 (*top_row)--;
651
652 *rows = 1 + *bot_row - *top_row;
653 }
654 // tintin_printf2(ses, "debug4: rows %d top_row: %d bot_row %d", *rows, *top_row, *bot_row);
655
656 if (tot_width > max_width)
657 {
658 tot_width = max_width;
659 }
660
661 if (tot_width > *cols)
662 {
663 *bot_col = get_col_index(ses, *top_col + tot_width - 1);
664
665 if (inside)
666 {
667 if (*bot_col > ses->split->bot_col)
668 {
669 *bot_col = ses->split->bot_col;
670 }
671 }
672 *cols = URANGE(1, 1 + *bot_col - *top_col, gtd->screen->cols);
673 }
674
675 while (tot_width > *cols)
676 {
677 (*top_col)--;
678
679 *cols = 1 + *bot_col - *top_col;
680 }
681 // tintin_printf2(ses, "debug4: cols %d top_col: %d bot_col %d", *cols, *top_col, *bot_col);
682
683 pop_call();
684 return;
685 }
686
687 char *alnum_normal[] =
688 {
689 "\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",
690 " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
691 "@", "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", "[", "\\", "]", "^", "_",
692 "`", "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"
693 };
694
695 char *alnum_normal_fat[] =
696 {
697 "\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",
698 " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "", "", "", "", "", "", "", "", "", "", ":", ";", "<", "=", ">", "?",
699 "@", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Z", "", "\\", "]", "^", "_",
700 "`", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "{", "|", "}", "~", "\x7F"
701 };
702
703 char *alnum_cursive[] =
704 {
705 "\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",
706 " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
707 "@", "", "ℬ", "", "", "ℰ", "ℱ", "", "ℋ", "ℐ", "", "", "ℒ", "ℳ", "", "", "", "", "ℛ", "", "", "", "", "", "", "", "", "[", "\\", "]", "^", "_",
708 "`", "", "", "", "", "ℯ", "", "ℊ", "", "", "", "", "", "", "", "ℴ", "", "", "", "", "", "", "", "", "", "", "", "{", "|", "}", "~", "\x7F"
709 };
710
711 char *alnum_sansserif[] =
712 {
713 "\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",
714 " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "", "", "", "", "", "", "", "", "", "", ":", ";", "<", "=", ">", "?",
715 "@", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "[", "\\", "]", "^", "_",
716 "`", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "{", "|", "}", "~", "\x7F"
717 };
718
string_to_font(struct session * ses,long long flags,char * in,char * out)719 void string_to_font(struct session *ses, long long flags, char *in, char *out)
720 {
721 char buf[BUFFER_SIZE];
722 char *pti, *pto;
723 int skip;
724
725 push_call("string_to_font(%p,%d,%p,%p)",ses,flags,in,out);
726
727 // DRAW_FLAG_FAT, DRAW_FLAG_ITALIC, DRAW_FLAG_SERIF, DRAW_FLAG_CURSIVE, DRAW_FLAG_GOTHIC, DRAW_FLAG_TRACED, DRAW_FLAG_MONO
728
729 strcpy(buf, in);
730
731 pti = buf;
732 pto = out;
733
734 while (*pti)
735 {
736 skip = skip_vt102_codes(pti);
737
738 if (skip)
739 {
740 pto += sprintf(pto, "%.*s", skip, pti);
741
742 pti += skip;
743
744 continue;
745 }
746
747 if (*pti >= 32)
748 {
749 switch (HAS_BIT(flags, DRAW_FLAG_FAT|DRAW_FLAG_CURSIVE|DRAW_FLAG_SANSSERIF))
750 {
751 case DRAW_FLAG_CURSIVE:
752 pto += sprintf(pto, "%s", alnum_cursive[(int) *pti]);
753 break;
754
755 case DRAW_FLAG_FAT:
756 pto += sprintf(pto, "%s", alnum_normal_fat[(int) *pti]);
757 break;
758
759 case DRAW_FLAG_SANSSERIF:
760 pto += sprintf(pto, "%s", alnum_sansserif[(int) *pti]);
761 break;
762
763 default:
764 *pto++ = *pti;
765 break;
766 }
767 pti++;
768 }
769 else
770 {
771 *pto++ = *pti++;
772 }
773 }
774 *pto++ = 0;
775
776 pop_call();
777 return;
778 }
779
find_stamp(char * in,char * out)780 int find_stamp(char *in, char *out)
781 {
782 int cnt;
783
784 for (cnt = 0 ; huge_stamp_table[cnt].name != NULL ; cnt++)
785 {
786 if (!strcmp(in, huge_stamp_table[cnt].name))
787 {
788 strcpy(out, huge_stamp_table[cnt].desc);
789
790 return huge_stamp_table[cnt].length;
791 }
792 }
793 tintin_printf2(gtd->ses, "debug: didn't find stamp {%s}", in);
794
795 return 0;
796 }
797
stamp_cat(char * color,long long flags,char * str,char * cat,char * out)798 void stamp_cat(char *color, long long flags, char *str, char *cat, char *out)
799 {
800 char *pts = str;
801 char *ptc = cat;
802 char *pto = out;
803
804 while (*pts || *ptc)
805 {
806 while (*pts && *pts != '\n')
807 {
808 *pto++ = *pts++;
809 }
810
811 pto += sprintf(pto, "%s", color);
812
813 while (*ptc && *ptc != '\n')
814 {
815 if (HAS_BIT(flags, DRAW_FLAG_SHADOWED))
816 {
817 *pto++ = *ptc++;
818 }
819 else if (HAS_BIT(flags, DRAW_FLAG_TRACED))
820 {
821 if (!strncmp(ptc, "╗", 3))
822 {
823 pto += sprintf(pto, "┐");
824 ptc += strlen("╗");
825 }
826 else if (!strncmp(ptc, "║", 3))
827 {
828 pto += sprintf(pto, "│");
829 ptc += strlen("║");
830 }
831 else if (!strncmp(ptc, "╝", 3))
832 {
833 pto += sprintf(pto, "┘");
834 ptc += strlen("╝");
835 }
836 else if (!strncmp(ptc, "╚", 3))
837 {
838 pto += sprintf(pto, "└");
839 ptc += strlen("╚");
840 }
841 else if (!strncmp(ptc, "╔", 3))
842 {
843 pto += sprintf(pto, "┌");
844 ptc += strlen("╔");
845 }
846 else if (!strncmp(ptc, "═", 3))
847 {
848 pto += sprintf(pto, "─");
849 ptc += strlen("═");
850 }
851 else
852 {
853 *pto++ = *ptc++;
854 }
855 }
856 else
857 {
858 if (!strncmp(ptc, "╗", 3))
859 {
860 pto += sprintf(pto, " ");
861 ptc += strlen("╗");
862 }
863 else if (!strncmp(ptc, "║", 3))
864 {
865 pto += sprintf(pto, " ");
866 ptc += strlen("║");
867 }
868 else if (!strncmp(ptc, "╝", 3))
869 {
870 pto += sprintf(pto, " ");
871 ptc += strlen("╝");
872 }
873 else if (!strncmp(ptc, "╚", 3))
874 {
875 pto += sprintf(pto, " ");
876 ptc += strlen("╚");
877 }
878 else if (!strncmp(ptc, "╔", 3))
879 {
880 pto += sprintf(pto, " ");
881 ptc += strlen("╔");
882 }
883 else if (!strncmp(ptc, "═", 3))
884 {
885 pto += sprintf(pto, " ");
886 ptc += strlen("═");
887 }
888 else
889 {
890 *pto++ = *ptc++;
891 }
892 }
893 }
894
895 if (*pts == '\n' && *ptc == '\n')
896 {
897 *pto++ = *pts++;
898 ptc++;
899 }
900 else if (*ptc == '\n')
901 {
902 *pto++ = *ptc++;
903 }
904 }
905 *pto = 0;
906 }
907
string_to_stamp(struct session * ses,long long flags,char * in,char * out)908 void string_to_stamp(struct session *ses, long long flags, char *in, char *out)
909 {
910 char *pti, *buf1, *buf2, *buf3, chr1[CHAR_SIZE], color[COLOR_SIZE] = { 0 };
911 int skip;
912
913 push_call("string_to_stamp(%p,%d,%p,%p)",ses,flags,in,out);
914
915 buf1 = str_alloc_stack(0);
916 buf2 = str_alloc_stack(0);
917 buf3 = str_alloc_stack(0);
918
919 sub_arg_in_braces(ses, in, buf1, GET_ALL, SUB_COL|SUB_LIT|SUB_ESC);
920
921 pti = buf1;
922
923 buf3[0] = 0;
924
925 while (*pti)
926 {
927 skip = skip_vt102_codes(pti);
928
929 if (skip)
930 {
931 get_color_codes(color, pti, color, GET_ONE);
932
933 pti += skip;
934
935 continue;
936 }
937 pti = get_char(ses, pti, chr1);
938
939 find_stamp(chr1, buf2);
940
941 stamp_cat(color, flags, buf3, buf2, out);
942
943 strcpy(buf3, out);
944 }
945 strcat(out, "\n");
946
947 pop_call();
948 return;
949 }
950
get_draw_corner(long long flags,char * str)951 char *get_draw_corner(long long flags, char *str)
952 {
953 draw_cnt = (draw_cnt + 1) % 100;
954
955 if (HAS_BIT(flags, DRAW_FLAG_BLANKED))
956 {
957 strcpy(draw_buf[draw_cnt], " ");
958 }
959 else if (HAS_BIT(flags, DRAW_FLAG_NUMBERED))
960 {
961 sprintf(draw_buf[draw_cnt], "%d", draw_cnt % 10);
962 }
963 else if (HAS_BIT(flags, DRAW_FLAG_UTF8))
964 {
965 if (HAS_BIT(flags, DRAW_FLAG_PRUNED))
966 {
967 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
968 {
969 strcpy(draw_buf[draw_cnt], " ");
970 }
971 else
972 {
973 strcpy(draw_buf[draw_cnt], "\e[C");
974 }
975 }
976 else if (HAS_BIT(flags, DRAW_FLAG_CIRCLED))
977 {
978 if (HAS_BIT(flags, DRAW_FLAG_CROSSED))
979 {
980 strcpy(draw_buf[draw_cnt], "ϴ");
981 }
982 else if (HAS_BIT(flags, DRAW_FLAG_FILLED))
983 {
984 strcpy(draw_buf[draw_cnt], "⬤");
985 }
986 else if (HAS_BIT(flags, DRAW_FLAG_VER))
987 {
988 strcpy(draw_buf[draw_cnt], "O");
989 }
990 else
991 {
992 strcpy(draw_buf[draw_cnt], "○");
993 }
994 }
995 else if (HAS_BIT(flags, DRAW_FLAG_CROSSED))
996 {
997 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
998 {
999 strcpy(draw_buf[draw_cnt], "╬");
1000 }
1001 else
1002 {
1003 strcpy(draw_buf[draw_cnt], "┼");
1004 }
1005 }
1006 else if (HAS_BIT(flags, DRAW_FLAG_JEWELED))
1007 {
1008 if (HAS_BIT(flags, DRAW_FLAG_FILLED))
1009 {
1010 strcpy(draw_buf[draw_cnt], "⧫");
1011 }
1012 else
1013 {
1014 strcpy(draw_buf[draw_cnt], "◊");
1015 }
1016 }
1017 else if (HAS_BIT(flags, DRAW_FLAG_TEED))
1018 {
1019 if (HAS_BIT(flags, DRAW_FLAG_HOR))
1020 {
1021 if (HAS_BIT(flags, DRAW_FLAG_LEFT))
1022 {
1023 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1024 {
1025 strcpy(draw_buf[draw_cnt], "╠");
1026 }
1027 else
1028 {
1029 strcpy(draw_buf[draw_cnt], "├");
1030 }
1031 }
1032 else
1033 {
1034 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1035 {
1036 strcpy(draw_buf[draw_cnt], "╣");
1037 }
1038 else
1039 {
1040 strcpy(draw_buf[draw_cnt], "┤");
1041 }
1042 }
1043 }
1044 else
1045 {
1046 if (HAS_BIT(flags, DRAW_FLAG_TOP))
1047 {
1048 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1049 {
1050 strcpy(draw_buf[draw_cnt], "╦");
1051 }
1052 else
1053 {
1054 strcpy(draw_buf[draw_cnt], "┬");
1055 }
1056 }
1057 else
1058 {
1059 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1060 {
1061 strcpy(draw_buf[draw_cnt], "╩");
1062 }
1063 else
1064 {
1065 strcpy(draw_buf[draw_cnt], "┴");
1066 }
1067 }
1068 }
1069 }
1070 else if (HAS_BIT(flags, DRAW_FLAG_BOXED) || HAS_BIT(flags, DRAW_FLAG_CORNERED))
1071 {
1072 if (HAS_BIT(flags, DRAW_FLAG_LEFT))
1073 {
1074 if (HAS_BIT(flags, DRAW_FLAG_TOP))
1075 {
1076 if (HAS_BIT(flags, DRAW_FLAG_ROUNDED))
1077 {
1078 strcpy(draw_buf[draw_cnt], "╭");
1079 }
1080 else
1081 {
1082 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1083 {
1084 strcpy(draw_buf[draw_cnt], "╔");
1085 }
1086 else
1087 {
1088 strcpy(draw_buf[draw_cnt], "┌");
1089 }
1090 }
1091 }
1092 else if (HAS_BIT(flags, DRAW_FLAG_BOT))
1093 {
1094 if (HAS_BIT(flags, DRAW_FLAG_ROUNDED))
1095 {
1096 strcpy(draw_buf[draw_cnt], "╰");
1097 }
1098 else
1099 {
1100 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1101 {
1102 strcpy(draw_buf[draw_cnt], "╚");
1103 }
1104 else
1105 {
1106 strcpy(draw_buf[draw_cnt], "└");
1107 }
1108 }
1109 }
1110 else
1111 {
1112 if (HAS_BIT(flags, DRAW_FLAG_HOR))
1113 {
1114 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1115 {
1116 strcpy(draw_buf[draw_cnt], "═");
1117 }
1118 else
1119 {
1120 strcpy(draw_buf[draw_cnt], "─");
1121 }
1122 }
1123 else
1124 {
1125 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1126 {
1127 strcpy(draw_buf[draw_cnt], "║");
1128 }
1129 else
1130 {
1131 strcpy(draw_buf[draw_cnt], "│");
1132 }
1133 }
1134 }
1135 }
1136 else if (HAS_BIT(flags, DRAW_FLAG_RIGHT))
1137 {
1138 if (HAS_BIT(flags, DRAW_FLAG_TOP))
1139 {
1140 if (HAS_BIT(flags, DRAW_FLAG_ROUNDED))
1141 {
1142 strcpy(draw_buf[draw_cnt], "╮");
1143 }
1144 else
1145 {
1146 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1147 {
1148 strcpy(draw_buf[draw_cnt], "╗");
1149 }
1150 else
1151 {
1152 strcpy(draw_buf[draw_cnt], "┐");
1153 }
1154 }
1155 }
1156 else if (HAS_BIT(flags, DRAW_FLAG_BOT))
1157 {
1158 if (HAS_BIT(flags, DRAW_FLAG_ROUNDED))
1159 {
1160 strcpy(draw_buf[draw_cnt], "╯");
1161 }
1162 else
1163 {
1164 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1165 {
1166 strcpy(draw_buf[draw_cnt], "╝");
1167 }
1168 else
1169 {
1170 strcpy(draw_buf[draw_cnt], "┘");
1171 }
1172 }
1173 }
1174 else
1175 {
1176 if (HAS_BIT(flags, DRAW_FLAG_HOR))
1177 {
1178 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1179 {
1180 strcpy(draw_buf[draw_cnt], "═");
1181 }
1182 else
1183 {
1184 strcpy(draw_buf[draw_cnt], "─");
1185 }
1186 }
1187 else
1188 {
1189 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1190 {
1191 strcpy(draw_buf[draw_cnt], "║");
1192 }
1193 else
1194 {
1195 strcpy(draw_buf[draw_cnt], "│");
1196 }
1197 }
1198 }
1199 }
1200 else
1201 {
1202 if (HAS_BIT(flags, DRAW_FLAG_HOR))
1203 {
1204 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1205 {
1206 strcpy(draw_buf[draw_cnt], "═");
1207 }
1208 else
1209 {
1210 strcpy(draw_buf[draw_cnt], "─");
1211 }
1212 }
1213 else
1214 {
1215 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1216 {
1217 strcpy(draw_buf[draw_cnt], "║");
1218 }
1219 else
1220 {
1221 strcpy(draw_buf[draw_cnt], "│");
1222 }
1223 }
1224 }
1225 }
1226 else
1227 {
1228 if (HAS_BIT(flags, DRAW_FLAG_HOR))
1229 {
1230 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1231 {
1232 strcpy(draw_buf[draw_cnt], "═");
1233 }
1234 else
1235 {
1236 strcpy(draw_buf[draw_cnt], "─");
1237 }
1238 }
1239 else if (HAS_BIT(flags, DRAW_FLAG_VER))
1240 {
1241 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1242 {
1243 strcpy(draw_buf[draw_cnt], "║");
1244 }
1245 else
1246 {
1247 strcpy(draw_buf[draw_cnt], "│");
1248 }
1249 }
1250 else
1251 {
1252 strcpy(draw_buf[draw_cnt], "?");
1253 }
1254 }
1255 }
1256 else
1257 {
1258 if (HAS_BIT(flags, DRAW_FLAG_PRUNED))
1259 {
1260 strcpy(draw_buf[draw_cnt], "\e[C");
1261 }
1262 else if (HAS_BIT(flags, DRAW_FLAG_CIRCLED) || HAS_BIT(flags, DRAW_FLAG_ROUNDED))
1263 {
1264 strcpy(draw_buf[draw_cnt], "o");
1265 }
1266 else if (HAS_BIT(flags, DRAW_FLAG_CROSSED))
1267 {
1268 strcpy(draw_buf[draw_cnt], "+");
1269 }
1270 else
1271 {
1272 strcpy(draw_buf[draw_cnt], "+");
1273 }
1274 }
1275 return draw_buf[draw_cnt];
1276 }
1277
draw_horizontal(long long flags,char * str)1278 char *draw_horizontal(long long flags, char *str)
1279 {
1280 draw_cnt = (draw_cnt + 1) % 100;
1281
1282 if (HAS_BIT(flags, DRAW_FLAG_BLANKED))
1283 {
1284 strcpy(draw_buf[draw_cnt], " ");
1285 }
1286 else if (HAS_BIT(flags, DRAW_FLAG_NUMBERED))
1287 {
1288 sprintf(draw_buf[draw_cnt], "%d", draw_cnt % 10);
1289 }
1290 else if (HAS_BIT(flags, DRAW_FLAG_UTF8))
1291 {
1292 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1293 {
1294 strcpy(draw_buf[draw_cnt], "═");
1295 }
1296 else
1297 {
1298 strcpy(draw_buf[draw_cnt], "─");
1299 }
1300 }
1301 else
1302 {
1303 strcpy(draw_buf[draw_cnt], "-");
1304 }
1305 return draw_buf[draw_cnt];
1306 }
1307
draw_vertical(long long flags,char * str)1308 char *draw_vertical(long long flags, char *str)
1309 {
1310 draw_cnt = (draw_cnt + 1) % 100;
1311
1312 if (HAS_BIT(flags, DRAW_FLAG_BLANKED))
1313 {
1314 strcpy(draw_buf[draw_cnt], " ");
1315 }
1316 else if (HAS_BIT(flags, DRAW_FLAG_NUMBERED))
1317 {
1318 sprintf(draw_buf[draw_cnt], "%d", draw_cnt % 10);
1319 }
1320 else if (HAS_BIT(flags, DRAW_FLAG_UTF8))
1321 {
1322 if (HAS_BIT(flags, DRAW_FLAG_TUBED))
1323 {
1324 strcpy(draw_buf[draw_cnt], "║");
1325 }
1326 else
1327 {
1328 strcpy(draw_buf[draw_cnt], "│");
1329 }
1330 }
1331 else
1332 {
1333 strcpy(draw_buf[draw_cnt], "|");
1334 }
1335 return draw_buf[draw_cnt];
1336 }
1337
1338 // options
1339
DO_DRAW(draw_bot_side)1340 DO_DRAW(draw_bot_side)
1341 {
1342 int col, corner;
1343
1344 if (!HAS_BIT(flags, DRAW_FLAG_LEFT) && !HAS_BIT(flags, DRAW_FLAG_RIGHT) && !HAS_BIT(flags, DRAW_FLAG_BOT))
1345 {
1346 return;
1347 }
1348
1349 SET_BIT(flags, HAS_BIT(flags, DRAW_FLAG_VER) ? DRAW_FLAG_VER : DRAW_FLAG_HOR);
1350
1351 corner = flags;
1352
1353 DEL_BIT(corner, DRAW_FLAG_RIGHT|DRAW_FLAG_TOP);
1354
1355 arg = arg1;
1356
1357 if (HAS_BIT(flags, DRAW_FLAG_LEFT) || HAS_BIT(flags, DRAW_FLAG_BOT))
1358 {
1359 SET_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_BOT);
1360
1361 arg1 += sprintf(arg1, "%s%s", box_color, get_draw_corner(corner, "└"));
1362 }
1363
1364 if (cols - 2 >= 0)
1365 {
1366 if (HAS_BIT(flags, DRAW_FLAG_BOT))
1367 {
1368 for (col = top_col + 1 ; col < bot_col ; col++)
1369 {
1370 arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "─"));
1371 }
1372 }
1373 else if (HAS_BIT(flags, DRAW_FLAG_RIGHT) && cols - 2 > 0)
1374 {
1375 arg1 += sprintf(arg1, "\e[%dC", cols - 2);
1376 }
1377
1378 corner = flags;
1379
1380 DEL_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_TOP);
1381
1382 if (HAS_BIT(flags, DRAW_FLAG_RIGHT) || HAS_BIT(flags, DRAW_FLAG_BOT))
1383 {
1384 arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "┘"));
1385 }
1386 }
1387
1388 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
1389 {
1390
1391 tintin_printf2(ses, "%s%s", indent_one(top_col - 1), arg);
1392 }
1393 else
1394 {
1395 goto_pos(ses, bot_row, top_col);
1396
1397 print_stdout(bot_row, top_col, "%s", arg);
1398 }
1399 }
1400
1401 /*
1402 DO_DRAW(draw_arg)
1403 {
1404 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
1405 top_row = get_row_index_arg(ses, arg1);
1406
1407 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
1408 top_col = get_col_index_arg(ses, arg1);
1409
1410 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
1411 bot_row = get_row_index_arg(ses, arg1);
1412
1413 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
1414 bot_col = get_col_index_arg(ses, arg1);
1415
1416 rows = URANGE(1, 1 + bot_row - top_row, gtd->screen->rows);
1417 cols = URANGE(1, 1 + bot_col - top_col, gtd->screen->cols);
1418
1419 save_pos(ses);
1420
1421 draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, arg2, arg1, arg, arg3);
1422
1423 restore_pos(ses);
1424 }
1425 */
1426
DO_DRAW(draw_box)1427 DO_DRAW(draw_box)
1428 {
1429 if (HAS_BIT(flags, DRAW_FLAG_TOP))
1430 {
1431 draw_top_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
1432 }
1433
1434 draw_vertical_lines(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
1435
1436 if (HAS_BIT(flags, DRAW_FLAG_BOT))
1437 {
1438 draw_bot_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
1439 }
1440 }
1441
DO_DRAW(draw_buffer)1442 DO_DRAW(draw_buffer)
1443 {
1444 char *buf;
1445 int cnt, line;
1446
1447 push_call("draw_buffer(%p,...)",ses);
1448
1449 buf = str_alloc_stack(0);
1450
1451 if (ses->scroll->line == -1)
1452 {
1453 line = ses->scroll->used - 1;
1454 }
1455 else
1456 {
1457 line = ses->scroll->line;
1458 }
1459
1460 for (cnt = rows ; cnt >= 0 && line - cnt >= 0 ; cnt--)
1461 {
1462 str_cat_printf(&buf, "{%s}", ses->scroll->buffer[line - cnt]->str);
1463 }
1464
1465 draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, buf, arg1, arg2, arg3);
1466
1467 pop_call();
1468 return;
1469 }
1470
DO_DRAW(draw_corner)1471 DO_DRAW(draw_corner)
1472 {
1473 if (*arg)
1474 {
1475 strcpy(arg1, arg);
1476 }
1477 else
1478 {
1479 strcpy(arg1, get_draw_corner(flags, " "));
1480 }
1481
1482 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
1483 {
1484 tintin_printf2(ses, "%s%s%s", indent_one(top_col - 1), box_color, arg1);
1485 }
1486 else
1487 {
1488 goto_pos(ses, top_row, top_col);
1489
1490 print_stdout(top_row, top_col, "%s%s", box_color, arg1);
1491 }
1492 }
1493
DO_DRAW(draw_line_horizontal)1494 DO_DRAW(draw_line_horizontal)
1495 {
1496 int col, corner;
1497
1498 if (!HAS_BIT(flags, DRAW_FLAG_VER))
1499 {
1500 SET_BIT(flags, DRAW_FLAG_HOR);
1501 }
1502
1503 if (HAS_BIT(flags, DRAW_FLAG_APPENDIX))
1504 {
1505 if (!HAS_BIT(flags, DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT))
1506 {
1507 SET_BIT(flags, DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT);
1508 }
1509 }
1510
1511 corner = flags;
1512
1513 arg = arg1;
1514
1515 if (HAS_BIT(flags, DRAW_FLAG_LEFT))
1516 {
1517 DEL_BIT(corner, DRAW_FLAG_RIGHT);
1518
1519 arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "┌"));
1520 }
1521 else
1522 {
1523 arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "─"));
1524 }
1525
1526 if (cols - 2 > 0)
1527 {
1528 for (col = top_col + 1 ; col < bot_col ; col++)
1529 {
1530 arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "─"));
1531 }
1532 }
1533
1534 if (HAS_BIT(flags, DRAW_FLAG_RIGHT) && cols - 2 > 0)
1535 {
1536 SET_BIT(corner, DRAW_FLAG_RIGHT);
1537 DEL_BIT(corner, DRAW_FLAG_LEFT);
1538
1539 arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "┐"));
1540 }
1541 else
1542 {
1543 arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "─"));
1544 }
1545
1546 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
1547 {
1548 tintin_printf2(ses, "%*s%s%s", top_col - 1, "", box_color, arg);
1549 }
1550 else
1551 {
1552 goto_pos(ses, top_row, top_col);
1553
1554 print_stdout(top_row, top_col, "%s%s", box_color, arg);
1555 }
1556 }
1557
DO_DRAW(draw_line_vertical)1558 DO_DRAW(draw_line_vertical)
1559 {
1560 int row, corner;
1561
1562 if (!HAS_BIT(flags, DRAW_FLAG_HOR))
1563 {
1564 SET_BIT(flags, DRAW_FLAG_VER);
1565 }
1566
1567 if (HAS_BIT(flags, DRAW_FLAG_APPENDIX))
1568 {
1569 if (!HAS_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT))
1570 {
1571 SET_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT);
1572 }
1573 }
1574
1575 corner = flags;
1576
1577 arg = arg1;
1578
1579 if (HAS_BIT(flags, DRAW_FLAG_TOP))
1580 {
1581 DEL_BIT(corner, DRAW_FLAG_BOT);
1582
1583 arg1 += sprintf(arg1, "{%s}", get_draw_corner(corner, "┬"));
1584 }
1585 else
1586 {
1587 arg1 += sprintf(arg1, "{%s}", draw_vertical(flags, "│"));
1588 }
1589
1590 if (rows - 2 > 0)
1591 {
1592 for (row = top_row + 1 ; row < bot_row ; row++)
1593 {
1594 arg1 += sprintf(arg1, "{%s}", draw_vertical(flags, "│"));
1595 }
1596 }
1597
1598 if (HAS_BIT(flags, DRAW_FLAG_BOT))
1599 {
1600 SET_BIT(corner, DRAW_FLAG_BOT);
1601 DEL_BIT(corner, DRAW_FLAG_TOP);
1602
1603 arg1 += sprintf(arg1, "{%s}", get_draw_corner(corner, "┴"));
1604 }
1605 else
1606 {
1607 arg1 += sprintf(arg1, "{%s}", draw_vertical(flags, "│"));
1608 }
1609
1610 row = top_row;
1611
1612 while (*arg)
1613 {
1614 arg = get_arg_in_braces(ses, arg, arg2, GET_ONE);
1615
1616 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
1617 {
1618 tintin_printf2(ses, "%*s%s%s", top_col - 1, "", box_color, arg2);
1619 }
1620 else
1621 {
1622 goto_pos(ses, row, top_col);
1623
1624 print_stdout(row, top_col, "%s%s", box_color, arg2);
1625 }
1626 row++;
1627 }
1628 return;
1629 }
1630
DO_DRAW(draw_line)1631 DO_DRAW(draw_line)
1632 {
1633 if (top_row == bot_row)
1634 {
1635 draw_line_horizontal(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
1636
1637 return;
1638 }
1639
1640 if (top_col == bot_col)
1641 {
1642 draw_line_vertical(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
1643
1644 return;
1645 }
1646
1647 draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
1648 }
1649
DO_DRAW(draw_map)1650 DO_DRAW(draw_map)
1651 {
1652 int map_rows = rows;
1653 int map_cols = cols;
1654
1655 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_TOP|DRAW_FLAG_PRUNED))
1656 {
1657 map_rows--;
1658 }
1659
1660 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_BOT|DRAW_FLAG_PRUNED))
1661 {
1662 map_rows--;
1663 }
1664
1665 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_PRUNED))
1666 {
1667 map_cols--;
1668 }
1669
1670 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_RIGHT|DRAW_FLAG_PRUNED))
1671 {
1672 map_cols--;
1673 }
1674
1675 if (ses->map && ses->map->in_room)
1676 {
1677 sprintf(arg, "{%d} {%d} {SAVE}", map_rows, map_cols);
1678
1679 map_map(ses, arg, arg1, arg2);
1680 }
1681 else
1682 {
1683 str_cpy(>d->buf, "{}");
1684 }
1685
1686 if (HAS_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT))
1687 {
1688 draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3);
1689 }
1690 else
1691 {
1692 draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3);
1693 }
1694 }
1695
1696 // ideas
1697 // 0 use color gradients
1698 // 1 use inverse color so text can be added to solid blocks.
1699 // 2 use ralign for raligned bar
1700 // 3 use calign for centered bar
1701 // 4 use box drawing modifiers if no box is specified.
1702 // 4.1 rounded = (###)
1703 // 4.2 teed = [---]
1704 // 4.3 jeweled = <###>
1705 // 4.4 crossed = +++++
1706 // 4.5 circled = OOOOO
1707 // 4.6 pruned = no rounding
1708
1709 // hpbar <square> {val;max;color}
1710
DO_DRAW(draw_hbar)1711 DO_DRAW(draw_hbar)
1712 {
1713 char *nest, *buf, *ptb, *col1;
1714 int cnt, val, bar;
1715 long double min, max;
1716
1717 bar = cols;
1718
1719 bar -= HAS_BIT(flags, DRAW_FLAG_LEFT) ? 1 : 0;
1720 bar -= HAS_BIT(flags, DRAW_FLAG_RIGHT) ? 1 : 0;
1721
1722 if (bar <= 0)
1723 {
1724 show_error(ses, LIST_COMMAND, "#DRAW BAR %d %d %d %d: DRAWING WIDTH (%d) MUST BE GREATER THAN 0.", top_row, top_col, bot_row, bot_col, bar);
1725
1726 return;
1727 }
1728
1729 buf = str_alloc_stack(0);
1730 col1 = str_alloc_stack(0);
1731
1732 str_cpy(>d->buf, "");
1733
1734 bar *= 8;
1735
1736 start:
1737
1738 arg = get_arg_in_braces(ses, arg, buf, GET_ALL);
1739
1740 nest = buf;
1741 nest = get_arg_in_braces(ses, nest, arg1, GET_ALL);
1742 if (*nest == COMMAND_SEPARATOR)
1743 nest++;
1744 nest = get_arg_in_braces(ses, nest, arg2, GET_ALL);
1745 if (*nest == COMMAND_SEPARATOR)
1746 nest++;
1747 nest = get_arg_in_braces(ses, nest, arg3, GET_ALL);
1748
1749 min = get_number(ses, arg1);
1750 max = get_number(ses, arg2);
1751
1752 if (max <= 0)
1753 {
1754 show_error(ses, LIST_COMMAND, "#DRAW BAR {%s;%s;%s}: MAX (%Lg) MUST BE GREATER THAN 0.", arg1, arg2, arg3, max);
1755
1756 return;
1757 }
1758
1759 if (min > max)
1760 {
1761 min = max;
1762 }
1763
1764 color_gradient(arg3, min, max);
1765
1766 translate_color_names(ses, arg3, col1);
1767
1768 // printf("debug: min %d max %d bar %d\n", (int) min, (int) max, bar);
1769
1770 ptb = buf;
1771
1772 ptb += sprintf(ptb, "{%s", col1);
1773
1774 val = bar * min / max;
1775
1776 for (cnt = 8 ; cnt <= bar + 8 ; cnt += 8)
1777 {
1778 // printf("debug: cnt %3d - val = %3d\n", cnt, val);
1779
1780 if (cnt > val)
1781 {
1782 break;
1783 }
1784 ptb += sprintf(ptb, "█");
1785 }
1786
1787 // printf("debug: val - lst = %d - %d\n", val, lst);
1788
1789 if (cnt <= bar)
1790 {
1791 switch (val + 8 - cnt)
1792 {
1793 case 0: ptb += sprintf(ptb, " "); break;
1794 case 1: ptb += sprintf(ptb, "▏"); break;
1795 case 2: ptb += sprintf(ptb, "▎"); break;
1796 case 3: ptb += sprintf(ptb, "▍"); break;
1797 case 4: ptb += sprintf(ptb, "▌"); break;
1798 case 5: ptb += sprintf(ptb, "▋"); break;
1799 case 6: ptb += sprintf(ptb, "▊"); break;
1800 case 7: ptb += sprintf(ptb, "▉"); break;
1801 case 8: ptb += sprintf(ptb, "█"); break;
1802 }
1803 ptb += sprintf(ptb, "%*s%s}", (bar - cnt) / 8, "", box_color);
1804 }
1805 else
1806 {
1807 ptb += sprintf(ptb, "%s}", box_color);
1808 }
1809
1810 str_cat(>d->buf, buf);
1811
1812 // printf("debug (%s) bar: %d cnt %d val %d\n", gtd->buf, bar, cnt, val);
1813
1814 if (*arg)
1815 {
1816 goto start;
1817 }
1818
1819 *arg1 = 0;
1820 *arg2 = 0;
1821 *arg3 = 0;
1822
1823 if (HAS_BIT(flags, DRAW_FLAG_TOP|DRAW_FLAG_BOT))
1824 {
1825 draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3);
1826 }
1827 else
1828 {
1829 draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, gtd->buf, arg1, arg2, arg3);
1830 }
1831 }
1832
1833 char *rain_symbols = "ロヲアウエオカキケコサシスセソタツテナニヌネハヒホマミムメモヤユラリワ01SԐ45789Z=*+-¦|_ʺ╌";
1834 char *braille_symbols = "⠁⠂⠃⠄⠅⠆⠇⠈⠊⠌⠎⠐⠑⠔⠕⠘⠜⠠⠡⠢⠣⠨⠪⠰⠱⠸⡀⡁⡂⡃⡄⡅⡆⡇⡈⡊⡌⡎⡐⡑⡔⡕⡘⡜⡠⡡⡢⡣⡨⡪⡰⡱⡸⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢌⢎⢐⢑⢔⢕⢘⢜⢠⢡⢢⢣⢨⢪⢰⢱";
1835
DO_DRAW(draw_rain)1836 DO_DRAW(draw_rain)
1837 {
1838 char code[BUFFER_SIZE], arg4[BUFFER_SIZE], *rain[400];
1839 struct listnode *node;
1840 int row, col, len, rand, cnt, size, max, utfs[400];
1841 long double density, fade;
1842
1843 strcpy(code, arg2);
1844
1845 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
1846
1847
1848 if (!valid_variable(ses, arg1))
1849 {
1850 show_error(ses, LIST_COMMAND, "#SYNTAX: #DRAW {<COLOR>} RAIN %d %d %d %d {<VARIABLE>} {[SPAWN]} {[FADE]} {[LEGEND]}.", top_row, top_col, bot_row, bot_col);
1851
1852 return;
1853 }
1854
1855 node = search_nest_node_ses(ses, arg1);
1856
1857 if (node == NULL || node->root == NULL)
1858 {
1859 node = set_nest_node(ses->list[LIST_VARIABLE], arg1, "{0}{}");
1860 }
1861
1862 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
1863
1864 if (*arg1 == 0)
1865 {
1866 density = 1;
1867 }
1868 else
1869 {
1870 density = URANGE(0.01, get_number(ses, arg1), 100);
1871 }
1872
1873 arg = get_arg_in_braces(ses, arg, arg1, GET_ONE);
1874
1875 if (*arg1 == 0)
1876 {
1877 fade = 10;
1878 }
1879 else
1880 {
1881 fade = URANGE(1, get_number(ses, arg1), 100);
1882 }
1883
1884 arg = get_arg_in_braces(ses, arg, arg4, GET_ONE);
1885
1886 if (*arg4 == 0)
1887 {
1888 if (HAS_BIT(ses->config_flags, CONFIG_FLAG_SCREENREADER))
1889 {
1890 for (max = len = 0 ; braille_symbols[len] ; max++)
1891 {
1892 rain[max] = &braille_symbols[len];
1893 utfs[max] = get_utf8_size(&braille_symbols[len]);
1894 len += utfs[max];
1895 }
1896 }
1897 else
1898 {
1899 for (max = len = 0 ; rain_symbols[len] ; max++)
1900 {
1901 rain[max] = &rain_symbols[len];
1902 utfs[max] = get_utf8_size(&rain_symbols[len]);
1903 len += utfs[max];
1904 }
1905 }
1906 }
1907 else
1908 {
1909 for (max = len = 0 ; arg4[len] && max < 400 ; max++)
1910 {
1911 rain[max] = &arg4[len];
1912 utfs[max] = get_utf8_size(&arg4[len]);
1913 len += utfs[max];
1914 }
1915 }
1916
1917 // tintin_printf2(ses, "debug: [%s] (%s) <%s>", code, fuzzy_color_code(ses, code), dim_color_code(ses, code, 20));
1918
1919 for (col = 0 ; col < 1 + bot_col - top_col ; col++)
1920 {
1921 if (node->root->used <= col)
1922 {
1923 set_nest_node(node->root, ntos(col), "");
1924 }
1925
1926 if (node->root->list[col]->val16[0] == 0)
1927 {
1928 if (generate_rand(ses) % 10000 / (long double) 100 < density)
1929 {
1930 rand = generate_rand(ses) % rows;
1931
1932 node->root->list[col]->val16[0] = 1;
1933 node->root->list[col]->val16[1] = rand;
1934 node->root->list[col]->val16[2] = rand < rows / 2 ? 2 : 0;
1935 node->root->list[col]->val16[3] = 0;
1936
1937 str_cpy_printf(&node->root->list[col]->arg2, "%*s", rand, "");
1938 }
1939 continue;
1940 }
1941 else if (node->root->list[col]->val16[0] == 1)
1942 {
1943 if (node->root->list[col]->val16[2])
1944 {
1945 node->root->list[col]->val16[3]++;
1946
1947 if (node->root->list[col]->val16[3] % 2)
1948 {
1949 rand = generate_rand(ses) % max;
1950
1951 sprintf(arg2, "%s%.*s", lit_color_code(ses, code, 10), utfs[rand], rain[rand]);
1952
1953 substitute(ses, arg2, arg3, SUB_COL);
1954
1955 goto_pos(ses, top_row + node->root->list[col]->val16[1], top_col + col);
1956
1957 print_stdout(0, 0, "%s", arg3);
1958
1959 continue;
1960 }
1961 }
1962
1963 rand = generate_rand(ses) % max;
1964
1965 str_cat_printf(&node->root->list[col]->arg2, "%.*s", utfs[rand], rain[rand]);
1966
1967 node->root->list[col]->val16[1]++;
1968
1969 if (generate_rand(ses) % 10000 / (long double) 100 < fade)
1970 {
1971 node->root->list[col]->val16[0] = 2;
1972 }
1973 else if (node->root->list[col]->val16[1] > rows - generate_rand(ses) % 8)
1974 {
1975 node->root->list[col]->val16[0] = 2;
1976 }
1977 }
1978 else
1979 {
1980 node->root->list[col]->val16[0]++;
1981 }
1982
1983 len = str_len(node->root->list[col]->arg2);
1984
1985 row = 0;
1986 cnt = 0;
1987
1988 if (node->root->list[col]->val16[0] == 1)
1989 {
1990 while (row < len)
1991 {
1992 if (node->root->list[col]->arg2[row] == ' ')
1993 {
1994 cnt++;
1995 row++;
1996
1997 continue;
1998 }
1999 goto_pos(ses, top_row + cnt, top_col + col);
2000
2001 cnt++;
2002
2003 size = get_utf8_size(&node->root->list[col]->arg2[row]);
2004
2005 if (cnt == node->root->list[col]->val16[1])
2006 {
2007 sprintf(arg2, "%s%.*s", lit_color_code(ses, code, 5), size, &node->root->list[col]->arg2[row]);
2008 }
2009 else
2010 {
2011 if (node->root->list[col]->val16[1] % 2 == 0)
2012 {
2013 row += size;
2014
2015 continue;
2016 }
2017
2018 sprintf(arg2, "%s%.*s", fuzzy_color_code(ses, code), size, &node->root->list[col]->arg2[row]);
2019 }
2020
2021 substitute(ses, arg2, arg3, SUB_COL);
2022
2023 print_stdout(0, 0, "%s", arg3);
2024
2025 row += size;
2026 }
2027 }
2028 else if (node->root->list[col]->val16[0] > 1)
2029 {
2030 while (row < len)
2031 {
2032 if (node->root->list[col]->arg2[row] == ' ')
2033 {
2034 cnt++;
2035 row++;
2036 continue;
2037 }
2038
2039 goto_pos(ses, top_row + cnt, top_col + col);
2040
2041 cnt++;
2042
2043 size = get_utf8_size(&node->root->list[col]->arg2[row]);
2044
2045 if (node->root->list[col]->val16[0] - cnt > 15)
2046 {
2047 sprintf(arg2, "%s ", dim_color_code(ses, code, node->root->list[col]->val16[0] - cnt));
2048 substitute(ses, arg2, arg3, SUB_COL);
2049 print_stdout(0, 0, "%s", arg3);
2050
2051 print_stdout(0, 0, " ");
2052 }
2053 else if (node->root->list[col]->val16[0] - cnt < 0)
2054 {
2055 sprintf(arg2, "%s%.*s", fuzzy_color_code(ses, code), size, &node->root->list[col]->arg2[row]);
2056 substitute(ses, arg2, arg3, SUB_COL);
2057 print_stdout(0, 0, "%s", arg3);
2058 }
2059 else
2060 {
2061 sprintf(arg2, "%s%.*s", dim_color_code(ses, code, node->root->list[col]->val16[0] - cnt), size, &node->root->list[col]->arg2[row]);
2062 substitute(ses, arg2, arg3, SUB_COL);
2063 print_stdout(0, 0, "%s", arg3);
2064 }
2065
2066 row += size;
2067 }
2068
2069 if (node->root->list[col]->val16[0] - cnt > 16)
2070 {
2071 node->root->list[col]->val16[0] = 0;
2072 node->root->list[col]->val16[1] = 0;
2073
2074 str_cpy(&node->root->list[col]->arg2, "");
2075 }
2076 }
2077 else
2078 {
2079 tintin_printf2(ses, "debug: problemo");
2080 }
2081 }
2082 }
2083
DO_DRAW(draw_side)2084 DO_DRAW(draw_side)
2085 {
2086 push_call("draw_side()");
2087
2088 draw_box(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
2089
2090 pop_call();
2091 return;
2092 }
2093
DO_DRAW(draw_square)2094 DO_DRAW(draw_square)
2095 {
2096 if (HAS_BIT(flags, DRAW_FLAG_TOP))
2097 {
2098 draw_top_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
2099 }
2100
2101 draw_text(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
2102
2103 if (HAS_BIT(flags, DRAW_FLAG_BOT))
2104 {
2105 draw_bot_side(ses, top_row, top_col, bot_row, bot_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
2106 }
2107 }
2108
2109
DO_DRAW(draw_table_grid)2110 DO_DRAW(draw_table_grid)
2111 {
2112 char buf1[BUFFER_SIZE], *str, buf2[BUFFER_SIZE], buf3[BUFFER_SIZE], row_color[COLOR_SIZE];
2113 int corner, blank, row, col, max_r, max_c, r, c, top_r, top_c, bot_r, bot_c, tot_r, tot_c;
2114
2115 row = cnt_arg_all(ses, arg, GET_ALL);
2116
2117 row = URANGE(0, row, (rows - 1) / 2);
2118
2119 get_arg_in_braces(ses, arg, buf1, GET_ALL);
2120
2121 col = cnt_arg_all(ses, buf1, GET_ALL);
2122
2123 if (row == 0 || col == 0)
2124 {
2125 tintin_printf2(ses, "#ERROR: #DRAW TABLE: NEED AT LEAST 1 ROW AND 1 COLUMN.");
2126
2127 return;
2128 }
2129
2130 if (*arg3)
2131 {
2132 substitute(ses, arg3, row_color, SUB_COL|SUB_LIT|SUB_ESC);
2133 }
2134 else
2135 {
2136 row_color[0] = 0;
2137 }
2138
2139 corner = flags;
2140
2141 DEL_BIT(corner, DRAW_FLAG_LEFT | DRAW_FLAG_RIGHT | DRAW_FLAG_TOP | DRAW_FLAG_BOT);
2142
2143 if (HAS_BIT(flags, DRAW_FLAG_GRID))
2144 {
2145 max_r = (rows - 1) / row;
2146 max_c = (cols - 1) / col;
2147
2148 tot_r = 1 + max_r * row;
2149 tot_c = 1 + max_c * col;
2150
2151 if (max_r <= 0)
2152 {
2153 tintin_printf2(ses, "#ERROR: #DRAW TABLE: ROW SIZE TOO SMALL.");
2154 return;
2155 }
2156
2157 if (max_c <= 0)
2158 {
2159 tintin_printf2(ses, "#ERROR: #DRAW TABLE: COLUMN SIZE TOO SMALL.");
2160 return;
2161 }
2162
2163
2164 for (r = 0 ; r < tot_r ; r++)
2165 {
2166 buf3[0] = 0;
2167
2168 if (r % max_r == 0)
2169 {
2170 arg = get_arg_in_braces(ses, arg, buf1, GET_ALL);
2171 str = buf1;
2172
2173 if (*arg == COMMAND_SEPARATOR)
2174 {
2175 arg++;
2176 }
2177 }
2178 else
2179 {
2180 str = buf1;
2181 }
2182
2183 for (c = 0 ; c < tot_c ; c++)
2184 {
2185 if (r == 0)
2186 {
2187 if (c == 0)
2188 {
2189 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_LEFT | DRAW_FLAG_TOP, "┌"));
2190 }
2191 else if (c == tot_c - 1)
2192 {
2193 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_RIGHT | DRAW_FLAG_TOP, "┐"));
2194 }
2195 else if (c % max_c == 0)
2196 {
2197 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_TOP, "┬"));
2198 }
2199 else
2200 {
2201 strcat(buf3, draw_horizontal(flags, "?"));
2202 }
2203 }
2204 else if (r == tot_r - 1)
2205 {
2206 if (c == 0)
2207 {
2208 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_LEFT | DRAW_FLAG_BOT, "?"));
2209 }
2210 else if (c == tot_c - 1)
2211 {
2212 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_RIGHT | DRAW_FLAG_BOT, "?"));
2213 }
2214 else if (c % max_c == 0)
2215 {
2216 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_BOT, "┬"));
2217 }
2218 else
2219 {
2220 strcat(buf3, draw_horizontal(flags, "?"));
2221 }
2222 }
2223 else if (r % max_r == 0)
2224 {
2225 if (c == 0)
2226 {
2227 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_HOR | DRAW_FLAG_LEFT, "?"));
2228 }
2229 else if (c == tot_c - 1)
2230 {
2231 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_TEED | DRAW_FLAG_HOR | DRAW_FLAG_RIGHT, "?"));
2232 }
2233 else if (c % max_c == 0)
2234 {
2235 strcat(buf3, get_draw_corner(corner | DRAW_FLAG_CROSSED, "?"));
2236 }
2237 else
2238 {
2239 strcat(buf3, draw_horizontal(flags, "?"));
2240 }
2241 }
2242 else if (r % max_r == 1)
2243 {
2244 if (c == tot_c - 1)
2245 {
2246 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
2247 {
2248 cat_sprintf(buf3, "%s", draw_vertical(flags, "│"));
2249 }
2250 else
2251 {
2252 goto_pos(ses, top_row + r, top_col + c);
2253
2254 print_stdout(top_row + r, top_col + c, "%s%s", box_color, draw_vertical(flags, "│"));
2255 }
2256 }
2257 else if (c == 0 || c % max_c == 0)
2258 {
2259 strcpy(buf2, row_color);
2260
2261 str = sub_arg_in_braces(ses, str, buf2 + strlen(buf2), GET_ALL, SUB_VAR|SUB_FUN|SUB_LIT|SUB_ESC|SUB_COL);
2262
2263 get_color_codes(row_color, buf2, row_color, GET_ALL);
2264
2265 top_r = top_row + r - 1;
2266 top_c = top_col + c;
2267 bot_r = top_row + r - 1 + max_r;
2268 bot_c = top_col + c + max_c;
2269
2270 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);
2271
2272 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
2273 {
2274 strcat(buf3, arg2);
2275 }
2276
2277 if (*str == COMMAND_SEPARATOR)
2278 {
2279 str++;
2280 }
2281 }
2282 }
2283 else
2284 {
2285 if (c == tot_c - 1)
2286 {
2287 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
2288 {
2289 cat_sprintf(buf3, "%s", draw_vertical(flags, "│"));
2290 }
2291 else
2292 {
2293 goto_pos(ses, top_row + r, top_col + c);
2294
2295 print_stdout(top_row + r, top_col + c, "%s%s", box_color, draw_vertical(flags, "│"));
2296 }
2297 }
2298 }
2299 }
2300
2301 if (*buf3)
2302 {
2303 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
2304 {
2305 tintin_printf2(ses, "%s%s%s", indent_one(top_col - 1), box_color, buf3);
2306 }
2307 else
2308 {
2309 goto_pos(ses, top_row + r, top_col);
2310
2311 print_stdout(top_row + r, top_col, "%s%s", box_color, buf3);
2312 }
2313 }
2314
2315 }
2316 return;
2317 }
2318
2319 blank = flags;
2320
2321 DEL_BIT(blank, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT|DRAW_FLAG_TOP|DRAW_FLAG_BOT);
2322
2323 max_r = rows / row;
2324 max_c = cols / col;
2325
2326 for (r = 0 ; r < row ; r++)
2327 {
2328 top_r = top_row + r * max_r;
2329 bot_r = top_row + r * max_r + max_r - 1;
2330
2331 arg = get_arg_in_braces(ses, arg, buf1, GET_ALL);
2332
2333 str = buf1;
2334
2335 for (c = 0 ; c < col ; c++)
2336 {
2337 str = get_arg_in_braces(ses, str, buf2, GET_ALL);
2338
2339 top_c = top_col + c * max_c;
2340 bot_c = top_col + c * max_c + max_c - 1;
2341
2342 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);
2343
2344 // 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);
2345
2346 if (*str == COMMAND_SEPARATOR)
2347 {
2348 str++;
2349 }
2350 }
2351
2352 if (cols > max_c * col)
2353 {
2354 top_c = top_col + c * max_c;
2355 bot_c = bot_col;
2356
2357 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);
2358 }
2359
2360 if (*arg == COMMAND_SEPARATOR)
2361 {
2362 arg++;
2363 }
2364 }
2365 }
2366
DO_DRAW(draw_text)2367 DO_DRAW(draw_text)
2368 {
2369 char *txt, *buf1, *buf2, *buf3, side1[100], side2[100];
2370 int row, col, height, width;
2371
2372 push_call("draw_text(%p,%d,%p,%p,%p)",ses,flags,arg,arg1,arg2);
2373
2374 buf1 = str_alloc_stack(0);
2375 buf2 = str_alloc_stack(0);
2376 buf3 = str_alloc_stack(0);
2377
2378 side1[0] = side2[0] = arg2[0] = 0;
2379
2380 txt = buf2;
2381
2382 substitute(ses, arg, buf3, SUB_VAR|SUB_FUN);
2383
2384 arg = buf3;
2385
2386 if (*arg3)
2387 {
2388 txt += substitute(ses, arg3, txt, SUB_COL|SUB_LIT|SUB_ESC);
2389 }
2390
2391 if (HAS_BIT(flags, DRAW_FLAG_HUGE))
2392 {
2393 string_to_stamp(ses, flags, arg, txt);
2394 }
2395 else
2396 {
2397 while (*arg)
2398 {
2399 arg = sub_arg_in_braces(ses, arg, buf1, GET_ALL, SUB_COL|SUB_LIT|SUB_ESC|SUB_VAR|SUB_FUN);
2400
2401 txt += sprintf(txt, "%s\n", buf1);
2402
2403 if (*arg == COMMAND_SEPARATOR)
2404 {
2405 arg++;
2406 }
2407 }
2408 string_to_font(ses, flags, buf2, buf2);
2409 }
2410
2411 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_TOP|DRAW_FLAG_PRUNED))
2412 {
2413 top_row++;
2414 rows--;
2415 }
2416
2417 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_BOT|DRAW_FLAG_PRUNED))
2418 {
2419 bot_row--;
2420 rows--;
2421 }
2422
2423 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_LEFT|DRAW_FLAG_PRUNED))
2424 {
2425 strcpy(side1, " ");
2426 cols--;
2427 }
2428
2429 if (HAS_BIT(flags, DRAW_FLAG_BOXED|DRAW_FLAG_RIGHT|DRAW_FLAG_PRUNED))
2430 {
2431 if (!HAS_BIT(flags, DRAW_FLAG_GRID) || HAS_BIT(flags, DRAW_FLAG_RIGHT))
2432 {
2433 strcpy(side2, " ");
2434 }
2435 cols--;
2436 }
2437
2438 if (HAS_BIT(flags, DRAW_FLAG_UALIGN))
2439 {
2440 ualign(ses, buf2, buf3, cols);
2441
2442 word_wrap_split(ses, buf3, buf1, cols, 0, 0, FLAG_NONE, &height, &width);
2443 }
2444 else
2445 {
2446 word_wrap_split(ses, buf2, buf1, cols, 0, 0, FLAG_NONE, &height, &width);
2447 }
2448
2449 height--;
2450
2451 txt = buf1;
2452
2453 if (HAS_BIT(flags, DRAW_FLAG_BALIGN))
2454 {
2455 str_fix(buf1);
2456
2457 while (height < rows)
2458 {
2459 str_ins(&buf1, 0, "\n");
2460 height++;
2461 }
2462 }
2463
2464 if (HAS_BIT(flags, DRAW_FLAG_TALIGN))
2465 {
2466 height = 0;
2467
2468 while (*txt && height < rows)
2469 {
2470 txt = strchr(txt, '\n');
2471 txt++;
2472 height++;
2473 }
2474 *txt = 0;
2475 txt = buf1;
2476 }
2477 else
2478 {
2479 while (*txt && height > rows)
2480 {
2481 txt = strchr(txt, '\n');
2482 txt++;
2483 height--;
2484 }
2485 }
2486
2487 if (HAS_BIT(flags, DRAW_FLAG_LEFT))
2488 {
2489 strcpy(side1, draw_vertical(flags, "│"));
2490 }
2491
2492 if (HAS_BIT(flags, DRAW_FLAG_RIGHT))
2493 {
2494 strcpy(side2, draw_vertical(flags, "│"));
2495 }
2496
2497 row = top_row;
2498 col = top_col;
2499
2500 arg = txt;
2501
2502 while (*arg)
2503 {
2504 arg = strchr(arg, '\n');
2505
2506 if (arg)
2507 {
2508 *arg++ = 0;
2509 }
2510 else
2511 {
2512 break;
2513 }
2514
2515 if (HAS_BIT(flags, DRAW_FLAG_CONVERT))
2516 {
2517 convert_meta(txt, buf3, FALSE);
2518
2519 justify_string(ses, buf3, buf2, 0 - cols, cols);
2520 }
2521 else if (HAS_BIT(flags, DRAW_FLAG_CALIGN|DRAW_FLAG_LALIGN|DRAW_FLAG_RALIGN))
2522 {
2523 if (HAS_BIT(flags, DRAW_FLAG_CALIGN))
2524 {
2525 calign(ses, txt, buf3, cols);
2526 }
2527 else if (HAS_BIT(flags, DRAW_FLAG_LALIGN))
2528 {
2529 lalign(ses, txt, buf3, cols);
2530 }
2531 else
2532 {
2533 ralign(ses, txt, buf3, cols);
2534 }
2535 justify_string(ses, buf3, buf2, 0 - cols, cols);
2536 }
2537 else
2538 {
2539 justify_string(ses, txt, buf2, 0 - cols, cols);
2540 }
2541
2542 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
2543 {
2544 if (HAS_BIT(flags, DRAW_FLAG_GRID))
2545 {
2546 cat_sprintf(arg2, "%s%s%s%s%s", box_color, side1, buf2, box_color, side2);
2547 }
2548 else
2549 {
2550 tintin_printf2(ses, "%s%s%s%s%s%s", indent_one(top_col - 1), box_color, side1, buf2, box_color, side2);
2551 }
2552 }
2553 else
2554 {
2555 goto_pos(ses, row, col);
2556
2557 print_stdout(row, col, "%s%s%s%s%s", box_color, side1, buf2, box_color, side2);
2558 }
2559 row++;
2560
2561 txt = arg;
2562 }
2563
2564 while (height < rows)
2565 {
2566 if (HAS_BIT(flags, DRAW_FLAG_LEFT))
2567 {
2568 strcpy(side1, draw_vertical(flags, "│"));
2569 }
2570
2571 if (HAS_BIT(flags, DRAW_FLAG_RIGHT))
2572 {
2573 strcpy(side2, draw_vertical(flags, "│"));
2574 }
2575
2576 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
2577 {
2578 if (HAS_BIT(flags, DRAW_FLAG_GRID))
2579 {
2580 cat_sprintf(arg2, "%s%s%*s%s%s", box_color, side1, cols, "", box_color, side2);
2581 }
2582 else
2583 {
2584 tintin_printf2(ses, "%s%s%s%-*s%s%s", indent_one(top_col - 1), box_color, side1, cols, "", box_color, side2);
2585 }
2586 }
2587 else
2588 {
2589 goto_pos(ses, row, col);
2590
2591 print_stdout(row, col, "%s%s%*s%s%s", box_color, side1, cols, "", box_color, side2);
2592
2593 row++;
2594 }
2595 height++;
2596 }
2597 pop_call();
2598 return;
2599 }
2600
DO_DRAW(draw_top_side)2601 DO_DRAW(draw_top_side)
2602 {
2603 int col, corner;
2604
2605 SET_BIT(flags, HAS_BIT(flags, DRAW_FLAG_VER) ? DRAW_FLAG_VER : DRAW_FLAG_HOR);
2606
2607 corner = flags;
2608
2609 DEL_BIT(corner, DRAW_FLAG_RIGHT|DRAW_FLAG_BOT);
2610
2611 arg = arg1;
2612
2613 if (HAS_BIT(flags, DRAW_FLAG_LEFT) || HAS_BIT(flags, DRAW_FLAG_TOP))
2614 {
2615 SET_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_RIGHT);
2616
2617 arg1 += sprintf(arg1, "%s%s", box_color, get_draw_corner(corner, "┌"));
2618 }
2619
2620 if (cols - 2 >= 0)
2621 {
2622 if (HAS_BIT(flags, DRAW_FLAG_TOP))
2623 {
2624 for (col = top_col + 1 ; col < bot_col ; col++)
2625 {
2626 arg1 += sprintf(arg1, "%s", draw_horizontal(flags, "─"));
2627 }
2628 }
2629 else if (HAS_BIT(flags, DRAW_FLAG_RIGHT) && cols - 2 > 0)
2630 {
2631 arg1 += sprintf(arg1, "\e[%dC", cols - 2);
2632 }
2633
2634 corner = flags;
2635
2636 DEL_BIT(corner, DRAW_FLAG_LEFT|DRAW_FLAG_BOT);
2637
2638 if (HAS_BIT(flags, DRAW_FLAG_TOP) || HAS_BIT(flags, DRAW_FLAG_RIGHT))
2639 {
2640 SET_BIT(corner, DRAW_FLAG_RIGHT|DRAW_FLAG_TOP);
2641
2642 arg1 += sprintf(arg1, "%s", get_draw_corner(corner, "┐"));
2643 }
2644 }
2645
2646 if (HAS_BIT(flags, DRAW_FLAG_SCROLL))
2647 {
2648 tintin_printf2(ses, "%*s%s", top_col - 1, "", arg);
2649 }
2650 else
2651 {
2652 goto_pos(ses, top_row, top_col);
2653
2654 print_stdout(top_row, top_col, "%s", arg);
2655 }
2656 }
2657
DO_DRAW(draw_vertical_lines)2658 DO_DRAW(draw_vertical_lines)
2659 {
2660 int row;
2661
2662 push_call("draw_vertical_lines(%p,%d,%p,%p,%p)",ses,flags,arg,arg1,arg2);
2663
2664 if (HAS_BIT(flags, DRAW_FLAG_SCROLL) || *arg)
2665 {
2666 draw_text(ses, top_row, top_col, bot_row, top_col, rows, cols, flags, box_color, txt_color, arg, arg1, arg2, arg3);
2667
2668 pop_call();
2669 return;
2670 }
2671
2672 arg1[0] = arg2[0] = 0;
2673
2674 if (HAS_BIT(flags, DRAW_FLAG_BOXED) || HAS_BIT(flags, DRAW_FLAG_TOP))
2675 {
2676 top_row++;
2677 rows--;
2678 }
2679
2680 if (HAS_BIT(flags, DRAW_FLAG_BOXED) || HAS_BIT(flags, DRAW_FLAG_BOT))
2681 {
2682 bot_row--;
2683 rows--;
2684 }
2685
2686 if (HAS_BIT(flags, DRAW_FLAG_LEFT))
2687 {
2688 strcpy(arg1, draw_vertical(flags, "│"));
2689
2690 cols--;
2691 }
2692
2693 if (HAS_BIT(flags, DRAW_FLAG_RIGHT))
2694 {
2695 strcpy(arg2, draw_vertical(flags, "│"));
2696
2697 cols--;
2698 }
2699
2700 // tintin_printf2(ses, "debug: rows = %d", rows);
2701
2702 if (*arg1)
2703 {
2704 row = top_row;
2705
2706 while (row <= bot_row)
2707 {
2708 goto_pos(ses, row, top_col);
2709
2710 print_stdout(row, top_col, "%s%s", box_color, arg1);
2711
2712 row++;
2713 }
2714 }
2715
2716 if (*arg2)
2717 {
2718 row = top_row;
2719
2720 while (row <= bot_row)
2721 {
2722 goto_pos(ses, row, bot_col);
2723
2724 print_stdout(row, bot_col, "%s%s", box_color, arg2);
2725
2726 row++;
2727 }
2728 }
2729
2730 pop_call();
2731 return;
2732 }
2733