/* Hello, Emacs, this is -*-C-*- * $Id: tkcanvas.trm,v 1.28 2006/08/27 22:10:46 sfeam Exp $ * */ /* GNUPLOT - tkcanvas.trm */ /*[ * Copyright 1990 - 1993, 1998, 2004 * * 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/Tcl canvas widgets * * AUTHORS - original dxy.trm * 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 * * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net). * */ /* * 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 , * the variable 'tk_perl' switches between tcl/tk and perltk code. * '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 */ #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 void TK_put_text __PROTO((unsigned int x, unsigned int y, const char *str)); TERM_PUBLIC void TK_reset __PROTO((void)); TERM_PUBLIC int TK_justify_text __PROTO((enum JUSTIFY)); TERM_PUBLIC int TK_set_font __PROTO((const char *font)); TERM_PUBLIC void TK_linewidth __PROTO((double linewidth)); #define TK_XMAX 1000 #define TK_YMAX 1000 #define TK_XLAST (TK_XMAX - 1) #define TK_YLAST (TK_XMAX - 1) #define TK_VCHAR (25) /* double actual height of characters */ #define TK_HCHAR (16) /* actual width including spacing */ #define TK_VTIC (18) #define TK_HTIC (18) #endif /* TERM_PROTO */ #ifndef TERM_PROTO_ONLY #ifdef TERM_BODY /* axis.c */ /* FIXME HBB 20000725: "Never use extern in a source file". This needs * to be fixed. As is, this driver causes the terminal layer to * depend on several other core modules. The lack of proper #include's * partly hides this, but it's still a design bug. "term" is supposed * a 'frontier' layer: it should not be dependant on any other code * inside gnuplot */ extern AXIS axis_array[]; /* command.c */ extern TBOOLEAN is_3d_plot; /* static int tk_angle = 0; unused, for now */ static int tk_lastx; static int tk_lasty; static int tk_color = 0; static char tk_anchor[7] = "w"; static double tk_linewidth = 1.0; static int tk_perl = 0; static int tk_interactive = 0; static const char *tk_colors[] = { "black", "gray", "red", "blue", "green", "brown", "magenta", "cyan" }; enum TK_id { TK_PERLTK, TK_INTERACTIVE, TK_OTHER }; static struct gen_table TK_opts[] = { { "p$erltk", TK_PERLTK }, { "i$nteractive", TK_INTERACTIVE }, { NULL, TK_OTHER } }; TERM_PUBLIC void TK_options() { tk_perl = 0; tk_interactive = 0; while (!END_OF_COMMAND) { switch(lookup_table(&TK_opts[0],c_token)) { case TK_PERLTK: tk_perl = 1; c_token++; break; case TK_INTERACTIVE: tk_interactive = 1; c_token++; break; case TK_OTHER: default: c_token++; break; } } sprintf(term_options, "%s %s", tk_perl ? "perltk" : "", tk_interactive ? "interactive" : ""); } TERM_PUBLIC void TK_init() { } TERM_PUBLIC void TK_graphics() { /* * the resulting tcl or perl code takes the actual width and height * of the defined canvas and scales the plot to fit. * => NOTE: this makes 'set size' useless !!! * unless the original width and height is taken into account * by some tcl or perl code, that's why the 'gnuplot_plotarea' and * 'gnuplot_axisranges' procedures are supplied. */ if (tk_perl) { fputs("\ sub {\n\ my($can) = @_;\n\ $can->delete('all');\n\ my $cmx = $can->width - 2 * $can->cget(-border) - 2 * $can->cget(-highlightthickness);\n\ if ($cmx <= 1) {\n$cmx = ($can->cget(-width));\n}\n\ my $cmy = $can->height - 2 * $can->cget(-border) - 2 * $can->cget(-highlightthickness);\n\ if ($cmy <= 1) {\n$cmy = ($can->cget(-height));\n}\n", gpoutfile); } else { fputs("\ proc gnuplot can {\n\ $can delete all\n\ set cmx [expr [winfo width $can]-2*[$can cget -border]-2*[$can cget -highlightthickness]]\n\ if {$cmx <= 1} {set cmx [$can cget -width]}\n\ set cmy [expr [winfo height $can]-2*[$can cget -border]-2*[$can cget -highlightthickness]]\n\ if {$cmy <= 1} {set cmy [$can cget -height]}\n", gpoutfile); } tk_lastx = tk_lasty = tk_color = 0; } TERM_PUBLIC void TK_reset() { } TERM_PUBLIC void TK_linetype(int linetype) { if (linetype < -2) linetype = LT_BLACK; tk_color = (linetype + 2) & 7; } TERM_PUBLIC void TK_linewidth(double linewidth) { tk_linewidth = linewidth; } TERM_PUBLIC void TK_move(unsigned int x, unsigned int y) { tk_lastx = x; tk_lasty = 1000 - 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) TERM_PUBLIC void TK_vector(unsigned int x, unsigned int y) { /* * this is the 1st part of the wrapper around the 'create line' command * used to bind some actions to a line segment: * bind { * normal create line command * } gnuplot_xy(some coordinates) */ if (tk_interactive && !is_3d_plot) { if (tk_perl) fprintf(gpoutfile, "$can->bind("); else fprintf(gpoutfile, "$can bind [\n"); } /* * end of 1st part of wrapper */ y = 1000 - y; /* * here is the basic well-known command for plotting a line segment */ if (tk_perl) { fprintf(gpoutfile,"\ $can->createLine(\ $cmx * %d / 1000, \ $cmy * %d / 1000, \ $cmx * %d / 1000, \ $cmy * %d / 1000, -fill => q{%s}, -width => %f, -capstyle => q{round})", tk_lastx, tk_lasty, x, y, tk_colors[tk_color], tk_linewidth); } else { fprintf(gpoutfile,"\ $can create line \ [expr $cmx * %d /1000] \ [expr $cmy * %d /1000] \ [expr $cmx * %d /1000] \ [expr $cmy * %d /1000] -fill %s -width %f -capstyle round\n", tk_lastx, tk_lasty, x, y, tk_colors[tk_color], tk_linewidth); } /* * this is the 2nd part of the wrapper around the 'create line' * command it generates a mechanism which calls 'gnuplot_xy' for * the line segment pointed to by the mouse cursor when a mouse * button is pressed */ if (tk_interactive && !is_3d_plot) { if (tk_perl) { /* Ev('W') not needed here, supplied anyhow, WHY ??? */ fprintf(gpoutfile,"\ , '