/* Hello, Emacs, this is -*-C-*- * $Id: tkcanvas.trm,v 1.28.8.7 2016/03/07 06:32:34 markisch Exp $ * */ /* GNUPLOT - tkcanvas.trm */ /*[ * Copyright 1990 - 1993, 1998, 2004, 2014 * * Permission to use, copy, and distribute this software and its * documentation for any purpose with or without fee is hereby granted, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. * * Permission to modify the software is granted, but not the right to * distribute the complete modified source code. Modifications are to * be distributed as patches to the released version. Permission to * distribute binaries produced by compiling modified sources is granted, * provided you * 1. distribute the corresponding source modifications from the * released version in the form of a patch file along with the binaries, * 2. add special version identification to distinguish your version * in addition to the base release version number, * 3. provide your name and address as the primary contact for the * support of your modified version, and * 4. retain our contact information in regard to use of the base * software. * Permission to distribute the released version of the source code along * with corresponding source modifications in the form of a patch file is * granted with same provisions 2 through 4 for binary distributions. * * This software is provided "as is" without express or implied warranty * to the extent permitted by applicable law. ]*/ /* * This file is included by ../term.c. * * This terminal driver supports: * Tk canvas widgets under several scripting languages * (currently Tcl, Perl/Tk, Perl/Tkx, Python, Ruby, Rexx) * * AUTHORS and HISTORY: * original dxy.trm by Martin Yii, eln557h@monu3.OZ * Further modified Jan 1990 by Russell Lang, rjl@monu1.cc.monash.oz * * port to the Tk/Tcl canvas widget * D. Jeff Dionne, July 1995 jeff@ryeham.ee.ryerson.ca * Alex Woo, woo@playfair.stanford.edu * * adapted to the new terminal layout by Alex Woo (Sept. 1996) * * extended interactive Tk/Tcl capabilities * Thomas Sefzick, March 1999, t.sefzick@fz-juelich.de * * added the perltk.trm code written by Slaven Rezic . * 'linewidth' and 'justify text' added, ends of plotted lines are now rounded. * Thomas Sefzick, May 1999, t.sefzick@fz-juelich.de * * scale plot to fit into the actual size of the canvas as reported by * the window manager (the canvas itself doesn't report its real size). * Matt Willis, October 1999, mattbwillis@my-deja.com * * cleaned up and generalized in order to accomodate an increasing * number of scripting languages; added support for Python and Ruby. * based on a patch dated October 2002. * Joachim Wuttke, November 2014, jwuttke@users.sourceforge.net * * Add support for Perl/Tkx and Rexx. * Add support for rgb and palette color, filled boxes and polygons, * rotated text, (custom) dashed lines, background colour, closed paths, * rounded or butt line ends, Tk-arrows, optimized drawing of lines, * boxed text and bold and italic text. Add 'size' option to give the * code a hint of proper tic and font sizes. Add 'standalone' option to * create self-contained scripts. Add support for enhanced text and * external images for Tcl only. * Bastian Maerkisch, December 2014, bmaerkisch@web.de * * BUGS or MISSING FEATURES: * - enhanced text only for Tcl * - option to change function name (multiple plots) * - layer actions by adding tags to items * - hypertext and image are missing * - transparency is not possible * - text encoding setting is ignored, we always use the system's default * - The "interactive" mode has several issues: * - The optimised line drawing, which merges adjacent segments into one * path, renders the 'interactive mode' pretty useless. * - It is not (yet) implemented at all for Python/Tkinter and Rexx/Tk. * - Ruby/Tkinter: no support for user_gnuplot_coordinates(). * - gnuplot_xy: * the definition (with 12 input and 4 output coordinates) is clumsy, * and the implementation is unelegant. * - we don't take advantage of object orientation; our Ruby code looks * like an almost literal translation from Tcl (because that's what it is). * - no support for Lua/Tk */ #include "driver.h" #ifdef TERM_REGISTER register_term(tkcanvas) #endif #ifdef TERM_PROTO TERM_PUBLIC void TK_options __PROTO((void)); TERM_PUBLIC void TK_init __PROTO((void)); TERM_PUBLIC void TK_graphics __PROTO((void)); TERM_PUBLIC void TK_text __PROTO((void)); TERM_PUBLIC void TK_linetype __PROTO((int linetype)); TERM_PUBLIC void TK_move __PROTO((unsigned int x, unsigned int y)); TERM_PUBLIC void TK_vector __PROTO((unsigned int x, unsigned int y)); TERM_PUBLIC int TK_text_angle(int ang); TERM_PUBLIC void TK_put_text(unsigned int x, unsigned int y, const char *str); TERM_PUBLIC void TK_reset(void); TERM_PUBLIC int TK_justify_text(enum JUSTIFY); TERM_PUBLIC void TK_point(unsigned int, unsigned int, int); TERM_PUBLIC void TK_arrow(unsigned int, unsigned int, unsigned int, unsigned int, int); TERM_PUBLIC int TK_set_font(const char *font); TERM_PUBLIC void TK_enhanced_open(char * fontname, double fontsize, double base, TBOOLEAN widthflag, TBOOLEAN showflag, int overprint); TERM_PUBLIC void TK_enhanced_flush(void); TERM_PUBLIC void TK_linewidth(double linewidth); TERM_PUBLIC int TK_make_palette(t_sm_palette *palette); TERM_PUBLIC void TK_color(t_colorspec *colorspec); TERM_PUBLIC void TK_fillbox(int style, unsigned int x, unsigned int y, unsigned int w, unsigned int h); TERM_PUBLIC void TK_filled_polygon(int points, gpiPoint *corners); #ifdef WRITE_PNG_IMAGE TERM_PUBLIC void TK_image(unsigned m, unsigned n, coordval *image, gpiPoint *corner, t_imagecolor color_mode); #endif TERM_PUBLIC void TK_dashtype(int dt, t_dashtype *custom_dash_pattern); #ifdef EAM_BOXED_TEXT TERM_PUBLIC void TK_boxed_text(unsigned int x, unsigned int y, int option); #endif /* nominal canvas size */ #define TK_XMAX 1000 #define TK_YMAX 1000 /* char size and tic sizes in pixels */ #define TK_VCHAR 14 /* height of characters */ #define TK_HCHAR 6 /* width of characters including spacing */ #define TK_VTIC 8 #define TK_HTIC 8 #endif /* TERM_PROTO */ #ifndef TERM_PROTO_ONLY #ifdef TERM_BODY /* FIXME HBB 20000725: This needs to be fixed. As is, this driver causes * the terminal layer to depend on several other core modules. This is a * design bug. "term" is supposed as 'frontier' layer: it should not be * dependent on any other code inside gnuplot */ #include "axis.h" /* axis_array */ #include "gadgets.h" /* is_3d_plot, plot_bounds */ /* text, font */ static int tk_angle = 0; static char tk_anchor[7] = "w"; static enum JUSTIFY tk_justify; static TBOOLEAN tk_next_text_use_font = FALSE; static TBOOLEAN tk_boxed = FALSE; /* enhanced text */ static TBOOLEAN tk_enhanced_opened_string = FALSE; static TBOOLEAN tk_enhanced_show = FALSE; static int tk_enhanced_base = 0; static int tk_enhanced_overprint = 0; static TBOOLEAN tk_enhanced_widthflag = FALSE; /* vectors, polygons, paths */ static TBOOLEAN tk_rounded = FALSE; static double tk_linewidth = 1.0; static int tk_lastx = 0; static int tk_lasty = 0; static TBOOLEAN tk_in_path = FALSE; static int * tk_path_x = NULL; static int * tk_path_y = NULL; static int tk_maxpath = 0; static int tk_polygon_points = 0; static char tk_dashpattern[3*DASHPATTERN_LENGTH]; static const char * tk_dashtypes[] = { "", "1 1", "", "3 1", "2 2", "3 1 1 1", "3 1 1 1 1 1" }; /* color */ static const char * tk_colors[] = { "black", "gray", "red", "green", "blue", "magenta", "cyan", "brown" }; static char tk_color[20] = "black"; static char tk_background[20] = ""; static char * tk_background_opt = NULL; /* other options */ static TBOOLEAN tk_interactive = FALSE; static TBOOLEAN tk_standalone = FALSE; static int tk_width = 800; static int tk_height = 600; /* images */ static int tk_image_counter = 0; /* prototypes of local functions */ static void TK_put_noenhanced_text(unsigned int x, unsigned int y, const char *str); static void TK_put_enhanced_text(unsigned int x, unsigned int y, const char *str); static void TK_rectangle(int x1, int y1, int x2, int y2, char * color, char * stipple); static void TK_add_path_point(int x, int y); /* add a new point to current path or line */ static void TK_flush_line(); /* finish a poly-line */ enum TK_id { /* languages first (order is important as it is used as index!) */ TK_LANG_TCL=0, TK_LANG_PERL, TK_LANG_PYTHON, TK_LANG_RUBY, TK_LANG_REXX, TK_LANG_PERLTKX, TK_LANG_MAX, /* other options */ TK_INTERACTIVE, TK_STANDALONE, TK_INPUT, TK_NOROTTEXT, TK_ROTTEXT, TK_BACKGROUND, TK_NOBACKGROUND, TK_ROUNDED, TK_BUTT, TK_SIZE, TK_ENHANCED, TK_NOENHANCED, TK_PIXELS, TK_EXTERNALIMAGES, TK_INLINEIMAGES, TK_OTHER }; static int tk_script_language = TK_LANG_TCL; static char *tk_script_languages[TK_LANG_MAX] = { "tcl", "perl", "python", "ruby", "rexx", "perltkx" }; static struct gen_table TK_opts[] = { { "t$cl", TK_LANG_TCL }, { "pe$rltk", TK_LANG_PERL }, { "perltkx", TK_LANG_PERLTKX }, { "tkx", TK_LANG_PERLTKX }, { "py$thontkinter", TK_LANG_PYTHON }, { "ru$bytkinter", TK_LANG_RUBY }, { "re$xxtk", TK_LANG_REXX }, { "int$eractive", TK_INTERACTIVE }, { "inp$ut", TK_INPUT }, { "stand$alone", TK_STANDALONE }, { "nor$ottext", TK_NOROTTEXT }, { "rot$text", TK_ROTTEXT }, { "backg$round", TK_BACKGROUND }, { "noback$ground", TK_NOBACKGROUND }, { "round$ed", TK_ROUNDED }, { "butt", TK_BUTT }, { "size", TK_SIZE }, { "enh$anced", TK_ENHANCED }, { "noenh$anced", TK_NOENHANCED }, { "pix$els", TK_PIXELS }, { "inl$ineimages", TK_INLINEIMAGES }, { "ext$ernalimages", TK_EXTERNALIMAGES }, { NULL, TK_OTHER } }; TERM_PUBLIC void TK_options() { int cmd; tk_interactive = FALSE; while (!END_OF_COMMAND) { switch (cmd = lookup_table(&TK_opts[0], c_token)) { case TK_LANG_TCL: case TK_LANG_PERL: case TK_LANG_PERLTKX: case TK_LANG_RUBY: case TK_LANG_PYTHON: case TK_LANG_REXX: tk_script_language = cmd; c_token++; break; case TK_INTERACTIVE: tk_interactive = TRUE; c_token++; break; case TK_INPUT: tk_standalone = FALSE; c_token++; break; case TK_STANDALONE: tk_standalone = TRUE; c_token++; break; case TK_NOROTTEXT: term->text_angle = null_text_angle; c_token++; break; case TK_ROTTEXT: term->text_angle = TK_text_angle; c_token++; break; case TK_BACKGROUND: { long rgb; int red, green, blue; c_token++; rgb = parse_color_name(); free(tk_background_opt); tk_background_opt = NULL; m_capture(&tk_background_opt, c_token-1, c_token); red = (rgb >> 16) & 0xff; green = (rgb >> 8) & 0xff; blue = (rgb ) & 0xff; snprintf(tk_background, sizeof(tk_background), "#%02x%02x%02x", red, green, blue); break; } case TK_NOBACKGROUND: tk_background[0] = NUL; free(tk_background_opt); tk_background_opt = NULL; c_token++; break; case TK_ROUNDED: tk_rounded = TRUE; c_token++; break; case TK_BUTT: tk_rounded = FALSE; c_token++; break; case TK_SIZE: { c_token++; if (END_OF_COMMAND) int_error(c_token, "size requires 'width,heigth'"); tk_width = real_expression(); if (!equals(c_token++, ",")) int_error(c_token, "size requires 'width,heigth'"); tk_height = real_expression(); if (tk_width < 1 || tk_height < 1) int_error(c_token, "size is out of range"); break; } case TK_ENHANCED: c_token++; term->flags |= TERM_ENHANCED_TEXT; break; case TK_NOENHANCED: c_token++; term->flags &= ~TERM_ENHANCED_TEXT; break; case TK_PIXELS: c_token++; term->image = NULL; break; case TK_INLINEIMAGES: case TK_EXTERNALIMAGES: c_token++; #ifdef WRITE_PNG_IMAGE term->image = TK_image; #endif break; case TK_OTHER: default: c_token++; int_error(c_token, "unknown option"); break; } } /* calculate the proper tic sizes and character size */ term->h_char = TK_HCHAR * TK_XMAX / (double) tk_width + 0.5; term->h_tic = TK_HTIC * TK_XMAX / (double) tk_width + 0.5; term->v_char = TK_VCHAR * TK_YMAX / (double) tk_height + 0.5; term->v_tic = TK_VTIC * TK_YMAX / (double) tk_height + 0.5; /* FIXME: image support only available for Tcl */ if ((term->image != NULL) && (tk_script_language != TK_LANG_TCL)) term->image = NULL; /* FIXME: enhanced text only available for Tcl */ if ((term->flags & TERM_ENHANCED_TEXT) && (tk_script_language != TK_LANG_TCL)) term->flags &= ~TERM_ENHANCED_TEXT; sprintf(term_options, "%s%s %s %s%s %s %s %s size %d,%d", tk_script_languages[tk_script_language], tk_interactive ? " interactive" : "", tk_standalone ? "standalone" : "input", (tk_background[0] == NUL) ? "nobackground " : "background ", (tk_background[0] == NUL) ? "" : tk_background_opt, tk_rounded ? "rounded" : "butt", term->text_angle == null_text_angle ? "norottext" : "rottext", term->image == NULL ? "pixels" : "externalimages", tk_width, tk_height); } TERM_PUBLIC void TK_init() { tk_image_counter = 0; } static char *tk_standalone_init[TK_LANG_MAX] = { /* Tcl */ "canvas .c -width %d -height %d\n" "pack .c\n" "gnuplot .c\n\n", /* Perl */ "use Tk;\n" "my $top = MainWindow->new;\n" "my $c = $top->Canvas(-width => %d, -height => %d)->pack;\n" "gnuplot($c);\n" "MainLoop;\n", /* Python */ "from tkinter import *\n" "from tkinter import font\n" "root = Tk()\n" "c = Canvas(root, width=%d, height=%d)\n" "c.pack()\n" "gnuplot(c)\n" "root.mainloop()\n", /* Ruby */ "require 'tk'\n" "root = TkRoot.new { title 'Ruby/Tk' }\n" "c = TkCanvas.new(root, 'width'=>%d, 'height'=>%d) { pack { } }\n" "gnuplot(c)\n" "Tk.mainloop\n", /* Rexx */ "/**/\n" "call RxFuncAdd 'TkLoadFuncs', 'rexxtk', 'TkLoadFuncs'\n" "call TkLoadFuncs\n" "cv = TkCanvas('.c', '-width', %d, '-height', %d)\n" "call TkPack cv\n" "call gnuplot cv\n" "do forever\n" " interpret 'call' TkWait()\n" "end\n" "return 0\n\n" "exit:\nquit:\n" "call TkDropFuncs\n" "exit 0\n", /* Perl/Tkx */ "use Tkx;\n" "my $top = Tkx::widget->new(\".\");\n" "my $c = $top->new_tk__canvas(-width => %d, -height => %d);\n" "$c->g_pack;\n" "gnuplot($c);\n" "Tkx::MainLoop();\n" }; static char *tk_init_gnuplot[TK_LANG_MAX] = { /* Tcl */ "proc %s cv {\n" " $cv delete all\n" " set cmx [expr\\\n" " [winfo width $cv]-2*[$cv cget -border]" "-2*[$cv cget -highlightthickness]]\n" " if {$cmx <= 1} {set cmx [$cv cget -width]}\n" " set cmy [expr\\\n" " [winfo height $cv]-2*[$cv cget -border]" "-2*[$cv cget -highlightthickness]]\n" " if {$cmy <= 1} {set cmy [$cv cget -height]}\n", /* Perl */ "sub %s {\n" " my($cv) = @_;\n" " $cv->delete('all');\n" " my $cmx = $cv->width - 2 * $cv->cget(-border)\n" " - 2 * $cv->cget(-highlightthickness);\n" " if ($cmx <= 1) {\n" " $cmx = ($cv->cget(-width));\n" " }\n" " my $cmy = $cv->height - 2 * $cv->cget(-border)\n" " - 2 * $cv->cget(-highlightthickness);\n" " if ($cmy <= 1) {\n" " $cmy = ($cv->cget(-height));\n" " }\n", /* Python */ "def %s (cv):\n" "\tcv.delete('all')\n" "\tcmdelta = 2*(int(cv.cget('border'))+" "int(cv.cget('highlightthickness')))\n" "\tcmx = int(cv.cget('width'))-cmdelta\n" "\tif (cmx<=1):\n\t\tcmx = int(cv.cget('width'))\n" "\tcmy = int(cv.cget('height'))-cmdelta\n" "\tif (cmy<=1):\n\t\tcmy = int(cv.cget('height'))\n" "", /* Ruby (below, we NEED the blank in "- 2" !)*/ "def %s(cv)\n" " cv.delete('all')\n" " cmx = cv.width - 2*cv.cget('border') - 2*cv.cget('highlightthickness')\n" " cmx = cvcget.width if (cmx <= 1)\n" " cmy = cv.height - 2*cv.cget('border') - 2*cv.cget('highlightthickness')\n" " cmy = cvcget.height if (cmy <= 1)\n" "", /* Rexx */ "/**/\n" "call %s arg(1)\n" "return 0\n\n" "%s: procedure\n" " cv = arg(1)\n" " call TkCanvasDelete cv,'all'\n" " cmx = TkCget(cv,'-width') - 2*TkCget(cv,'-border') - 2*TkCget(cv,'-highlightthickness')\n" " if cmx <= 1 then; cmx = TkCget(cv,'-width')\n" " cmy = TkCget(cv,'-height') - 2*TkCget(cv,'-border') - 2*TkCget(cv,'-highlightthickness')\n" " if cmy <= 1 then; cmy = TkCget(cv,'-height')\n" "\n", /* Perl/Tkx */ "sub %s {\n" " my($cv) = @_;\n" " $cv->delete('all');\n" " my $cmx = $cv->get_width - 2 * $cv->cget(-border)\n" " - 2 * $cv->cget(-highlightthickness);\n" " if ($cmx <= 1) {\n" " $cmx = ($cv->cget(-width));\n" " }\n" " my $cmy = $cv->get_height - 2 * $cv->cget(-border)\n" " - 2 * $cv->cget(-highlightthickness);\n" " if ($cmy <= 1) {\n" " $cmy = ($cv->cget(-height));\n" " }\n" }; static char *tk_set_background[TK_LANG_MAX] = { /* Tcl */ " $cv configure -bg %s\n", /* Perl */ " $cv->configure(-bg => q{%s});\n", /* Python */ "\tcv.configure(bg='%s')\n", /* Ruby */ " cv.configure('bg'=>'%s')\n", /* Rexx */ " call TkConfigure cv, '-bg', '%s'\n", /* Perl/Tkx */ " $cv->configure(-bg => q{%s});\n" }; TERM_PUBLIC void TK_graphics() { /* * Here we start the definition of the `gnuplot` procedure. * The resulting script code takes the actual width and height * of the defined canvas and scales the plot to fit. * You can tune the output for a particular size of the canvas by * using the `size` option. */ char * tk_function = "gnuplot"; /* Reset to start of output file. If the user mistakenly tries to */ /* plot again into the same file, it will overwrite the original */ /* rather than corrupting it. */ fseek(gpoutfile, 0L, SEEK_SET); fflush(gpoutfile); ftruncate(fileno(gpoutfile), (off_t)0); if (!tk_standalone && ((tk_script_language == TK_LANG_PERL) || (tk_script_language == TK_LANG_PERLTKX))) tk_function = ""; if (tk_standalone && (tk_script_language == TK_LANG_REXX)) fprintf(gpoutfile, tk_standalone_init[tk_script_language], tk_width, tk_height); fprintf(gpoutfile, tk_init_gnuplot[tk_script_language], tk_function, tk_function); tk_angle = tk_lastx = tk_lasty = 0; safe_strncpy(tk_color, tk_colors[0], sizeof(tk_color)); /* set background */ if (tk_background[0] != NUL) { //TK_rectangle(0, 0, TK_XMAX, TK_YMAX, tk_background, ""); fprintf(gpoutfile, tk_set_background[tk_script_language], tk_background); } } TERM_PUBLIC void TK_reset() { free(tk_path_x); free(tk_path_y); tk_path_x = tk_path_y = NULL; tk_polygon_points = tk_maxpath = 0; } TERM_PUBLIC void TK_linetype(int linetype) { t_colorspec colorspec; colorspec.type = TC_LT; colorspec.lt = linetype; TK_color(&colorspec); TK_dashtype(DASHTYPE_SOLID, NULL); } TERM_PUBLIC int TK_make_palette(t_sm_palette *palette) { return 0; /* we can do RGB colors */ } TERM_PUBLIC void TK_color(t_colorspec *colorspec) { char tmp_color[20]; safe_strncpy(tmp_color, tk_color, sizeof(tmp_color)); switch (colorspec->type) { case TC_LT: { int linetype = colorspec->lt; char * color = NULL; if (linetype == LT_BACKGROUND) color = (tk_background[0] != NUL) ? tk_background : "white"; if (linetype == LT_NODRAW) color = ""; if (color == NULL) { if (linetype < LT_BLACK) linetype = LT_BLACK; color = (char *) tk_colors[(linetype + 2) % 8]; } safe_strncpy(tmp_color, color, sizeof(tmp_color)); break; } case TC_FRAC: { rgb255_color rgb255; /* Immediately translate palette index to RGB colour */ rgb255maxcolors_from_gray(colorspec->value, &rgb255); snprintf(tmp_color, sizeof(tmp_color), "#%02x%02x%02x", rgb255.r, rgb255.g, rgb255.b); break; } case TC_RGB: { int red, green, blue; red = (colorspec->lt >> 16) & 0xff; green = (colorspec->lt >> 8) & 0xff; blue = (colorspec->lt) & 0xff; snprintf(tmp_color, sizeof(tk_color), "#%02x%02x%02x", red, green, blue); break; } } if (strcmp(tk_color, tmp_color) != 0) { TK_flush_line(); safe_strncpy(tk_color, tmp_color, sizeof(tk_color)); } } TERM_PUBLIC void TK_linewidth(double linewidth) { if (fabs(tk_linewidth - linewidth) > FLT_EPSILON) TK_flush_line(); tk_linewidth = linewidth; } TERM_PUBLIC void TK_dashtype(int dt, t_dashtype *custom_dash_pattern) { int i; char tmp_dashpattern[3*DASHPATTERN_LENGTH]; TBOOLEAN preserve = FALSE; if (dt >= 0) { // {PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT}; dt %= 5; dt += 2; strcpy(tmp_dashpattern, tk_dashtypes[dt]); } else if (dt == DASHTYPE_SOLID) { tmp_dashpattern[0] = NUL; } else if (dt == DASHTYPE_AXIS) { strcpy(tmp_dashpattern, tk_dashtypes[1]); } else if (dt == DASHTYPE_CUSTOM) { if (custom_dash_pattern->dstring[0] != NUL) { /* Tk and gnuplot support the very same dash pattern syntax. */ strncpy(tmp_dashpattern, custom_dash_pattern->dstring, sizeof(tmp_dashpattern)-1); preserve = TRUE; /* do not change pattern */ } else { tmp_dashpattern[0] = NUL; for (i = 0; (i < DASHPATTERN_LENGTH/2) && (fabs(custom_dash_pattern->pattern[2*i]) > FLT_EPSILON); i++) { char buf[32]; snprintf(buf, sizeof(buf), "%d %d ", (int) (custom_dash_pattern->pattern[2*i] * tk_linewidth), (int) (custom_dash_pattern->pattern[2*i + 1] * tk_linewidth)); strncat(tmp_dashpattern, buf, sizeof(tmp_dashpattern) - strlen(tmp_dashpattern)-1); } tmp_dashpattern[strlen(tmp_dashpattern) - 1] = NUL; } } if ((tk_script_language == TK_LANG_PYTHON) && !preserve) { for (i = 0; tmp_dashpattern[i] != NUL; i++) if (tmp_dashpattern[i] == ' ') tmp_dashpattern[i] = ','; } if (strcmp(tk_dashpattern, tmp_dashpattern) != 0) { TK_flush_line(); safe_strncpy(tk_dashpattern, tmp_dashpattern, sizeof(tk_dashpattern)); } } TERM_PUBLIC void TK_move(unsigned int x, unsigned int y) { /* terminate current path if we move to a disconnected position */ if (tk_polygon_points > 0) { if ((tk_path_x[tk_polygon_points - 1] != x) || (tk_path_y[tk_polygon_points - 1] != TK_YMAX - y)) TK_flush_line(); else return; } TK_add_path_point(x, TK_YMAX - y); tk_lastx = x; tk_lasty = TK_YMAX - y; } /* FIXME HBB 20000725: should use AXIS_UNDO_LOG() macro... */ #define TK_REAL_VALUE(value,axis) \ (axis_array[axis].log) \ ? pow(axis_array[axis].base, axis_array[axis].min \ + value*(axis_array[axis].max-axis_array[axis].min)) \ : axis_array[axis].min \ + value*(axis_array[axis].max-axis_array[axis].min) #define TK_X_VALUE(value) \ (double)(value-plot_bounds.xleft)/(double)(plot_bounds.xright-plot_bounds.xleft) #define TK_Y_VALUE(value) \ (double)((TK_YMAX-value)-plot_bounds.ybot)/(double)(plot_bounds.ytop-plot_bounds.ybot) static char *tk_bind_init[TK_LANG_MAX] = { /* Tcl */ " $cv bind [\n ", /* Perl */ " $cv->bind(\n ", /* Python */ "", /* Ruby */ "", /* Rexx */ "", /* Perl/Tkx */ " $cv->bind(\n " }; static char *tk_line_segment_start[TK_LANG_MAX] = { /* Tcl */ " $cv create line\\\n", /* Perl */ " $cv->createLine(\n", /* Python */ "\tcv.create_line(\\\n", /* Ruby */ " cl=TkcLine.new(cv,\\\n", /* Rexx */ " obj = TkCanvasLine(cv, ,\n", /* Perl/Tkx */ " $cv->create_line(\n" }; static char *tk_poly_point[TK_LANG_MAX] = { /* Tcl */ " [expr $cmx*%d/1000] [expr $cmy*%d/1000]\\\n", /* Perl */ " $cmx*%d/1000, $cmy*%d/1000,\n", /* Python */ "\t\tcmx*%d/1000, cmy*%d/1000,\\\n", /* Ruby */ " cmx*%d/1000, cmy*%d/1000,\\\n", /* Rexx */ "\tcmx*%d/1000, cmy*%d/1000, ,\n", /* Perl/Tkx */ " $cmx*%d/1000, $cmy*%d/1000,\n" }; static char *tk_line_segment_opt[TK_LANG_MAX] = { /* Tcl */ " -fill {%s} -width %.1f -capstyle %s -joinstyle %s", /* Perl */ " -fill => q{%s}, -width => %.1f, -capstyle => q{%s}, -joinstyle => q{%s}", /* Python */ "\t\tfill='%s', width=%.1f, capstyle='%s', joinstyle='%s'", /* Ruby */ " 'fill'=>'%s', 'width'=>%.1f, 'capstyle'=>'%s', 'joinstyle'=>'%s'", /* Rexx */ "\t'-fill', '%s', '-width', '%.1f', '-capstyle', '%s', '-joinstyle', '%s'", /* Perl/Tkx */ " -fill => q{%s}, -width => %.1f, -capstyle => q{%s}, -joinstyle => q{%s}", }; static char *tk_line_segment_dash[TK_LANG_MAX] = { /* Tcl */ " -dash {%s}", /* Perl */ ", -dash => q{%s}", /* Python */ ", dash=(%s)", /* Ruby */ ", 'dash'=>'%s'", /* Rexx */ ", '-dash', '%s'", /* Perl/Tkx */ ", -dash => q{%s}" }; static char *tk_line_segment_end[TK_LANG_MAX] = { /* Tcl */ "\n", /* Perl */ ")", /* Python */ ")\n", /* Ruby */ ")\n", /* Rexx */ ")\n", /* Perl/Tkx */ ")" }; static char *tk_bind_main[TK_LANG_MAX] = { /* Tcl */ " ]