draw.c 64 KB

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