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: