textDraw
textDraw.c (24115B)
1 #! /usr/bin/env sheepy
2 /* or direct path to sheepy: #! /usr/local/bin/sheepy */
3
4 /* Libsheepy documentation: https://spartatek.se/libsheepy/ */
5 #include "libsheepyObject.h"
6 #include "shpPackages/short/short.h"
7
8 /*
9
10 unicode symbols:
11 https://www.codetable.net/Group/box-drawing
12 https://www.codetable.net/Group/arrows
13
14 border styles:
15 space
16 single
17 double
18 singleDouble
19 doubleSingle
20 classic
21 heavy ━
22 dash ╴
23 heavyDash ╸
24 doubleDash ╌
25 heavyDoubleDash ╍
26 trippleDash ┄
27 heavyTrippleDash ┅
28 quadrupleDash ┈
29 heavyQuadrupleDash ┉
30 arcCorner ╭
31
32 line intersections
33 ┌
34 Box Drawings Light Down And Right ┌ ┌
35 ┍
36 Box Drawings Down Light And Right Heavy ┍ ┍
37 ┎
38 Box Drawings Down Heavy And Right Light ┎ ┎
39 ┏
40 Box Drawings Heavy Down And Right ┏ ┏
41 ┐
42 Box Drawings Light Down And Left ┐ ┐
43 ┑
44 Box Drawings Down Light And Left Heavy ┑ ┑
45 ┒
46 Box Drawings Down Heavy And Left Light ┒ ┒
47 ┓
48 Box Drawings Heavy Down And Left ┓ ┓
49 └
50 Box Drawings Light Up And Right └ └
51 ┕
52 Box Drawings Up Light And Right Heavy ┕ ┕
53 ┖
54 Box Drawings Up Heavy And Right Light ┖ ┖
55 ┗
56 Box Drawings Heavy Up And Right ┗ ┗
57 ┘
58 Box Drawings Light Up And Left ┘ ┘
59 ┙
60 Box Drawings Up Light And Left Heavy ┙ ┙
61 ┚
62 Box Drawings Up Heavy And Left Light ┚ ┚
63 ┛
64 Box Drawings Heavy Up And Left ┛ ┛
65 ├
66 Box Drawings Light Vertical And Right ├ ├
67 ┝
68 Box Drawings Vertical Light And Right Heavy ┝ ┝
69 ┞
70 Box Drawings Up Heavy And Right Down Light ┞ ┞
71 ┟
72 Box Drawings Down Heavy And Right Up Light ┟ ┟
73 ┠
74 Box Drawings Vertical Heavy And Right Light ┠ ┠
75 ┡
76 Box Drawings Down Light And Right Up Heavy ┡ ┡
77 ┢
78 Box Drawings Up Light And Right Down Heavy ┢ ┢
79 ┣
80 Box Drawings Heavy Vertical And Right ┣ ┣
81 ┤
82 Box Drawings Light Vertical And Left ┤ ┤
83 ┥
84 Box Drawings Vertical Light And Left Heavy ┥ ┥
85 ┦
86 Box Drawings Up Heavy And Left Down Light ┦ ┦
87 ┧
88 Box Drawings Down Heavy And Left Up Light ┧ ┧
89 ┨
90 Box Drawings Vertical Heavy And Left Light ┨ ┨
91 ┩
92 Box Drawings Down Light And Left Up Heavy ┩ ┩
93 ┪
94 Box Drawings Up Light And Left Down Heavy ┪ ┪
95 ┫
96 Box Drawings Heavy Vertical And Left ┫ ┫
97 ┬
98 Box Drawings Light Down And Horizontal ┬ ┬
99 ┭
100 Box Drawings Left Heavy And Right Down Light ┭ ┭
101 ┮
102 Box Drawings Right Heavy And Left Down Light ┮ ┮
103 ┯
104 Box Drawings Down Light And Horizontal Heavy ┯ ┯
105 ┰
106 Box Drawings Down Heavy And Horizontal Light ┰ ┰
107 ┱
108 Box Drawings Right Light And Left Down Heavy ┱ ┱
109 ┲
110 Box Drawings Left Light And Right Down Heavy ┲ ┲
111 ┳
112 Box Drawings Heavy Down And Horizontal ┳ ┳
113 ┴
114 Box Drawings Light Up And Horizontal ┴ ┴
115 ┵
116 Box Drawings Left Heavy And Right Up Light ┵ ┵
117 ┶
118 Box Drawings Right Heavy And Left Up Light ┶ ┶
119 ┷
120 Box Drawings Up Light And Horizontal Heavy ┷ ┷
121 ┸
122 Box Drawings Up Heavy And Horizontal Light ┸ ┸
123 ┹
124 Box Drawings Right Light And Left Up Heavy ┹ ┹
125 ┺
126 Box Drawings Left Light And Right Up Heavy ┺ ┺
127 ┻
128 Box Drawings Heavy Up And Horizontal ┻ ┻
129 ╞
130 Box Drawings Vertical Single And Right Double ╞ ╞
131 ╟
132 Box Drawings Vertical Double And Right Single ╟ ╟
133 ╠
134 Box Drawings Double Vertical And Right ╠ ╠
135 ╡
136 Box Drawings Vertical Single And Left Double ╡ ╡
137 ╢
138 Box Drawings Vertical Double And Left Single ╢ ╢
139 ╣
140 Box Drawings Double Vertical And Left ╣ ╣
141 ╤
142 Box Drawings Down Single And Horizontal Double ╤ ╤
143 ╥
144 Box Drawings Down Double And Horizontal Single ╥ ╥
145 ╦
146 Box Drawings Double Down And Horizontal ╦ ╦
147 ╧
148 Box Drawings Up Single And Horizontal Double ╧ ╧
149 ╨
150 Box Drawings Up Double And Horizontal Single ╨ ╨
151 ╩
152 Box Drawings Double Up And Horizontal ╩ ╩
153
154 geometric shape
155 ◀
156 Black Left-Pointing Triangle
157 ▲
158 Black Up-Pointing Triangle
159 ▶
160 Black Right-Pointing Triangle
161 ▼
162 Black Down-Pointing Triangle
163 ◃
164 White Left-Pointing Small Triangle ◃ ◃
165 ▵
166 White Up-Pointing Small Triangle ▵ ▵
167 ▹
168 White Right-Pointing Small Triangle
169 ▿
170 White Down-Pointing Small Triangle ▿ ▿
171 ◁
172 White Left-Pointing Triangle ◁ ◁
173 △
174 White Up-Pointing Triangle △ △
175 ▷
176 White Right-Pointing Triangle ▷ ▷
177 ▽
178 White Down-Pointing Triangle ▽ ▽
179 ◂
180 Black Left-Pointing Small Triangle ◂ ◂
181 ▴
182 Black Up-Pointing Small Triangle ▴ ▴
183 ▸
184 Black Right-Pointing Small Triangle ▸ ▸
185 ▾
186 Black Down-Pointing Small Triangle ▾ ▾
187 ▻
188 White Right-Pointing Pointer ▻ ▻
189 ◅
190 White Left-Pointing Pointer
191
192 arrow
193 ←
194 Leftwards Arrow ← ← ←
195 ↑
196 Upwards Arrow ↑ ↑ ↑
197 →
198 Rightwards Arrow → → →
199 ↓
200 Downwards Arrow ↓ ↓ ↓
201 ↚
202 Leftwards Arrow With Stroke ↚ ↚
203 ↛
204 Rightwards Arrow With Stroke ↛ ↛
205 ↜
206 Leftwards Wave Arrow ↜ ↜
207 ↝
208 Rightwards Wave Arrow ↝ ↝
209 ↞
210 Leftwards Two Headed Arrow ↞ ↞
211 ↟
212 Upwards Two Headed Arrow ↟ ↟
213 ↠
214 Rightwards Two Headed Arrow ↠ ↠
215 ↡
216 Downwards Two Headed Arrow ↡ ↡
217 ↢
218 Leftwards Arrow With Tail ↢ ↢
219 ↣
220 Rightwards Arrow With Tail ↣ ↣
221 ↤
222 Leftwards Arrow From Bar ↤ ↤
223 ↥
224 Upwards Arrow From Bar ↥ ↥
225 ↦
226 Rightwards Arrow From Bar ↦ ↦
227 ↧
228 Downwards Arrow From Bar ↧ ↧
229 ⇋
230 Leftwards Harpoon Over Rightwards Harpoon ⇋ ⇋
231 ⇌
232 Rightwards Harpoon Over Leftwards Harpoon ⇌ ⇌
233 ⇍
234 Leftwards Double Arrow With Stroke ⇍ ⇍
235 ⇎
236 Left Right Double Arrow With Stroke ⇎ ⇎
237 ⇏
238 Rightwards Double Arrow With Stroke ⇏ ⇏
239 ⇐
240 Leftwards Double Arrow ⇐ ⇐ ⇐
241 ⇑
242 Upwards Double Arrow ⇑ ⇑ ⇑
243 ⇒
244 Rightwards Double Arrow ⇒ ⇒ ⇒
245 ⇓
246 Downwards Double Arrow ⇓ ⇓ ⇓
247 ⇜
248 Leftwards Squiggle Arrow ⇜ ⇜
249 ⇝
250 Rightwards Squiggle Arrow ⇝ ⇝
251 ⇞
252 Upwards Arrow With Double Stroke ⇞ ⇞
253 ⇟
254 Downwards Arrow With Double Stroke ⇟ ⇟
255 ⇠
256 Leftwards Dashed Arrow ⇠ ⇠
257 ⇡
258 Upwards Dashed Arrow ⇡ ⇡
259 ⇢
260 Rightwards Dashed Arrow ⇢ ⇢
261 ⇣
262 Downwards Dashed Arrow ⇣ ⇣
263 ⇤
264 Leftwards Arrow To Bar ⇤ ⇤
265 ⇥
266 Rightwards Arrow To Bar ⇥ ⇥
267 ⇴
268 Right Arrow With Small Circle ⇴ ⇴
269 ⇷
270 Leftwards Arrow With Vertical Stroke ⇷ ⇷
271 ⇸
272 Rightwards Arrow With Vertical Stroke ⇸ ⇸
273 ⇹
274 Left Right Arrow With Vertical Stroke ⇹ ⇹
275 ⇺
276 Leftwards Arrow With Double Vertical Stroke ⇺ ⇺
277 ⇻
278 Rightwards Arrow With Double Vertical Stroke ⇻ ⇻
279 ⇼
280 Left Right Arrow With Double Vertical Stroke ⇼ ⇼
281 ⇽
282 Leftwards Open-Headed Arrow ⇽ ⇽
283 ⇾
284 Rightwards Open-Headed Arrow ⇾ ⇾
285 ⇿
286 Left Right Open-Headed Arrow ⇿ ⇿
287
288 */
289
290
291
292 /* enable/disable logging */
293 /* #undef pLog */
294 /* #define pLog(...) */
295
296 typ struct {
297 char *value;
298 char *color;
299 char *bgColor;
300 } screenElementt;
301
302 typ struct {
303 char *topLeft;
304 char *topRight;
305 char *bottomLeft;
306 char *bottomRight;
307 char *horizontal;
308 char *vertical;
309 } borderStylet;
310
311 // space
312 internal borderStylet spaceBorderStyle = {
313 .topLeft= " ",
314 .topRight= " ",
315 .bottomLeft= " ",
316 .bottomRight= " ",
317 .horizontal= " ",
318 .vertical= " "
319 };
320
321 // single
322 internal borderStylet singleBorderStyle = {
323 .topLeft= "┌",
324 .topRight= "┐",
325 .bottomLeft= "└",
326 .bottomRight= "┘",
327 .horizontal= "─",
328 .vertical= "│"
329 };
330
331 // double
332 internal borderStylet doubleBorderStyle = {
333 .topLeft= "╔",
334 .topRight= "╗",
335 .bottomLeft= "╚",
336 .bottomRight= "╝",
337 .horizontal= "═",
338 .vertical= "║"
339 };
340
341 // single-double
342 internal borderStylet singleDoubleBorderStyle = {
343 .topLeft= "╓",
344 .topRight= "╖",
345 .bottomLeft= "╙",
346 .bottomRight= "╜",
347 .horizontal= "─",
348 .vertical= "║"
349 };
350
351 // double-single
352 internal borderStylet doubleSingleBorderStyle = {
353 .topLeft= "╒",
354 .topRight= "╕",
355 .bottomLeft= "╘",
356 .bottomRight= "╛",
357 .horizontal= "═",
358 .vertical= "│"
359 };
360
361
362 // classic
363 internal borderStylet classicBorderStyle = {
364 .topLeft= "+",
365 .topRight= "+",
366 .bottomLeft= "+",
367 .bottomRight= "+",
368 .horizontal= "-",
369 .vertical= "|"
370 };
371
372 // heavy
373 internal borderStylet heavyBorderStyle = {
374 .topLeft= "┏",
375 .topRight= "┓",
376 .bottomLeft= "┗",
377 .bottomRight= "┛",
378 .horizontal= "━",
379 .vertical= "┃"
380 };
381
382 // dash
383 internal borderStylet dashBorderStyle = {
384 .topLeft= "┌",
385 .topRight= "┐",
386 .bottomLeft= "└",
387 .bottomRight= "┘",
388 .horizontal= "╴",
389 .vertical= "╵"
390 };
391
392 // heavyDash
393 internal borderStylet heavyDashBorderStyle = {
394 .topLeft= "┏",
395 .topRight= "┓",
396 .bottomLeft= "┗",
397 .bottomRight= "┛",
398 .horizontal= "╸",
399 .vertical= "╹"
400 };
401
402 // doubleDash
403 internal borderStylet doubleDashBorderStyle = {
404 .topLeft= "┌",
405 .topRight= "┐",
406 .bottomLeft= "└",
407 .bottomRight= "┘",
408 .horizontal= "╌",
409 .vertical= "╎"
410 };
411
412 // heavyDoubleDash
413 internal borderStylet heavyDoubleDashBorderStyle = {
414 .topLeft= "┏",
415 .topRight= "┓",
416 .bottomLeft= "┗",
417 .bottomRight= "┛",
418 .horizontal= "╍",
419 .vertical= "╏"
420 };
421
422 // trippleDash
423 internal borderStylet trippleDashBorderStyle = {
424 .topLeft= "┌",
425 .topRight= "┐",
426 .bottomLeft= "└",
427 .bottomRight= "┘",
428 .horizontal= "┄",
429 .vertical= "┆"
430 };
431
432 // heavyTrippleDash
433 internal borderStylet heavyTrippleDashBorderStyle = {
434 .topLeft= "┏",
435 .topRight= "┓",
436 .bottomLeft= "┗",
437 .bottomRight= "┛",
438 .horizontal= "┅",
439 .vertical= "┇"
440 };
441
442 // quadrupleDash
443 internal borderStylet quadrupleDashBorderStyle = {
444 .topLeft= "┌",
445 .topRight= "┐",
446 .bottomLeft= "└",
447 .bottomRight= "┘",
448 .horizontal= "┈",
449 .vertical= "┊"
450 };
451
452 // heavyQuadrupleDash
453 internal borderStylet heavyQuadrupleDashBorderStyle = {
454 .topLeft= "┏",
455 .topRight= "┓",
456 .bottomLeft= "┗",
457 .bottomRight= "┛",
458 .horizontal= "┉",
459 .vertical= "┋"
460 };
461
462 char *cross[3][3] = {
463 {"┼", "╪", "┿"},
464 {"╫", "╬", "╋"},
465 {"╂", "╋", "╋"}
466 };
467
468 bool showDiagram(smallJsont *dia) {
469
470 // Steps
471 // find diagram size
472 // show diagram
473 // allocate screen
474 // draw objects
475
476 u32 w = 0 ,h = 0; // diagram width and height
477 if (!dia) ret no;
478 // find diagram size
479 iter(dia, E) {
480 cast(smallDictt*,e,E);
481 if (!isOSmallDictG(e)) ret no; // all diagram elements are dicts
482 // compute element edges
483 u32 ew = 0, eh = 0;
484 if (eqG($(e,"type"), "verticalLine")) {
485 ew = u$(e,"at");
486 eh = maxV(u$(e,"start"), u$(e, "stop"));
487 }
488 elif (eqG($(e,"type"), "horizontalLine")) {
489 ew = maxV(u$(e,"start"), u$(e, "stop"));
490 eh = u$(e,"at");
491 }
492 elif (eqG($(e,"type"), "text")) {
493 ew = u$(e, "x") + strlen($(e,"text"));
494 eh = u$(e, "y");
495 }
496 elif (eqG($(e,"type"), "box")) {
497 ew = u$(e, "xx");
498 eh = u$(e, "yy");
499 }
500 w = maxV(w, ew);
501 h = maxV(h, eh);
502 }
503 // allocate screen
504 inc w; inc h;
505 screenElementt *screen = calloc(1, w * h * sizeof(screenElementt));
506 // draw objects
507 iter(dia, E) {
508 cast(smallDictt*,e,E);
509
510 cleanCharP(color) = null;
511 cleanCharP(bgColor) = null;
512 #define oColor(colr, value)\
513 if (icEqG($(e, "color"), colr)) {\
514 color = strdup(value);\
515 }
516 #define oBgColor(colr, value)\
517 if (icEqG($(e, "bgColor"), colr)) {\
518 bgColor = strdup(value);\
519 }
520 #define oHexColor(colr, opt, fgbgc)\
521 if ($(e, colr) && $(e, colr)[0] == '#') {\
522 /* hex color */\
523 char *c = $(e, colr);\
524 /* check if color is 0 */\
525 bool is0 = true;\
526 size_t i = 1;\
527 while(c[i]) if (c[i++] != '0') {is0 = false; break;}\
528 \
529 opt = BLK;\
530 if (!is0) {\
531 /* convert color string to int */\
532 cleanCharP(s) = catS("0x", &c[1]);\
533 u32 c = parseHex(s);\
534 if (!c) {\
535 /* invalid hex number */\
536 opt = strdup("");\
537 }\
538 else {\
539 opt = formatS("\x1b["fgbgc";2;%d;%d;%dm", c>>16, (c&0xFF00)>>8, c&0xFF);\
540 }\
541 }\
542 }
543 oColor ( "black" , BLK)
544 else oColor ( "red" , RED)
545 else oColor ( "green" , GRN)
546 else oColor ( "yellow" , YLW)
547 else oColor ( "blue" , BLU)
548 else oColor ( "magenta" , MGT)
549 else oColor ( "cyan" , CYN)
550 else oColor ( "white" , BLD WHT)
551 else oColor ( "gray" , WHT)
552 else oHexColor("color", color, "38")
553 oBgColor ( "black" , BGBLK)
554 else oBgColor ( "red" , BGRED)
555 else oBgColor ( "green" , BGGRN)
556 else oBgColor ( "yellow" , BGYLW)
557 else oBgColor ( "blue" , BGBLU)
558 else oBgColor ( "magenta" , BGMGT)
559 else oBgColor ( "cyan" , BGCYN)
560 else oBgColor ( "white" , BGWHT) // TODO RGB?
561 else oBgColor ( "gray" , BGWHT)
562 else oHexColor("bgColor", bgColor, "48")
563
564 if (eqG($(e,"type"), "verticalLine")) {
565 char *line;
566 #define lineStyle(style, value)\
567 if (icEqG($(e, "style"), style)) {\
568 line = value;\
569 }
570 lineStyle("single", "│")
571 else lineStyle("double", "║")
572 else lineStyle("heavy", "┃")
573 else lineStyle("dash", "╵")
574 else lineStyle("heavyDash", "╹")
575 else lineStyle("doubleDash", "╎")
576 else lineStyle("heavyDoubleDash", "╏")
577 else lineStyle("trippleDash", "┆")
578 else lineStyle("heavyTrippleDash", "┇")
579 else lineStyle("quadrupleDash", "┊")
580 else lineStyle("heavyQuadrupleDash", "┋")
581 screenElementt *ptr = screen + u$(e, "at") + u$(e, "start") * w;
582 ptr->value = strdup(orS($(e,"startEdge"), line));
583 if (color) ptr->color = strdup(color);
584 if (bgColor) ptr->bgColor = strdup(bgColor);
585 ptr = screen + u$(e, "at") + u$(e, "stop") * w;
586 ptr->value = strdup(orS($(e,"stopEdge"), line));
587 if (color) ptr->color = strdup(color);
588 if (bgColor) ptr->bgColor = strdup(bgColor);
589 u32 y = minV(u$(e, "start"), u$(e, "stop")) + 1/*edge*/;
590 u32 yy = maxV(u$(e, "start"), u$(e, "stop"));
591 rangeFrom(i, y, yy) {
592 ptr = screen + u$(e, "at") + i * w;
593 ptr->value = strdup(line);
594 if (color) ptr->color = strdup(color);
595 if (bgColor) ptr->bgColor = strdup(bgColor);
596 }
597 }
598 elif (eqG($(e,"type"), "horizontalLine")) {
599 char *line;
600 lineStyle("single", "─")
601 else lineStyle("double", "═")
602 else lineStyle("heavy", "━")
603 else lineStyle("dash", "╴")
604 else lineStyle("heavyDash", "╸")
605 else lineStyle("doubleDash", "╌")
606 else lineStyle("heavyDoubleDash", "╍")
607 else lineStyle("trippleDash", "┄")
608 else lineStyle("heavyTrippleDash", "┅")
609 else lineStyle("quadrupleDash", "┈")
610 else lineStyle("heavyQuadrupleDash", "┉")
611 screenElementt *ptr = screen + u$(e, "start") + u$(e, "at") * w;
612 ptr->value = strdup(orS($(e,"startEdge"), line));
613 if (color) ptr->color = strdup(color);
614 if (bgColor) ptr->bgColor = strdup(bgColor);
615 ptr = screen + u$(e, "stop") + u$(e, "at") * w;
616 ptr->value = strdup(orS($(e,"stopEdge"), line));
617 if (color) ptr->color = strdup(color);
618 if (bgColor) ptr->bgColor = strdup(bgColor);
619 u32 x = minV(u$(e, "start"), u$(e, "stop")) + 1/*edge*/;
620 u32 xx = maxV(u$(e, "start"), u$(e, "stop"));
621 rangeFrom(i, x, xx) {
622 ptr = screen + i + u$(e, "at") * w;
623 ptr->value = strdup(line);
624 if (color) ptr->color = strdup(color);
625 if (bgColor) ptr->bgColor = strdup(bgColor);
626 }
627 }
628 elif (eqG($(e,"type"), "text")) {
629 screenElementt *ptr = screen + u$(e, "x") + u$(e, "y") * w;
630 const char *s = $(e,"text");
631 char val[2] = init0Var;
632 loop(lenG(s)) {
633 val[0] = *s;
634 ptr->value = strdup(val);
635 if (color) ptr->color = strdup(color);
636 if (bgColor) ptr->bgColor = strdup(bgColor);
637 inc s;
638 inc ptr;
639 }
640 }
641 elif (eqG($(e,"type"), "box")) {
642 borderStylet borderStyle;
643 #define oborderStyle(style, value)\
644 if (icEqG($(e, "style"), style)) {\
645 borderStyle = value;\
646 }
647 oborderStyle("space" , spaceBorderStyle)
648 else oborderStyle("single" , singleBorderStyle)
649 else oborderStyle("double" , doubleBorderStyle)
650 else oborderStyle("single-double" , singleDoubleBorderStyle)
651 else oborderStyle("double-single" , doubleSingleBorderStyle)
652 else oborderStyle("classic" , classicBorderStyle)
653 else oborderStyle("heavy" , heavyBorderStyle)
654 else oborderStyle("dash" , dashBorderStyle)
655 else oborderStyle("heavyDash" , heavyDashBorderStyle)
656 else oborderStyle("doubleDash" , doubleDashBorderStyle)
657 else oborderStyle("heavyDoubleDash" , heavyDoubleDashBorderStyle)
658 else oborderStyle("trippleDash" , trippleDashBorderStyle)
659 else oborderStyle("heavyTrippleDash" , heavyTrippleDashBorderStyle)
660 else oborderStyle("quadrupleDash" , quadrupleDashBorderStyle)
661 else oborderStyle("heavyQuadrupleDash", heavyQuadrupleDashBorderStyle)
662
663 if (getG(e, rtBool, "arcCorner")) {
664 borderStyle.topLeft = "╭";
665 borderStyle.topRight = "╮";
666 borderStyle.bottomLeft = "╰";
667 borderStyle.bottomRight = "╯";
668 }
669
670 screenElementt *ptr = screen + u$(e, "x") + u$(e, "y") * w;
671 ptr->value = strdup(borderStyle.topLeft);
672 if (color) ptr->color = strdup(color);
673 if (bgColor) ptr->bgColor = strdup(bgColor);
674 ptr = screen + u$(e, "xx") + u$(e, "y") * w;
675 ptr->value = strdup(borderStyle.topRight);
676 if (color) ptr->color = strdup(color);
677 if (bgColor) ptr->bgColor = strdup(bgColor);
678 ptr = screen + u$(e, "x") + u$(e, "yy") * w;
679 ptr->value = strdup(borderStyle.bottomLeft);
680 if (color) ptr->color = strdup(color);
681 if (bgColor) ptr->bgColor = strdup(bgColor);
682 ptr = screen + u$(e, "xx") + u$(e, "yy") * w;
683 ptr->value = strdup(borderStyle.bottomRight);
684 if (color) ptr->color = strdup(color);
685 if (bgColor) ptr->bgColor = strdup(bgColor);
686 rangeFrom(i, u$(e, "x")+1, u$(e, "xx")) {
687 ptr = screen + i + u$(e, "y") * w;
688 ptr->value = strdup(borderStyle.horizontal);
689 if (color) ptr->color = strdup(color);
690 if (bgColor) ptr->bgColor = strdup(bgColor);
691 ptr = screen + i + u$(e, "yy") * w;
692 ptr->value = strdup(borderStyle.horizontal);
693 if (color) ptr->color = strdup(color);
694 if (bgColor) ptr->bgColor = strdup(bgColor);
695 }
696 rangeFrom(i, u$(e, "y")+1, u$(e, "yy")) {
697 ptr = screen + u$(e, "x") + i * w;
698 ptr->value = strdup(borderStyle.vertical);
699 if (color) ptr->color = strdup(color);
700 if (bgColor) ptr->bgColor = strdup(bgColor);
701 ptr = screen + u$(e, "xx") + i * w;
702 ptr->value = strdup(borderStyle.vertical);
703 if (color) ptr->color = strdup(color);
704 if (bgColor) ptr->bgColor = strdup(bgColor);
705 }
706 // box inside
707 rangeFrom(j, u$(e,"y")+1, u$(e,"yy")) {
708 rangeFrom(i, u$(e,"x")+1, u$(e,"xx")) {
709 ptr = screen + i + j * w;
710 ptr->value = strdup(" ");
711 if (color) ptr->color = strdup(color);
712 if (bgColor) ptr->bgColor = strdup(bgColor);
713 }
714 }
715 }
716 }
717 // add line crosses
718 // loop on vertical lines: v
719 // loop on horizontal lines: u
720 // choose cross character
721 createSmallJson(vertical);
722 createSmallJson(horizontal);
723 setsoG(&vertical, getsoG(dia));
724 setsoG(&horizontal, getsoG(dia));
725 u8 vidx, hidx; // indexes in cross[][]
726 iter(&vertical, V) {
727 cast(smallDictt*,v,V);
728 if (not eqG($(v,"type"), "verticalLine")) continue;
729
730 iter(&horizontal, U) {
731 cast(smallDictt*,u,U);
732 if (not eqG($(u,"type"), "horizontalLine")) continue;
733
734 // check if the lines cross
735 var vY = minV(u$(v, "start"), u$(v, "stop"));
736 var vYY = maxV(u$(v, "start"), u$(v, "stop"));
737 var uX = minV(u$(u, "start"), u$(u, "stop"));
738 var uXX = maxV(u$(u, "start"), u$(u, "stop"));
739 if (u$(v, "at") <= uX or u$(v, "at") >= uXX) continue; // outside
740 if (u$(u, "at") <= vY or u$(u, "at") >= vYY) continue; // outside
741
742 #define vCross(style, value)\
743 if (icEqG($(v, "style"), style)) {\
744 vidx = value;\
745 }
746 vCross ("single", 0)
747 else vCross("double", 1)
748 else vCross("heavy", 2)
749 else vCross("dash", 0)
750 else vCross("heavyDash", 2)
751 else vCross("doubleDash", 0)
752 else vCross("heavyDoubleDash", 2)
753 else vCross("trippleDash", 0)
754 else vCross("heavyTrippleDash", 2)
755 else vCross("quadrupleDash", 0)
756 else vCross("heavyQuadrupleDash", 2)
757 else vidx = 0;
758
759 #define hCross(style, value)\
760 if (icEqG($(u, "style"), style)) {\
761 hidx = value;\
762 }
763 hCross ("single", 0)
764 else hCross("double", 1)
765 else hCross("heavy", 2)
766 else hCross("dash", 0)
767 else hCross("heavyDash", 2)
768 else hCross("doubleDash", 0)
769 else hCross("heavyDoubleDash", 2)
770 else hCross("trippleDash", 0)
771 else hCross("heavyTrippleDash", 2)
772 else hCross("quadrupleDash", 0)
773 else hCross("heavyQuadrupleDash", 2)
774 else hidx = 0;
775
776 screenElementt *ptr = screen + u$(v, "at") + u$(u, "at") * w;
777 free(ptr->value);
778 ptr->value = strdup(cross[vidx][hidx]);
779
780 }
781 }
782 // show diagram
783 range(j, h) {
784 range(i, w) {
785 screenElementt *ptr = screen + i + j * w;
786 if (ptr->value) printf("%s%s%s"RST, nS(ptr->color), nS(ptr->bgColor), ptr->value);
787 else printf(" ");
788 }
789 put
790 }
791 range(j, h) {
792 range(i, w) {
793 screenElementt *ptr = screen + i + j * w;
794 free(ptr->value);
795 free(ptr->color);
796 free(ptr->bgColor);
797 }
798 }
799 free(screen);
800 }
801
802 int main(int ARGC, char** ARGV) {
803
804 initLibsheepy(ARGV[0]);
805 setLogMode(LOG_FUNC);
806 //openProgLogFile();
807 setLogSymbols(LOG_UTF8);
808 //disableLibsheepyErrorLogs;
809
810 if (ARGC < 2) {
811 logI("Usage: textDraw file");
812 }
813
814 cleanAllocateSmallJson(dia);
815 readFileG(dia, ARGV[1]);
816
817 showDiagram(dia);
818 }
819 // vim: set expandtab ts=2 sw=2: