1/* Hello, Emacs, this is -*-C-*- */ 2 3/* GNUPLOT - texdraw.trm */ 4 5/*[ 6 * Copyright 1990 - 1993, 1998, 2004, 2018 7 * 8 * Permission to use, copy, and distribute this software and its 9 * documentation for any purpose with or without fee is hereby granted, 10 * provided that the above copyright notice appear in all copies and 11 * that both that copyright notice and this permission notice appear 12 * in supporting documentation. 13 * 14 * Permission to modify the software is granted, but not the right to 15 * distribute the complete modified source code. Modifications are to 16 * be distributed as patches to the released version. Permission to 17 * distribute binaries produced by compiling modified sources is granted, 18 * provided you 19 * 1. distribute the corresponding source modifications from the 20 * released version in the form of a patch file along with the binaries, 21 * 2. add special version identification to distinguish your version 22 * in addition to the base release version number, 23 * 3. provide your name and address as the primary contact for the 24 * support of your modified version, and 25 * 4. retain our contact information in regard to use of the base 26 * software. 27 * Permission to distribute the released version of the source code along 28 * with corresponding source modifications in the form of a patch file is 29 * granted with same provisions 2 through 4 for binary distributions. 30 * 31 * This software is provided "as is" without express or implied warranty 32 * to the extent permitted by applicable law. 33]*/ 34 35/* 36 * This file is included by ../term.c. 37 * 38 * This terminal driver supports: 39 * The TEXDRAW macros for LaTeX. 40 * 41 * AUTHORS 42 * Khun Yee Fung. Modified from eepic.trm. 43 * clipper@csd.uwo.ca 44 * January 20, 1992 45 * 46 * Bastian Maerkisch 47 * 48 * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net). 49 * 50 */ 51 52/* 53 * This file contains the texdraw terminal driver, intended for use with the 54 * texdraw macro package for LaTeX. This is an alternative to the 55 * latex driver. You need texdraw.sty, and texdraw.tex in the texdraw package. 56 * 57 */ 58#include "driver.h" 59 60#ifdef TERM_REGISTER 61register_term(texdraw) 62#endif 63 64#ifdef TERM_PROTO 65TERM_PUBLIC void TEXDRAW_init(void); 66TERM_PUBLIC void TEXDRAW_options(void); 67TERM_PUBLIC void TEXDRAW_graphics(void); 68TERM_PUBLIC void TEXDRAW_text(void); 69TERM_PUBLIC void TEXDRAW_reset(void); 70TERM_PUBLIC void TEXDRAW_linetype(int linetype); 71TERM_PUBLIC void TEXDRAW_dashtype(int dt, t_dashtype *custom_dash_pattern); 72TERM_PUBLIC void TEXDRAW_linewidth(double linewidth); 73TERM_PUBLIC void TEXDRAW_move(unsigned int x, unsigned int y); 74TERM_PUBLIC void TEXDRAW_pointsize(double size); 75TERM_PUBLIC void TEXDRAW_point(unsigned int x, unsigned int y, int number); 76TERM_PUBLIC void TEXDRAW_vector(unsigned int ux, unsigned int uy); 77TERM_PUBLIC void TEXDRAW_arrow(unsigned int sx, unsigned int sy, 78 unsigned int ex, unsigned int ey, 79 int head); 80TERM_PUBLIC void TEXDRAW_put_text(unsigned int x, unsigned int y, const char str[]); 81TERM_PUBLIC int TEXDRAW_justify_text(enum JUSTIFY mode); 82TERM_PUBLIC int TEXDRAW_text_angle(int ang); 83TERM_PUBLIC void TEXDRAW_set_color(t_colorspec *colorspec); 84TERM_PUBLIC int TEXDRAW_make_palette(t_sm_palette *); 85TERM_PUBLIC void TEXDRAW_set_color(t_colorspec *); 86TERM_PUBLIC void TEXDRAW_fillbox(int style, 87 unsigned int x1, unsigned int y1, 88 unsigned int width, unsigned int height); 89TERM_PUBLIC void TEXDRAW_filled_polygon(int points, gpiPoint *corners); 90 91#define TEXDRAW_PTS_PER_INCH (72.27) 92/* resolution of printer we expect to use */ 93#define DOTS_PER_INCH (300) 94/* dot size in pt */ 95#define TEXDRAW_UNIT (TEXDRAW_PTS_PER_INCH/DOTS_PER_INCH) 96 97/* 5 inches wide by 3 inches high (default) */ 98#define TEXDRAW_XMAX (5*DOTS_PER_INCH) 99#define TEXDRAW_YMAX (3*DOTS_PER_INCH) 100 101#define TEXDRAW_HTIC (5*DOTS_PER_INCH/72) /* (5./TEXDRAW_UNIT) */ 102#define TEXDRAW_VTIC (5*DOTS_PER_INCH/72) /* (5./TEXDRAW_UNIT) */ 103#define TEXDRAW_HCHAR (DOTS_PER_INCH*53/10/72) /* (5.3/TEXDRAW_UNIT) */ 104#define TEXDRAW_VCHAR (DOTS_PER_INCH*11/72) /* (11./TEXDRAW_UNIT) */ 105 106#define GOT_TEXDRAW_PROTO 107#endif 108 109#ifndef TERM_PROTO_ONLY 110#ifdef TERM_BODY 111 112/* terminate any line in progress */ 113static void TEXDRAW_endline(void); 114 115/* determine gray level according to fillstyle */ 116static double TEXDRAW_fill_gray(int style); 117 118static unsigned int TEXDRAW_posx; 119static unsigned int TEXDRAW_posy; 120static enum JUSTIFY TEXDRAW_justify = LEFT; 121static enum JUSTIFY TEXDRAW_last_justify = LEFT; 122static int TEXDRAW_angle = 0; 123static float TEXDRAW_scalefactor = 0.2409; 124static double TEXDRAW_xscale = 1.0, TEXDRAW_yscale = 1.0; 125 126/* for DOTS point style */ 127#define TEXDRAW_TINY_DOT "\\htext{$\\cdot$}" 128 129/* POINTS */ 130#define TEXDRAW_POINT_TYPES 15 /* we supply more point types */ 131 132static const char * TEXDRAW_points[TEXDRAW_POINT_TYPES] = { 133 "\\htext{%s$+$}", 134 "\\htext{%s$\\times$}", 135 "\\htext{%s$\\ast$}", 136 "\\rmove(0 -8)\\htext{%s$\\Box$}", 137 "\\htext{%s$\\blacksquare$}", 138 "\\htext{%s$\\circ$}", 139 "\\htext{%s$\\bullet$}", 140 "\\htext{%s$\\triangle$}", 141 "\\htext{%s$\\blacktriangle$}", 142 "\\htext{%s$\\triangledown$}", 143 "\\htext{%s$\\blacktriangledown$}", 144 "\\htext{%s$\\lozenge$}", 145 "\\htext{%s$\\blacklozenge$}", 146 "\\htext{%s$\\heartsuit$}", 147 "\\htext{%s$\\spadesuit$}", 148}; 149 150/* LINES */ 151#define TEXDRAW_NUMLINES 5 /* number of linetypes below */ 152static const int TEXDRAW_lines[] = { 153 2, /* -2 border */ 154 1, /* -1 axes */ 155 2, /* 0 solid */ 156 2, /* 1 solid */ 157 2, /* 2 solid */ 158}; 159 160#define TEXDRAW_NUMPAT 5 161static const int TEXDRAW_dashpat[][6] = { 162 { 10, 6, 0, 0, 0, 0 }, 163 { 4, 8, 0, 0, 0, 0 }, 164 { 10, 6, 4, 6, 0, 0 }, 165 { 10, 6, 4, 6, 4, 6 }, 166}; 167 168/* The line type selected most recently */ 169static int TEXDRAW_last_type = 0; 170/* current line type */ 171static int TEXDRAW_type; 172/* are we in the middle of a line */ 173static TBOOLEAN TEXDRAW_inline = FALSE; 174/* number of points in line so far */ 175static int TEXDRAW_linecount = 0; 176/* max value for linecount */ 177#define TEXDRAW_LINEMAX 5 178/* linewidth scale factor */ 179static double TEXDRAW_lw; 180static double TEXDRAW_last_lw; 181/* dashtype */ 182static int TEXDRAW_dt; 183 184/* ARROWS */ 185static char TEXDRAW_arrow_type; 186static int TEXDRAW_arrow_length; 187static int TEXDRAW_arrow_width; 188 189/* GRAY LEVEL */ 190static double TEXDRAW_gray; 191static double TEXDRAW_last_gray; 192 193/* OPTIONS */ 194static TBOOLEAN TEXDRAW_standalone = FALSE; 195static TBOOLEAN TEXDRAW_rounded = TRUE; 196static TBOOLEAN TEXDRAW_colortext = FALSE; 197static TBOOLEAN TEXDRAW_psarrows = TRUE; 198static TBOOLEAN TEXDRAW_texpoints = TRUE; 199static size_units TEXDRAW_explicit_units = INCHES; 200static double TEXDRAW_size_x = 5.; 201static double TEXDRAW_size_y = 3.; 202static double TEXDRAW_lw_scale = 1.; 203static double TEXDRAW_ps = 1.; 204static double TEXDRAW_background = 1.; 205 206/* option names */ 207enum TEXDRAW_id { TEXDRAW_DEFAULT, 208 TEXDRAW_SIZE, 209 TEXDRAW_STANDALONE, TEXDRAW_INPUT, 210 TEXDRAW_BLACKTEXT, TEXDRAW_COLORTEXT, 211 TEXDRAW_ROUNDED, TEXDRAW_BUTT, 212 TEXDRAW_LINEWIDTH, TEXDRAW_POINTSCALE, 213 TEXDRAW_PSARROWS, TEXDRAW_GPARROWS, 214 TEXDRAW_TEXPOINTS, TEXDRAW_GPPOINTS, 215 TEXDRAW_BACKGROUND, 216 TEXDRAW_OTHER }; 217 218static struct gen_table TEXDRAW_opts[] = 219{ 220 { "def$ault", TEXDRAW_DEFAULT }, 221 { "size", TEXDRAW_SIZE }, 222 { "stand$alone", TEXDRAW_STANDALONE }, 223 { "inp$ut", TEXDRAW_INPUT }, 224 { "b$lacktext", TEXDRAW_BLACKTEXT }, 225 { "colort$ext", TEXDRAW_COLORTEXT }, 226 { "colourt$ext", TEXDRAW_COLORTEXT }, 227 { "round$ed", TEXDRAW_ROUNDED }, 228 { "butt", TEXDRAW_BUTT }, 229 { "backg$round", TEXDRAW_BACKGROUND }, 230 { "lw", TEXDRAW_LINEWIDTH }, 231 { "linew$idth", TEXDRAW_LINEWIDTH }, 232 { "points$cale", TEXDRAW_POINTSCALE }, 233 { "ps", TEXDRAW_POINTSCALE }, 234 { "psarrows", TEXDRAW_PSARROWS }, 235 { "gparrows", TEXDRAW_GPARROWS }, 236 { "texpoints", TEXDRAW_TEXPOINTS }, 237 { "gppoints", TEXDRAW_GPPOINTS }, 238 { NULL, TEXDRAW_OTHER } 239}; 240 241 242TERM_PUBLIC void 243TEXDRAW_options() 244{ 245 char size_str[80] = ""; 246 int bg; 247 248 while (!END_OF_COMMAND) { 249 switch ((enum TEXDRAW_id) lookup_table(&TEXDRAW_opts[0], c_token)) { 250 case TEXDRAW_DEFAULT: 251 TEXDRAW_standalone = FALSE; 252 TEXDRAW_rounded = TRUE; 253 TEXDRAW_colortext = TRUE; 254 TEXDRAW_psarrows = TRUE; 255 TEXDRAW_texpoints = TRUE; 256 TEXDRAW_lw_scale = TEXDRAW_ps = 1.; 257 TEXDRAW_background = 1.; 258 TEXDRAW_size_x = 5 ; 259 TEXDRAW_size_y = 3.; 260 term->xmax = TEXDRAW_size_x * DOTS_PER_INCH; 261 term->ymax = TEXDRAW_size_y * DOTS_PER_INCH; 262 term->v_char = TEXDRAW_VCHAR; 263 term->v_tic = TEXDRAW_VTIC; 264 break; 265 case TEXDRAW_SIZE: { 266 float width, height; 267 268 c_token++; 269 TEXDRAW_explicit_units = parse_term_size(&width, &height, INCHES); 270 TEXDRAW_size_x = width / gp_resolution; 271 TEXDRAW_size_y = height / gp_resolution; 272 term->xmax = TEXDRAW_size_x * DOTS_PER_INCH; 273 term->ymax = TEXDRAW_size_y * DOTS_PER_INCH; 274 term->v_char = TEXDRAW_VCHAR; 275 term->v_tic = TEXDRAW_VTIC; 276 break; 277 } 278 case TEXDRAW_STANDALONE: 279 TEXDRAW_standalone = TRUE; 280 c_token++; 281 break; 282 case TEXDRAW_INPUT: 283 TEXDRAW_standalone = FALSE; 284 c_token++; 285 break; 286 case TEXDRAW_COLORTEXT: 287 TEXDRAW_colortext = TRUE; 288 c_token++; 289 break; 290 case TEXDRAW_BLACKTEXT: 291 TEXDRAW_colortext = FALSE; 292 c_token++; 293 break; 294 case TEXDRAW_BUTT: 295 TEXDRAW_rounded = FALSE; 296 c_token++; 297 break; 298 case TEXDRAW_ROUNDED: 299 TEXDRAW_rounded = TRUE; 300 c_token++; 301 break; 302 case TEXDRAW_LINEWIDTH: 303 c_token++; 304 TEXDRAW_lw_scale = real_expression(); 305 if (TEXDRAW_lw_scale < 0.0) 306 TEXDRAW_lw_scale = 1.0; 307 break; 308 case TEXDRAW_POINTSCALE: 309 c_token++; 310 TEXDRAW_ps = real_expression(); 311 if (TEXDRAW_ps < 0.0) 312 TEXDRAW_ps = 1.0; 313 break; 314 case TEXDRAW_BACKGROUND: { 315 int background; 316 int red, green, blue; 317 318 c_token++; 319 background = parse_color_name(); 320 red = (double)((background >> 16) & 0xff); 321 green = (double)((background >> 8) & 0xff); 322 blue = (double)( background & 0xff); 323 TEXDRAW_background = (red * 0.30 + green * 0.59 + blue * 0.11) / 255; 324 break; 325 } 326 case TEXDRAW_GPARROWS: 327 c_token++; 328 TEXDRAW_psarrows = FALSE; 329 break; 330 case TEXDRAW_PSARROWS: 331 c_token++; 332 TEXDRAW_psarrows = TRUE; 333 break; 334 case TEXDRAW_GPPOINTS: 335 c_token++; 336 TEXDRAW_texpoints = FALSE; 337 break; 338 case TEXDRAW_TEXPOINTS: 339 c_token++; 340 TEXDRAW_texpoints = TRUE; 341 break; 342 default: 343 int_error(c_token, "Unknown terminal option"); 344 } 345 } 346 347 if (TEXDRAW_explicit_units == INCHES) 348 snprintf(size_str, sizeof(size_str), "size %.2fin, %.2fin", TEXDRAW_size_x, TEXDRAW_size_y); 349 else if (TEXDRAW_explicit_units == CM) 350 snprintf(size_str, sizeof(size_str), "size %.2fcm, %.2fcm", TEXDRAW_size_x * 2.54, TEXDRAW_size_y * 2.54); 351 352 // update terminal option string 353 bg = TEXDRAW_background * 255; 354 snprintf(term_options, MAX_LINE_LEN + 1, 355 "%s linewidth %.1f pointscale %.1f %stext " 356 "background \"#%02x%02x%02x\" " 357 "%sarrows %spoints %s", 358 TEXDRAW_rounded ? "rounded" : "butt", 359 TEXDRAW_lw_scale, TEXDRAW_ps, 360 TEXDRAW_colortext ? "color" : "black", 361 bg, bg, bg, 362 TEXDRAW_psarrows ? "ps" : "gp", 363 TEXDRAW_texpoints ? "tex" : "gp", 364 TEXDRAW_standalone ? "standalone" : "input"); 365} 366 367 368TERM_PUBLIC void 369TEXDRAW_init() 370{ 371 fputs("%% GNUPLOT: LaTeX using TEXDRAW macros\n", gpoutfile); 372 if (TEXDRAW_standalone) { 373 fputs( 374"\\documentclass[a4paper,10pt]{article}\n"\ 375"\\usepackage{texdraw}\n"\ 376"\\usepackage{latexsym}\n"\ 377"\\usepackage{amssymb}\n"\ 378"\\usepackage{xcolor}\n" 379"\\begin{document}\n", 380 gpoutfile); 381 } 382} 383 384 385TERM_PUBLIC void 386TEXDRAW_graphics() 387{ 388 static char tdg1[] = "\ 389\\btexdraw\n\ 390\\ifx\\pathDEFINED\\relax\\else\\let\\pathDEFINED\\relax\n\ 391 \\def\\QtGfr{\\ifx (\\TGre \\let\\YhetT\\cpath\\else\\let\\YhetT\\relax\\fi\\YhetT}\n\ 392 \\def\\path (#1 #2){\\move (#1 #2)\\futurelet\\TGre\\QtGfr}\n\ 393 \\def\\cpath (#1 #2){\\lvec (#1 #2)\\futurelet\\TGre\\QtGfr}\n\ 394\\fi\n\ 395\\drawdim pt\n\ 396\\setunitscale %2.2f\n\ 397\\linewd %d\n\ 398\\textref h:L v:C\n\ 399\\writeps{%d setlinecap} \\writeps{%d setlinejoin}\n"; 400 401 if (TEXDRAW_standalone) 402 fputs("\\begin{figure}\n", gpoutfile); 403 fprintf(gpoutfile, tdg1, 404 TEXDRAW_scalefactor, 405 TEXDRAW_lines[2], 406 TEXDRAW_rounded ? 1 : 0, TEXDRAW_rounded ? 1 : 0 407 ); 408 409 if (TEXDRAW_background == 1.) { 410 /* enforce bounding box */ 411 fprintf(gpoutfile, "\\move (0 0) \\rmove (%d %d)\n", 412 term->xmax, term->ymax); 413 } else { 414 fprintf(gpoutfile, "\\move (0 0) \\rlvec (%d 0) \\rlvec (0 %d) \\rlvec (%d 0) \\ifill f:%0.2f\n", 415 term->xmax, term->ymax, -term->xmax, 416 TEXDRAW_background); 417 } 418 419 TEXDRAW_last_type = 0; 420 TEXDRAW_type = 0; 421 TEXDRAW_posx = TEXDRAW_posy = 0; 422 TEXDRAW_lw = TEXDRAW_last_lw = 1.; 423 TEXDRAW_gray = TEXDRAW_last_gray = 0.; 424 TEXDRAW_arrow_type = 0; 425 TEXDRAW_arrow_length = -1; 426 TEXDRAW_arrow_width = -1; 427 TEXDRAW_justify = TEXDRAW_last_justify = LEFT; 428} 429 430 431TERM_PUBLIC void 432TEXDRAW_text() 433{ 434 TEXDRAW_endline(); 435 // fputs("\\drawbb\n", gpoutfile); 436 fputs("\\etexdraw\n", gpoutfile); 437 if (TEXDRAW_standalone) 438 fputs("\\end{figure}\n\n", gpoutfile); 439} 440 441 442TERM_PUBLIC void 443TEXDRAW_reset() 444{ 445 TEXDRAW_endline(); 446 TEXDRAW_posx = TEXDRAW_posy = 0; 447 448 if (TEXDRAW_standalone) 449 fputs("\\end{document}\n", gpoutfile); 450} 451 452 453TERM_PUBLIC void 454TEXDRAW_linetype(int linetype) 455{ 456 TEXDRAW_endline(); 457 458 if (linetype >= TEXDRAW_NUMLINES - 2) 459 linetype %= (TEXDRAW_NUMLINES - 2); 460 461 TEXDRAW_type = linetype > -2 ? linetype : LT_BLACK; 462 463 if (linetype == LT_AXIS) 464 TEXDRAW_dashtype(DASHTYPE_AXIS, NULL); 465 else 466 TEXDRAW_dashtype(DASHTYPE_SOLID, NULL); 467} 468 469 470TERM_PUBLIC void 471TEXDRAW_dashtype(int dt, t_dashtype *custom_dash_pattern) 472{ 473 TEXDRAW_endline(); 474 475 if (dt == DASHTYPE_SOLID) { 476 dt = 0; 477 } else if (dt == DASHTYPE_AXIS) { 478 dt = 2; 479 } else if (dt > 0) { 480 dt %= TEXDRAW_NUMPAT; 481 } 482 483 if (dt == TEXDRAW_dt) 484 return; 485 486 if (dt == 0) { 487 fputs("\\lpatt ()\n", gpoutfile); 488 TEXDRAW_dt = 0; 489 } else if (dt > 0) { 490 int i; 491 492 fputs("\\lpatt (", gpoutfile); 493 for (i = 0; i < 6; i++) { 494 if (TEXDRAW_dashpat[dt - 1][i] == 0) 495 break; 496 fprintf(gpoutfile, "%d ", (int) (TEXDRAW_dashpat[dt - 1][i] * TEXDRAW_lw)); 497 } 498 fputs(")\n", gpoutfile); 499 TEXDRAW_dt = dt; 500 } else if (dt == DASHTYPE_CUSTOM) { 501 /* not supported (yet) */ 502 } 503} 504 505 506 507TERM_PUBLIC void 508TEXDRAW_linewidth(double linewidth) 509{ 510 TEXDRAW_lw = linewidth * TEXDRAW_lw_scale; 511} 512 513 514TERM_PUBLIC void 515TEXDRAW_move(unsigned int x, unsigned int y) 516{ 517 TEXDRAW_endline(); 518 519 TEXDRAW_posx = x; 520 TEXDRAW_posy = y; 521} 522 523 524TERM_PUBLIC void 525TEXDRAW_pointsize(double size) 526{ 527 // We can only scale gnuplot's native point types 528 term_pointsize = (size >= 0 ? size * TEXDRAW_ps : 1); 529} 530 531 532TERM_PUBLIC void 533TEXDRAW_point(unsigned int x, unsigned int y, int number) 534{ 535 char colorstr[80] = ""; 536 537 TEXDRAW_move(x, y); 538 539 if (!TEXDRAW_texpoints) { 540 do_point(x, y, number); 541 return; 542 } 543 544 /* Print the character defined by 'number'; number < 0 means 545 * to use a dot, otherwise one of the defined points. */ 546 fprintf(gpoutfile, "\\move (%d %d)\n", 547 (int) ((double) x * TEXDRAW_xscale), 548 (int) ((double) y * TEXDRAW_yscale)); 549 if (TEXDRAW_last_justify != CENTRE) { 550 fprintf(gpoutfile, "\\textref h:C v:C "); 551 TEXDRAW_last_justify = CENTRE; 552 } 553 if (TEXDRAW_colortext && TEXDRAW_gray != 0) 554 snprintf(colorstr, sizeof(colorstr), "\\color{black!%d!}", 100 - (int) (TEXDRAW_gray * 100)); 555 if (number < 0) { 556 fprintf(gpoutfile, "%s\n", TEXDRAW_TINY_DOT); 557 } else { 558 fprintf(gpoutfile, TEXDRAW_points[number % TEXDRAW_POINT_TYPES], colorstr); 559 fputc('\n', gpoutfile); 560 } 561} 562 563 564TERM_PUBLIC void 565TEXDRAW_vector(unsigned int ux, unsigned int uy) 566{ 567 if (!TEXDRAW_inline) { 568 TEXDRAW_inline = TRUE; 569 570 /* Start a new line. This depends on line type */ 571 if ((TEXDRAW_type != TEXDRAW_last_type) || (TEXDRAW_last_lw != TEXDRAW_lw)) { 572 if (TEXDRAW_lines[TEXDRAW_type + 2] * TEXDRAW_lw != TEXDRAW_lines[TEXDRAW_last_type + 2] * TEXDRAW_last_lw) 573 fprintf(gpoutfile, "\\linewd %d\n", 574 (int) (TEXDRAW_lines[TEXDRAW_type + 2] * TEXDRAW_lw + 0.5)); 575 TEXDRAW_last_type = TEXDRAW_type; 576 TEXDRAW_last_lw = TEXDRAW_lw; 577 } 578 if (TEXDRAW_gray != TEXDRAW_last_gray) { 579 fprintf(gpoutfile, "\\setgray %0.2f\n", TEXDRAW_gray); 580 TEXDRAW_last_gray = TEXDRAW_gray; 581 } 582 fprintf(gpoutfile, "\\path (%d %d)", 583 (int) ((double) TEXDRAW_posx * TEXDRAW_xscale), 584 (int) ((double) TEXDRAW_posy * TEXDRAW_yscale)); 585 TEXDRAW_linecount = 1; 586 } else { 587 /* Even though we are in middle of a path, 588 * we may want to start a new path command. 589 * If they are too long then latex will choke. 590 */ 591 if (TEXDRAW_linecount++ >= TEXDRAW_LINEMAX) { 592 fputs("\n\\cpath ", gpoutfile); 593 TEXDRAW_linecount = 1; 594 } 595 } 596 fprintf(gpoutfile, "(%d %d)", 597 (int) ((double) ux * TEXDRAW_xscale), 598 (int) ((double) uy * TEXDRAW_yscale)); 599 TEXDRAW_posx = ux; 600 TEXDRAW_posy = uy; 601} 602 603 604static void 605TEXDRAW_endline() 606{ 607 if (TEXDRAW_inline) { 608 putc('\n', gpoutfile); 609 TEXDRAW_inline = FALSE; 610 } 611} 612 613 614TERM_PUBLIC void 615TEXDRAW_arrow( 616 unsigned int sx, unsigned int sy, 617 unsigned int ex, unsigned int ey, 618 int head) 619{ 620 char text; 621 char type = 'T'; // empty triangle 622 // These are the default arrow sizes: 623 int tiplen = (0.16 * 72 / TEXDRAW_scalefactor + 0.5); 624 int width = (0.08 * 72 / TEXDRAW_scalefactor + 0.5); 625 626 // Texdraw cannot only draw vector heads, fall back to built-in code. 627 if (!TEXDRAW_psarrows || (head & HEADS_ONLY)) { 628 do_arrow(sx, sy, ex, ey, head); 629 return; 630 } 631 632 switch (curr_arrow_headfilled) { 633 case AS_NOFILL: 634 type = 'V'; // open V-shape 635 break; 636 case AS_FILLED: 637 case AS_NOBORDER: 638 type = 'F'; // filled triangle 639 break; 640 case AS_EMPTY: 641 type = 'W'; // white filled triangle 642 break; 643 } 644 645 if (curr_arrow_headlength > 0) { 646 width = sin(curr_arrow_headangle * DEG2RAD) * curr_arrow_headlength; 647 tiplen = cos(curr_arrow_headangle * DEG2RAD) * curr_arrow_headlength; 648 if ((curr_arrow_headbackangle - curr_arrow_headangle) <= 15) 649 type = 'V'; // open V-shape 650 } 651 652 if (TEXDRAW_arrow_type != type) { 653 fprintf(gpoutfile, "\\arrowheadtype t:%c\n", type); 654 TEXDRAW_arrow_type = type; 655 } 656 if ((TEXDRAW_arrow_length != tiplen) || (TEXDRAW_arrow_width != width)) { 657 fprintf(gpoutfile, "\\arrowheadsize l:%d w:%d\n", tiplen, width); 658 TEXDRAW_arrow_length = tiplen; 659 TEXDRAW_arrow_width = width; 660 } 661 662 if ((head & BOTH_HEADS) != 0) 663 text = 'a'; // line with arrow 664 else 665 text = 'l'; // simple line 666 667 if ((head & END_HEAD) != 0 || (head & BOTH_HEADS) == 0) { 668 fprintf(gpoutfile, "\\move (%d %d)\\%cvec (%d %d)\n", 669 (int) ((double) sx * TEXDRAW_xscale), 670 (int) ((double) sy * TEXDRAW_yscale), 671 text, 672 (int) ((double) ex * TEXDRAW_xscale), 673 (int) ((double) ey * TEXDRAW_yscale)); 674 } 675 /* draw back-heads by drawing an arrow in the opposite direction */ 676 if ((head & BACKHEAD) != 0) { 677 fprintf(gpoutfile, "\\move (%d %d)\\%cvec (%d %d)\n", 678 (int) ((double) ex * TEXDRAW_xscale), 679 (int) ((double) ey * TEXDRAW_yscale), 680 text, 681 (int) ((double) sx * TEXDRAW_xscale), 682 (int) ((double) sy * TEXDRAW_yscale)); 683 } 684 685 TEXDRAW_posx = ex; 686 TEXDRAW_posy = ey; 687} 688 689 690TERM_PUBLIC void 691TEXDRAW_put_text(unsigned int x, unsigned int y, const char str[]) 692{ 693 char colorstr[80] = ""; 694 TEXDRAW_endline(); 695 696 fprintf(gpoutfile, "\\move (%d %d)", 697 (int) ((double) x * TEXDRAW_xscale), 698 (int) ((double) y * TEXDRAW_yscale)); 699 700 if (TEXDRAW_last_justify != TEXDRAW_justify) { 701 TEXDRAW_last_justify = TEXDRAW_justify; 702 if (TEXDRAW_justify == LEFT) 703 fputs("\\textref h:L v:C ", gpoutfile); 704 else if (TEXDRAW_justify == CENTRE) 705 fputs("\\textref h:C v:C ", gpoutfile); 706 else if (TEXDRAW_justify == RIGHT) 707 fputs("\\textref h:R v:C ", gpoutfile); 708 } 709 710 if (TEXDRAW_colortext && TEXDRAW_gray != 0) 711 snprintf(colorstr, sizeof(colorstr), "\\color{black!%d!}", 100 - (int) (TEXDRAW_gray * 100)); 712 if (TEXDRAW_angle == 0) 713 fprintf(gpoutfile, "\\htext{%s%s}\n", colorstr, str); 714 else if(TEXDRAW_angle == 90) 715 fprintf(gpoutfile, "\\vtext{%s%s}\n", colorstr, str); 716 else 717 fprintf(gpoutfile, "\\rtext td:%d {%s%s}\n", TEXDRAW_angle, colorstr, str); 718} 719 720 721TERM_PUBLIC int 722TEXDRAW_justify_text(enum JUSTIFY mode) 723{ 724 TEXDRAW_justify = mode; 725 return (TRUE); 726} 727 728 729TERM_PUBLIC int 730TEXDRAW_text_angle(int ang) 731{ 732 while (ang < 0) ang += 360; 733 ang %= 360; 734 TEXDRAW_angle = ang; 735 return (TRUE); 736} 737 738 739TERM_PUBLIC int 740TEXDRAW_make_palette(t_sm_palette *palette) 741{ 742 return 0; /* claim continuous colors */ 743} 744 745 746TERM_PUBLIC void 747TEXDRAW_set_color(t_colorspec *colorspec) 748{ 749 /* Users can choose any color as long as it is black. 750 Enables dash patterns. */ 751 switch (colorspec->type) { 752 case TC_FRAC: 753 TEXDRAW_gray = colorspec->value; 754 break; 755 case TC_RGB: { 756 int red, green, blue; 757 758 red = (colorspec->lt >> 16) & 0xff; 759 green = (colorspec->lt >> 8) & 0xff; 760 blue = (colorspec->lt ) & 0xff; 761 TEXDRAW_gray = (red * 0.30 + green * 0.59 + blue * 0.11) / 255; 762 break; 763 } 764 case TC_LT: 765 /* any line type is black for now */ 766 TEXDRAW_gray = 0.; 767 break; 768 default: 769 break; 770 } 771} 772 773 774static double 775TEXDRAW_fill_gray(int style) 776{ 777 double gray = TEXDRAW_gray; 778 int pattern = style >> 4; 779 int frac = style >> 4; 780 static const double TEXDRAW_pat_gray[4] = { 781 1.0, 0.5, 0.8, 0.0 782 }; 783 784 switch (style & 0x0f) { 785 case FS_SOLID: 786 case FS_TRANSPARENT_SOLID: 787 if (frac < 100) 788 gray *= frac / 100.; 789 break; 790 case FS_PATTERN: 791 case FS_TRANSPARENT_PATTERN: 792 gray = TEXDRAW_pat_gray[pattern % 4]; 793 break; 794 case FS_EMPTY: 795 gray = 1.0; 796 break; 797 case FS_DEFAULT: 798 default: 799 break; 800 } 801 return gray; 802} 803 804 805TERM_PUBLIC void 806TEXDRAW_fillbox(int style, 807 unsigned int x1, unsigned int y1, 808 unsigned int width, unsigned int height) 809{ 810 double gray; 811 812 TEXDRAW_endline(); 813 gray = TEXDRAW_fill_gray(style); 814 815 // outline box using relative moves 816 fprintf(gpoutfile, "\\move (%d %d)", x1, y1); 817 fprintf(gpoutfile, "\\rlvec (%d %d)", width, 0); 818 fprintf(gpoutfile, "\\rlvec (%d %d)", 0, height); 819 fprintf(gpoutfile, "\\rlvec (%d %d)", -width, 0); 820 // the polygon is closed automatically by fill 821 fprintf(gpoutfile, "\\ifill f:%0.2f\n", gray); 822} 823 824 825TERM_PUBLIC void 826TEXDRAW_filled_polygon(int points, gpiPoint *corners) 827{ 828 double gray; 829 int i; 830 831 TEXDRAW_endline(); 832 gray = TEXDRAW_fill_gray(corners->style); 833 834 // outline polygon 835 fprintf(gpoutfile, "\\move (%d %d)", corners[0].x, corners[0].y); 836 for (i = 1; i < points; i++) 837 fprintf(gpoutfile, "\\lvec (%d %d)", corners[i].x, corners[i].y); 838 // fill polygon 839 fprintf(gpoutfile, "\\ifill f:%0.2f\n", gray); 840} 841 842#endif /* TERM_BODY */ 843 844#ifdef TERM_TABLE 845 846TERM_TABLE_START(texdraw_driver) 847 "texdraw", 848 "LaTeX texdraw environment", 849 TEXDRAW_XMAX, TEXDRAW_YMAX, TEXDRAW_VCHAR, TEXDRAW_HCHAR, 850 TEXDRAW_VTIC, TEXDRAW_HTIC, TEXDRAW_options, TEXDRAW_init, TEXDRAW_reset, 851 TEXDRAW_text, null_scale, TEXDRAW_graphics, TEXDRAW_move, TEXDRAW_vector, 852 TEXDRAW_linetype, TEXDRAW_put_text, TEXDRAW_text_angle, 853 TEXDRAW_justify_text, TEXDRAW_point, TEXDRAW_arrow, set_font_null, 854 TEXDRAW_pointsize, 855 TERM_IS_LATEX | TERM_LINEWIDTH | TERM_POINTSCALE | TERM_MONOCHROME, 856 0 /*suspend*/, 0 /*resume*/, 857 TEXDRAW_fillbox, 858 TEXDRAW_linewidth, 859#ifdef USE_MOUSE 860 0, 0, 0, 0, 0, 861#endif 862 TEXDRAW_make_palette, 0, 863 TEXDRAW_set_color, 864 TEXDRAW_filled_polygon, 865 0, /* image */ 866 0, 0, 0, /* enhanced text */ 867 0, /* layer */ 868 0, /* path */ 869 0.0, /* scale (unused) */ 870 0, /* hypertext */ 871 0, 872 0, 873 TEXDRAW_dashtype 874TERM_TABLE_END(texdraw_driver) 875 876#undef LAST_TERM 877#define LAST_TERM texdraw_driver 878 879#endif /* TERM_TABLE */ 880 881#endif /* TERM_PROTO_ONLY */ 882 883#ifdef TERM_HELP 884START_HELP(texdraw) 885"1 texdraw", 886"?commands set terminal texdraw", 887"?set terminal texdraw", 888"?set term texdraw", 889"?terminal texdraw", 890"?term texdraw", 891"?texdraw", 892" The `texdraw` terminal driver supports the (La)TeX texdraw environment. It is", 893" intended for use with the texdraw package,", 894" see https://www.ctan.org/tex-archive/graphics/texdraw/ .", 895"", 896" set terminal texdraw", 897" {size <XX>{unit},<YY>{unit}}", 898" {standalone | input}", 899" {blacktext | colortext | colourtext}", 900" {linewidth <lw>} {rounded | butt}", 901" {pointscale <ps>}", 902" {psarrows | gparrows} {texpoints | gppoints}", 903" {background <rgbcolor>}", 904"", 905" Note: Graphics are in grayscale only. Text is always black. Boxes and polygons", 906" are filled using solid gray levels only. Patterns are not available.", 907"", 908" Points, among other things, are drawn using the LaTeX commands \"\\Diamond\" and", 909" \"\\Box\". These commands no longer belong to the LaTeX2e core; they are included", 910" in the latexsym package, which is part of the base distribution and thus part", 911" of any LaTeX implementation. Please do not forget to use this package.", 912" Other point types use symbols from the amssymb package. For compatibility with", 913" plain TeX you need to specify the `gppoints` option.", 914"", 915" `standalone` produces a LaTeX file with possibly multiple plots, ready", 916" to be compiled. The default is `input` to produce a TeX file which can", 917" be included.", 918"", 919" `blacktext` forces all text to be written in black. `colortext` enables", 920" \"colored\" text. The default is `blacktext` and \"color\" means grayscale", 921" really.", 922"", 923" `rounded` sets line caps and line joins to be rounded; `butt` sets butt", 924" caps and mitered joins and is the default.", 925"", 926" `linewidth` and `pointscale` scale the width of lines and the size of point", 927" symbols, respectively. `pointscale`only applies to `gppoints`.", 928"", 929" `psarrows` draws `arrow`s using TeXdraw commands which are shorter but do not", 930" offer all options. `gparrows` selects drawing drawing arrows using gnuplot's", 931" own routine for full functionality instead. Similarly, `texpoints`, and ", 932" `gppoints` select LaTeX symbols or gnuplot's point drawing routines." 933END_HELP(texdraw) 934#endif /* TERM_HELP */ 935