1/* Hello, Emacs, this is -*-C-*- */
2
3/* GNUPLOT - win.trm */
4
5/*[
6 * Copyright 1992 - 1993, 1998, 2004
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 *
37 * AUTHORS
38 *
39 *   Gnuplot for Windows:
40 *       Maurice Castro, Russell Lang
41 *
42 *   Current maintainer:
43 *       Bastian Maerkisch
44 *
45 */
46
47
48/* This file implements the terminal and printer display for gnuplot  */
49/* under Microsoft Windows.                                           */
50/*                                                                    */
51/* The modifications to allow Gnuplot to run under Windows were made  */
52/* by Maurice Castro (maurice@bruce.cs.monash.edu.au)                 */
53/* and Russell Lang (rjl@monu1.cc.monash.edu.au)         19 Nov 1992  */
54/*                                                                    */
55
56/* Edit this file with tabstop=4 (vi :se ts=4)                        */
57
58/*
59 * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
60 */
61
62#include "driver.h"
63
64#ifdef TERM_REGISTER
65register_term(windows)
66#endif
67
68#ifdef TERM_PROTO
69TERM_PUBLIC void WIN_options(void);
70TERM_PUBLIC void WIN_init(void);
71TERM_PUBLIC void WIN_reset(void);
72TERM_PUBLIC void WIN_text(void);
73TERM_PUBLIC void WIN_graphics(void);
74TERM_PUBLIC void WIN_move(unsigned int x, unsigned int y);
75TERM_PUBLIC void WIN_vector(unsigned int x, unsigned int y);
76TERM_PUBLIC void WIN_linetype(int lt);
77TERM_PUBLIC void WIN_dashtype(int type, t_dashtype *custom_dash_pattern);
78TERM_PUBLIC void WIN_put_text(unsigned int x, unsigned int y, const char *str);
79TERM_PUBLIC int WIN_justify_text(enum JUSTIFY mode);
80TERM_PUBLIC int WIN_text_angle(int ang);
81TERM_PUBLIC void WIN_point(unsigned int x, unsigned int y, int number);
82TERM_PUBLIC void WIN_resume(void);
83TERM_PUBLIC void WIN_set_pointsize(double);
84TERM_PUBLIC void WIN_linewidth(double linewidth);
85#ifdef USE_MOUSE
86TERM_PUBLIC void WIN_set_ruler(int, int);
87TERM_PUBLIC void WIN_set_cursor(int, int, int);
88TERM_PUBLIC void WIN_put_tmptext(int, const char str[]);
89TERM_PUBLIC void WIN_set_clipboard(const char[]);
90# ifdef WGP_CONSOLE
91TERM_PUBLIC int WIN_waitforinput(int);
92# endif
93#endif
94TERM_PUBLIC int WIN_make_palette(t_sm_palette *palette);
95TERM_PUBLIC void WIN_set_color(t_colorspec *);
96TERM_PUBLIC void WIN_filled_polygon(int points, gpiPoint *corners);
97TERM_PUBLIC void WIN_boxfill(int, unsigned int, unsigned int, unsigned int, unsigned int);
98TERM_PUBLIC int WIN_set_font(const char *font);
99TERM_PUBLIC void WIN_enhanced_open(char * fontname, double fontsize,
100				double base, TBOOLEAN widthflag, TBOOLEAN showflag, int overprint);
101TERM_PUBLIC void WIN_enhanced_flush(void);
102TERM_PUBLIC void WIN_image(unsigned int, unsigned int, coordval *, gpiPoint *, t_imagecolor);
103TERM_PUBLIC void WIN_layer(t_termlayer syncpoint);
104TERM_PUBLIC void WIN_hypertext(int type, const char * text);
105TERM_PUBLIC void WIN_modify_plots(unsigned int operations, int plotno);
106
107/* Initialization values - guess now, scale later */
108#define WIN_XMAX (24000)
109#define WIN_YMAX (18000)
110#define WIN_HCHAR (WIN_XMAX/75)
111#define WIN_VCHAR (WIN_YMAX/25)
112#define WIN_HTIC (WIN_XMAX/160)
113#define WIN_VTIC WIN_HTIC
114#endif /* TERM_PROTO */
115
116#ifndef TERM_PROTO_ONLY
117#ifdef TERM_BODY
118
119#include <windows.h>
120#include <tchar.h>
121#include <wchar.h>
122#include "win/winmain.h"
123
124
125/* Interface routines - create list of actions for Windows */
126
127enum WIN_id { WIN_DEFAULT, WIN_MONOCHROME, WIN_COLOR, WIN_GTITLE,
128	      WIN_ENHANCED, WIN_NOENHANCED, WIN_FONT, WIN_SIZE, WIN_WSIZE,
129	      WIN_POSITION, WIN_CLOSE, WIN_BACKGROUND,
130	      WIN_FONTSCALE, WIN_LINEWIDTH, WIN_POINTSCALE,
131	      WIN_SOLID, WIN_DASHED, WIN_ROUND, WIN_BUTT,
132	      WIN_DOCKED, WIN_STANDALONE, WIN_LAYOUT,
133	      WIN_OTHER };
134
135static struct gen_table WIN_opts[] =
136{
137    { "d$efault", WIN_DEFAULT },
138    { "c$olor", WIN_COLOR },
139    { "c$olour", WIN_COLOR },
140    { "m$onochrome", WIN_MONOCHROME },
141    { "backg$round", WIN_BACKGROUND },
142    { "solid", WIN_SOLID },
143    { "dash$ed", WIN_DASHED },
144    { "round$ed", WIN_ROUND },
145    { "butt", WIN_BUTT },
146    { "enh$anced", WIN_ENHANCED },
147    { "noenh$anced", WIN_NOENHANCED },
148    { "font", WIN_FONT },
149    { "fonts$cale", WIN_FONTSCALE },
150    { "linewidth", WIN_LINEWIDTH },
151    { "lw", WIN_LINEWIDTH },
152    { "pointscale", WIN_POINTSCALE},
153    { "ps", WIN_POINTSCALE},
154    { "ti$tle", WIN_GTITLE },
155    { "siz$e", WIN_SIZE },
156    { "ws$ize", WIN_WSIZE },
157    { "pos$ition", WIN_POSITION },
158    { "cl$ose", WIN_CLOSE },
159    { "dock$ed", WIN_DOCKED },
160    { "standalone", WIN_STANDALONE },
161    { "lay$out", WIN_LAYOUT },
162    { NULL, WIN_OTHER }
163};
164
165typedef struct {
166	unsigned n;
167	unsigned max;
168	POINT * point;
169} path_points;
170
171static int WIN_last_linetype = LT_NODRAW; /* HBB 20000813: linetype caching */
172termentry * WIN_term = NULL;
173TCHAR WIN_inifontname[MAXFONTNAME] = TEXT(WINFONT);
174int WIN_inifontsize = WINFONTSIZE;
175static path_points WIN_poly = {0, 0, NULL};
176
177static void WIN_add_path_point(path_points * poly, int x, int y);
178static void WIN_flush_line(path_points * poly);
179static TBOOLEAN WIN_docked = FALSE;  /* docked window option is "sticky" */
180
181
182static void
183WIN_add_path_point(path_points * poly, int x, int y)
184{
185	/* Enlarge size of array of polygon points */
186	if (poly->n >= poly->max) {
187		poly->max += 10;
188		poly->point = (POINT *) gp_realloc(poly->point, poly->max * sizeof(POINT), "points");
189	}
190	/* Store point */
191	poly->point[poly->n].x = x;
192	poly->point[poly->n].y = y;
193	poly->n++;
194	FPRINTF((stderr, "new polygon/polyline point: %i %i\n", x, y));
195}
196
197
198static void
199WIN_flush_line(path_points * poly)
200{
201	if (poly) {
202		if (poly->n > 1)
203			GraphOpSize(graphwin, W_polyline, poly->n, 0, (void *) poly->point, poly->n * sizeof(POINT));
204		if (poly->n > 0) {
205			/* Save last path point in case there's a vector command without preceding move. */
206			poly->point[0].x = poly->point[poly->n - 1].x;
207			poly->point[0].y = poly->point[poly->n - 1].y;
208			/* Reset counter */
209			poly->n = 0;
210		}
211	}
212}
213
214
215TERM_PUBLIC void
216WIN_options()
217{
218	char *s;
219	TBOOLEAN set_font = FALSE, set_fontsize = FALSE;
220	TBOOLEAN set_title = FALSE, set_close = FALSE;
221	TBOOLEAN set_dashed = FALSE, set_color = FALSE;
222	TBOOLEAN set_background = FALSE, set_fontscale = FALSE;
223	TBOOLEAN set_linewidth = FALSE, set_size = FALSE;
224	TBOOLEAN set_position = FALSE, set_number = FALSE;
225	TBOOLEAN set_wsize = FALSE, set_rounded = FALSE;
226	TBOOLEAN set_docked = FALSE;
227#ifndef WGP_CONSOLE
228	TBOOLEAN set_layout = FALSE;
229#endif
230	TBOOLEAN set_pointscale = FALSE;
231	TBOOLEAN color, dashed, rounded;
232	COLORREF background;
233	double fontscale, linewidth;
234	double pointscale;
235	int win_x = 0;
236	int win_y = 0;
237	int win_width = 0;
238	int win_height = 0;
239	char * title;
240	int fontsize;
241	char fontname[MAXFONTNAME];
242	int window_number;
243	unsigned dock_cols, dock_rows;
244
245	while (!END_OF_COMMAND) {
246		switch (lookup_table(&WIN_opts[0], c_token)) {
247		case WIN_DEFAULT:
248			color = TRUE;
249			dashed = FALSE;
250			rounded = FALSE;
251#ifdef UNICODE
252			WideCharToMultiByte(CP_ACP, 0, WIN_inifontname, -1, fontname, MAXFONTNAME, 0, 0);
253#else
254			strcpy(fontname, WIN_inifontname);
255#endif
256			fontsize = WIN_inifontsize;
257			fontscale = linewidth = pointscale = 1;
258			set_color = set_dashed = TRUE;
259			set_font = set_fontsize = TRUE;
260			set_fontscale = set_linewidth = set_pointscale = TRUE;
261			set_rounded = TRUE;
262			c_token++;
263			break;
264		case WIN_COLOR:
265			c_token++;
266			color = TRUE;
267			set_color = TRUE;
268			break;
269		case WIN_MONOCHROME:
270			c_token++;
271			color = FALSE;
272			set_color = TRUE;
273			break;
274		case WIN_BACKGROUND: {
275			int color;
276			c_token++;
277			color = parse_color_name();
278			/* TODO: save original background color and color string,
279			   add background color to status string
280			*/
281			background  =
282				RGB(((color >> 16) & 0xff), ((color >> 8) & 0xff), (color & 0xff));
283			set_background = TRUE;
284			break;
285		}
286		case WIN_ENHANCED:
287			c_token++;
288			term->flags |= TERM_ENHANCED_TEXT;
289			break;
290		case WIN_NOENHANCED:
291			c_token++;
292			term->flags &= ~TERM_ENHANCED_TEXT;
293			break;
294		case WIN_FONTSCALE: {
295			c_token++;
296			fontscale = real_expression();
297			if (fontscale <= 0) fontscale = 1.;
298			set_fontscale = TRUE;
299			break;
300		}
301		case WIN_LINEWIDTH: {
302			c_token++;
303			linewidth = real_expression();
304			if (linewidth <= 0) linewidth = 1.;
305			set_linewidth = TRUE;
306			break;
307		}
308		case WIN_POINTSCALE:
309			c_token++;
310			pointscale = real_expression();
311			if (pointscale <= 0.0) pointscale = 1.;
312			set_pointscale = TRUE;
313			break;
314		case WIN_SOLID:
315			c_token++;
316			dashed = FALSE;
317			set_dashed = TRUE;
318			break;
319		case WIN_DASHED:
320			c_token++;
321			dashed = TRUE;
322			set_dashed = TRUE;
323			break;
324		case WIN_BUTT:
325			c_token++;
326			rounded = FALSE;
327			set_rounded = TRUE;
328			break;
329		case WIN_ROUND:
330			c_token++;
331			rounded = TRUE;
332			set_rounded = TRUE;
333			break;
334		case WIN_SIZE: {
335		        double insize; /* shige 2019-02-27 for size 0 */
336			c_token++;
337			if (set_wsize)
338				int_error(c_token, "conflicting size options");
339			if (END_OF_COMMAND)
340				int_error(c_token,"size requires 'width,heigth'");
341			if ((insize = real_expression()) >= 1)
342				win_width = insize;
343			else
344				int_error(c_token, "size is out of range");
345			if (!equals(c_token++,","))
346				int_error(c_token,"size requires 'width,heigth'");
347			if ((insize = real_expression()) >= 1)
348				win_height = insize;
349			else
350				int_error(c_token, "size is out of range");
351			set_size = TRUE;
352			break;
353		}
354		case WIN_WSIZE: {
355			c_token++;
356			if (set_size)
357				int_error(c_token, "conflicting size options");
358			if (END_OF_COMMAND)
359				int_error(c_token,"windowsize requires 'width,heigth'");
360			win_width = real_expression();
361			if (!equals(c_token++,","))
362				int_error(c_token,"windowsize requires 'width,heigth'");
363			win_height = real_expression();
364			if (win_width < 1 || win_height < 1)
365				int_error(c_token, "windowsize canvas size is out of range");
366			set_wsize = TRUE;
367			break;
368		}
369		case WIN_POSITION: {
370			c_token++;
371			if (END_OF_COMMAND)
372				int_error(c_token,"position requires 'x,y'");
373			win_x = real_expression();
374			if (!equals(c_token++,","))
375				int_error(c_token,"position requires 'x,y'");
376			win_y = real_expression();
377			if (win_x < 1 || win_y < 1)
378				int_error(c_token, "position is out of range");
379			set_position = TRUE;
380			break;
381		}
382		case WIN_GTITLE:
383			c_token++;
384			title = try_to_get_string();
385			if (title == NULL)
386				int_error(c_token, "expecting string argument");
387			if (strcmp(title, "") == 0)
388				title = NULL;
389			set_title = TRUE;
390			break;
391		case WIN_CLOSE:
392			c_token++;
393			set_close = TRUE;
394			break;
395		case WIN_FONT:
396			c_token++;
397			/* Code copied from ps.trm and modified for windows terminal */
398			if ((s = try_to_get_string())) {
399				char *comma;
400				if (set_font)
401					int_error(c_token,
402						  "extraneous argument in set terminal %s",
403						  term->name);
404				comma = strrchr(s,',');
405				if (comma && (1 == sscanf(comma + 1, "%i", &fontsize))) {
406					set_fontsize = TRUE;
407					*comma = '\0';
408				}
409				if (*s) {
410					set_font = TRUE;
411					safe_strncpy(fontname, s, MAXFONTNAME);
412					free(s);
413				}
414			} else {
415				if (set_fontsize)
416					int_error(c_token,
417						  "extraneous argument in set terminal %s",
418						  term->name);
419				set_fontsize = TRUE;
420				fontsize = int_expression();
421			}
422			break;
423		case WIN_DOCKED:
424			c_token++;
425			if (!graphwin->bDocked && GraphHasWindow(graphwin))
426				int_error(c_token, "Cannot change the mode of an open window.");
427			if (persist_cl) {
428				fprintf(stderr, "Warning: cannot use docked graphs in persist mode\n");
429			} else {
430				set_docked = TRUE;
431				WIN_docked = TRUE;
432			}
433			break;
434		case WIN_STANDALONE:
435			c_token++;
436			if (graphwin->bDocked && GraphHasWindow(graphwin))
437				int_error(c_token, "Cannot change the mode of an open window.");
438			set_docked = TRUE;
439			WIN_docked = FALSE;
440			break;
441		case WIN_LAYOUT:
442			c_token++;
443			dock_rows = int_expression();
444			if (END_OF_COMMAND || !equals(c_token, ","))
445				int_error(c_token, "expecting ', <num_cols>'");
446			if (dock_rows == 0) {
447				dock_rows = 1;
448				fprintf(stderr, "Warning: layout requires at least one row.\n");
449			}
450			c_token++;
451			if (END_OF_COMMAND)
452				int_error(c_token, "expecting <num_cols>");
453			dock_cols = int_expression();
454			if (dock_cols == 0) {
455				dock_cols = 1;
456				fprintf(stderr, "Warning: layout requires at least one column.\n");
457			}
458#ifndef WGP_CONSOLE
459			set_layout = TRUE;
460#endif
461			break;
462		case WIN_OTHER:
463		default:
464			window_number = int_expression();
465			set_number = TRUE;
466			break;
467		}
468	}
469
470	/* change window? */
471	if (set_number) {
472		char status[100];
473		LPGW lpgw = listgraphs;
474		while ((lpgw->Id != window_number) && (lpgw->next))
475			lpgw = lpgw->next;
476		if (lpgw->Id != window_number) {
477			/* create new window */
478			lpgw->next = calloc(1, sizeof(GW));
479			lpgw = lpgw->next;
480			lpgw->Id = window_number;
481			lpgw->bDocked = WIN_docked; /* "sticky" default */
482		}
483#ifdef USE_MOUSE
484		/* set status line of previous graph window */
485		sprintf(status, "(inactive, window number %i)", graphwin->Id);
486		Graph_put_tmptext(graphwin, 0, status);
487		/* reset status text */
488		Graph_put_tmptext(lpgw, 0, "");
489#endif
490		graphwin = lpgw;
491	}
492
493	/* apply settings */
494	GraphInitStruct(graphwin);
495	if (set_color) {
496		graphwin->color = color;
497		/* Note: We no longer set TERM_MONOCHROME here, since colors
498		and grayscale conversion are fully handled by drawgraph() */
499		if (!set_dashed)
500			graphwin->dashed = !color;
501	}
502	if (set_dashed)
503		graphwin->dashed = dashed;
504	if (set_rounded)
505		graphwin->rounded = rounded;
506	if (set_background)
507		graphwin->background = background;
508	if (set_fontscale)
509		graphwin->fontscale = fontscale;
510	if (set_linewidth)
511		graphwin->linewidth = linewidth;
512	if (set_pointscale)
513		graphwin->pointscale = pointscale;
514	if (set_size || set_wsize) {
515		graphwin->Size.x = win_width;
516		graphwin->Size.y = win_height;
517	}
518#ifdef WGP_CONSOLE
519	if (set_docked && WIN_docked)
520		WIN_docked = FALSE; /* silently ignore docked option for console mode gnuplot */
521#endif
522	if (!WIN_docked) {
523		if (set_docked)
524			graphwin->bDocked = WIN_docked;
525		if (set_size) {
526			graphwin->Canvas.x = win_width;
527			graphwin->Canvas.y = win_height;
528		}
529		if (set_wsize) {
530			graphwin->Canvas.x = 0;
531			graphwin->Canvas.y = 0;
532		}
533		if (set_position) {
534			graphwin->Origin.x = win_x;
535			graphwin->Origin.y = win_y;
536		}
537	} else {
538		if (set_docked)
539			graphwin->bDocked = WIN_docked;
540	}
541#ifndef WGP_CONSOLE
542	if (set_layout) {
543		textwin.nDockRows = dock_rows;
544		textwin.nDockCols = dock_cols;
545	}
546#endif
547	if (set_title) {
548		free (graphwin->Title);
549#ifdef UNICODE
550		graphwin->Title = (title) ?  UnicodeText(title, encoding) : _tcsdup(WINGRAPHTITLE);
551#else
552		graphwin->Title = (title) ?  title : strdup(WINGRAPHTITLE);
553#endif
554		GraphChangeTitle(graphwin);
555	}
556	if (set_fontsize)
557		graphwin->deffontsize = graphwin->fontsize = fontsize;
558	if (set_font) {
559#ifdef UNICODE
560		LPWSTR wfontname = UnicodeText(fontname, encoding);
561		wcscpy(graphwin->fontname, wfontname);
562		wcscpy(graphwin->deffontname, wfontname);
563		free(wfontname);
564#else
565		strcpy(graphwin->fontname, fontname);
566		strcpy(graphwin->deffontname, fontname);
567#endif
568	}
569	/* font initialization */
570	WIN_set_font(NULL);
571
572	WIN_update_options();
573
574	if (set_close) {
575		win_close_terminal_window(graphwin);
576		return;
577	}
578
579#ifndef WGP_CONSOLE
580	/* update text window */
581	if (set_layout) {
582		DockedUpdateLayout(&textwin);
583	}
584#endif
585
586	/* update graph window */
587	if ((set_position || set_size || set_wsize) && GraphHasWindow(graphwin))
588		GraphUpdateWindowPosSize(graphwin);
589	if (GraphHasWindow(graphwin) && IsIconic(graphwin->hWndGraph))
590		ShowWindow(graphwin->hWndGraph, SW_SHOWNORMAL);
591	GraphRedraw(graphwin);
592}
593
594
595void
596WIN_update_options()
597{
598	TBOOLEAN set_font = FALSE, set_fontsize = FALSE;
599
600	/* update term_options */
601	sprintf(term_options, "%i %s %s %s %s %s",
602		graphwin->Id,
603		graphwin->color ? "color" : "monochrome",
604		graphwin->dashed ? "dashed" : "solid",
605		graphwin->rounded ? "rounded" : "butt",
606		term->flags & TERM_ENHANCED_TEXT ? "enhanced" : "noenhanced",
607		graphwin->bDocked ? "docked" : "standalone");
608
609#ifndef WGP_CONSOLE
610	if (graphwin->bDocked) {
611		char buf[128];
612		sprintf(buf, " layout %i,%i", textwin.nDockRows, textwin.nDockCols);
613		strcat(term_options, buf);
614	}
615#endif
616
617	set_fontsize = (graphwin->deffontsize != WIN_inifontsize);
618	set_font = (_tcscmp(graphwin->deffontname, WIN_inifontname) != 0);
619	if (set_font || set_fontsize) {
620		char * fontstring = (char *) gp_alloc(_tcslen(graphwin->deffontname) + 24, "win font");
621		if (!set_fontsize) {
622			sprintf(fontstring, " font \"" TCHARFMT "\"", graphwin->deffontname);
623		} else {
624			sprintf(fontstring, " font \"" TCHARFMT ", %d\"",
625				set_font ? graphwin->deffontname : TEXT(""), graphwin->deffontsize);
626		}
627		strcat(term_options, fontstring);
628		free(fontstring);
629	}
630
631	if (graphwin->background != RGB(255, 255, 255))
632		sprintf(&(term_options[strlen(term_options)]),
633			" background \"#%0x%0x%0x\"", GetRValue(graphwin->background),
634			GetGValue(graphwin->background), GetBValue(graphwin->background));
635
636	if (graphwin->fontscale != 1)
637		sprintf(&(term_options[strlen(term_options)]),
638			" fontscale %.1f", graphwin->fontscale);
639
640	if (graphwin->linewidth != 1)
641		sprintf(&(term_options[strlen(term_options)]),
642			" linewidth %.1f", graphwin->linewidth);
643
644	if (graphwin->pointscale != 1)
645		sprintf(&(term_options[strlen(term_options)]),
646			" pointscale %.1f", graphwin->pointscale);
647
648	if (!graphwin->bDocked) {
649		if (graphwin->Canvas.x != 0)
650			sprintf(&(term_options[strlen(term_options)]),
651				" size %li,%li", graphwin->Canvas.x, graphwin->Canvas.y);
652		else if (graphwin->Size.x != CW_USEDEFAULT)
653			sprintf(&(term_options[strlen(term_options)]),
654				" wsize %li,%li", graphwin->Size.x, graphwin->Size.y);
655	}
656}
657
658
659TERM_PUBLIC void
660WIN_init()
661{
662	if (!graphwin->hWndGraph) {
663		graphwin->xmax = WIN_XMAX;
664		graphwin->ymax = WIN_YMAX;
665		graphwin->htic = WIN_HTIC;
666		graphwin->vtic = WIN_VTIC;
667		GraphInit(graphwin);
668	}
669	WIN_last_linetype = LT_NODRAW;	/* HBB 20000813: linetype caching */
670	WIN_term = term;
671}
672
673
674TERM_PUBLIC void
675WIN_reset()
676{
677}
678
679
680TERM_PUBLIC void
681WIN_text()
682{
683	WIN_flush_line(&WIN_poly);
684	GraphEnd(graphwin);
685}
686
687
688TERM_PUBLIC void
689WIN_graphics()
690{
691	GraphStart(graphwin, pointsize);
692	/* Fix up the text size if the user has resized the window. */
693	term->h_char = graphwin->hchar;
694	term->v_char = graphwin->vchar;
695	term->h_tic = graphwin->htic;
696	term->v_tic = graphwin->vtic;
697	WIN_last_linetype = LT_NODRAW;		/* HBB 20000813: linetype caching */
698
699	/* Save current text encoding */
700	GraphOp(graphwin, W_text_encoding, encoding, 0, NULL);
701}
702
703
704TERM_PUBLIC void
705WIN_move(unsigned int x, unsigned int y)
706{
707	/* terminate current path only if we move to a disconnected position */
708	if ((WIN_poly.n > 0) &&
709		((WIN_poly.point[WIN_poly.n - 1].x != x) ||
710		 (WIN_poly.point[WIN_poly.n - 1].y != y))) {
711			WIN_flush_line(&WIN_poly);
712	}
713	WIN_add_path_point(&WIN_poly, x, y);
714}
715
716
717TERM_PUBLIC void
718WIN_vector(unsigned int x, unsigned int y)
719{
720	if ((WIN_poly.n == 0) ||
721	    (WIN_poly.point[WIN_poly.n - 1].x != x) ||
722	    (WIN_poly.point[WIN_poly.n - 1].y != y)) {
723		if (WIN_poly.n == 0) {
724			/* vector command without preceding move: e.g. in "with line lc variable" */
725			/* Coordinates were saved with last flush already. */
726			WIN_poly.n++;
727		}
728		WIN_add_path_point(&WIN_poly, x, y);
729	}
730}
731
732
733TERM_PUBLIC void
734WIN_linetype(int lt)
735{
736	if (lt != WIN_last_linetype) {
737		WIN_flush_line(&WIN_poly);
738
739		GraphOp(graphwin, W_line_type, lt, 0, NULL);
740		WIN_last_linetype = lt;
741	}
742}
743
744
745TERM_PUBLIC void
746WIN_dashtype(int dt, t_dashtype *custom_dash_pattern)
747{
748	WIN_flush_line(&WIN_poly);
749
750	GraphOpSize(graphwin, W_dash_type, dt, 0, (char *) custom_dash_pattern, sizeof(t_dashtype));
751}
752
753
754TERM_PUBLIC void
755WIN_put_text(unsigned int x, unsigned int y, const char *str)
756{
757	WIN_flush_line(&WIN_poly);
758
759	if ((str == NULL) || !strlen(str))
760		return;
761
762	/* If no enhanced text processing is needed, we can use the plain  */
763	/* vanilla put_text() routine instead of this fancy recursive one. */
764	if (!(term->flags & TERM_ENHANCED_TEXT) || ignore_enhanced_text || (!strpbrk(str, "{}^_@&~") && !contains_unicode(str)))
765		GraphOp(graphwin, W_put_text, x, y, str);
766	else
767		GraphOp(graphwin, W_enhanced_text, x, y, str);
768}
769
770
771TERM_PUBLIC int
772WIN_justify_text(enum JUSTIFY mode)
773{
774	GraphOp(graphwin, W_justify, mode, 0, NULL);
775	return (TRUE);
776}
777
778
779TERM_PUBLIC int
780WIN_text_angle(int ang)
781{
782	if (graphwin->rotate)
783		GraphOp(graphwin, W_text_angle, ang, 0, NULL);
784	return graphwin->rotate;
785}
786
787
788TERM_PUBLIC void
789WIN_point(unsigned int x, unsigned int y, int number)
790{
791	WIN_flush_line(&WIN_poly);
792
793	/* draw point shapes later to save memory */
794	/* HBB 20010411: secure against pointtype -1 or lower */
795	if (number < -1)
796		number = -1;		/* refuse nonsense values */
797	if (number >= 0)
798		number %= WIN_POINT_TYPES;
799	number += 1;
800	GraphOp(graphwin, W_dot + number, x, y, NULL);
801}
802
803
804TERM_PUBLIC void
805WIN_resume()
806{
807	GraphResume(graphwin);
808}
809
810
811TERM_PUBLIC void
812WIN_set_pointsize(double s)
813{
814	if (s < 0) s = 1;
815	/* Pass the scale as a scaled-up integer. */
816	GraphOp(graphwin, W_pointsize, (int) 100 * s, 0, NULL);
817}
818
819
820TERM_PUBLIC void
821WIN_linewidth(double linewidth)
822{
823	// TODO: line width caching
824	WIN_flush_line(&WIN_poly);
825
826	WIN_last_linetype = LT_NODRAW;        /* invalidate cached linetype */
827	GraphOp(graphwin, W_line_width, (int) 100 * linewidth, 0, NULL);
828}
829
830
831#ifdef USE_MOUSE
832
833/* Implemented by Petr Mikulik, February 2001 --- the best Windows solutions
834 * come from OS/2 :-))
835 */
836
837TERM_PUBLIC void
838WIN_put_tmptext(int i, const char str[])
839{
840	Graph_put_tmptext(graphwin, i, str);
841}
842
843
844TERM_PUBLIC void
845WIN_set_ruler(int x, int y)
846{
847	Graph_set_ruler(graphwin, x, y);
848}
849
850
851TERM_PUBLIC void
852WIN_set_cursor(int c, int x, int y)
853{
854	Graph_set_cursor(graphwin, c, x, y);
855}
856
857
858TERM_PUBLIC void
859WIN_set_clipboard(const char s[])
860{
861	Graph_set_clipboard(graphwin, s);
862}
863
864
865#ifdef WGP_CONSOLE
866
867TERM_PUBLIC int
868WIN_waitforinput(int options)
869{
870	/* Not required: message handling already done elsewhere. */
871	if (options == TERM_ONLY_CHECK_MOUSING)
872		return NUL;
873
874	return ConsoleGetch();
875}
876
877#endif /* WGP_CONSOLE */
878
879#endif /* USE_MOUSE */
880
881
882/* Note: this used to be a verbatim copy of PM_image (pm.trm) with only minor changes */
883
884TERM_PUBLIC void
885WIN_image(unsigned int M, unsigned int N, coordval *image,
886	  gpiPoint *corner, t_imagecolor color_mode)
887{
888	PBYTE rgb_image;
889	unsigned int image_size;
890	unsigned int pad_bytes;
891
892	WIN_flush_line(&WIN_poly);
893
894	/* BM: IC_PALETTE, IC_RGB and IC_RGBA images are converted to a format
895	   suitable for Windows:
896	    - sequence of lines is reversed
897	    - each line starts at a 4 byte boundary
898	    - 24bits RGB  for IC_PALETTE and IC_RGB
899	    - 32bits RGBA for IC_RGBA
900	*/
901	if ((color_mode == IC_PALETTE) || (color_mode == IC_RGB)) {
902		pad_bytes = (4 - (3 * M) % 4) % 4; /* scan lines start on ULONG boundaries */
903		image_size = (3 * M + pad_bytes) * N;
904	} else if (color_mode == IC_RGBA) {
905		pad_bytes = 0;
906		image_size = M * N * 4;
907	} else {
908		int_warn(NO_CARET, "Unknown color mode in WIN_image");
909		return;
910	}
911	rgb_image = (PBYTE) gp_alloc(image_size, "WIN RGB image");
912
913	if (color_mode == IC_PALETTE) {
914		unsigned int x, y;
915
916		rgb_image += N * (3 * M + pad_bytes);
917		for (y=0; y<N; y++) {
918			rgb_image -= 3 * M + pad_bytes;
919			for (x=0; x<M; x++) {
920				rgb255_color rgb255;
921				rgb255maxcolors_from_gray(*image++, &rgb255);
922				*(rgb_image++) = rgb255.b;
923				*(rgb_image++) = rgb255.g;
924				*(rgb_image++) = rgb255.r;
925			}
926			rgb_image -= 3 * M;
927		}
928	} else if (color_mode == IC_RGB) {
929		unsigned int x, y;
930
931		rgb_image += N * (3 * M + pad_bytes);
932		for (y=0; y<N; y++) {
933			rgb_image -= 3 * M + pad_bytes;
934			for (x=0; x<M; x++) {
935				rgb255_color rgb255;
936				rgb255.r = (BYTE) (*image++ * 255 + 0.5);
937				rgb255.g = (BYTE) (*image++ * 255 + 0.5);
938				rgb255.b = (BYTE) (*image++ * 255 + 0.5);
939				*(rgb_image++) = rgb255.b;
940				*(rgb_image++) = rgb255.g;
941				*(rgb_image++) = rgb255.r;
942			}
943			rgb_image -= 3 * M;
944		}
945	} else if (color_mode == IC_RGBA) {
946		unsigned int x, y;
947
948		rgb_image += M * N * 4;
949		for (y=0; y<N; y++) {
950			rgb_image -= 4 * M;
951			for (x=0; x<M; x++) {
952				coordval red, green ,blue, alpha;
953				red   = *image++; /* RGB is [0:1] */
954				green = *image++;
955				blue  = *image++;
956				alpha = *image++; /* BUT alpha is [0:255] */
957				*(rgb_image++) = (BYTE)(blue  * alpha);
958				*(rgb_image++) = (BYTE)(green * alpha);
959				*(rgb_image++) = (BYTE)(red   * alpha);
960				*(rgb_image++) = (BYTE)(alpha);
961			}
962			rgb_image -= 4 * M;
963		}
964	}
965
966	/* squeeze all the information into the buffer */
967	if ((color_mode == IC_PALETTE) || (color_mode == IC_RGB) || (color_mode == IC_RGBA)) {
968		GraphOp(graphwin, W_image, color_mode,  0, NULL);
969		GraphOp(graphwin, W_image, corner[0].x, corner[0].y, NULL);
970		GraphOp(graphwin, W_image, corner[1].x, corner[1].y, NULL);
971		GraphOp(graphwin, W_image, corner[2].x, corner[2].y, NULL);
972		GraphOp(graphwin, W_image, corner[3].x, corner[3].y, NULL);
973		/* GraphOp() cannot be used here since the image might
974		   contain char(0), so use  GraphOpSize() instead */
975		GraphOpSize(graphwin, W_image, M, N, (LPCSTR)rgb_image, image_size);
976	}
977
978	free(rgb_image);
979}
980
981
982TERM_PUBLIC int
983WIN_make_palette(t_sm_palette *palette)
984{
985	/* Win can do continuous colors. However, we round them only to WIN_PAL_COLORS levels
986	    * in order to pass an integer to GraphOp; it also reasonably limits
987	    * the number of colors if "copy to clipboard" is used.
988	    * EAM: Would it be better to use the approximate_palette() mechanism instead,
989	    * like the x11 terminal?
990	    */
991	return WIN_PAL_COLORS;
992}
993
994
995TERM_PUBLIC void
996WIN_set_color(t_colorspec *colorspec)
997{
998	// TODO: color caching
999	WIN_flush_line(&WIN_poly);
1000
1001	switch (colorspec->type ) {
1002		case TC_FRAC: {
1003			/* Immediately translate palette index to RGB colour */
1004			rgb255_color rgb255;
1005			rgb255maxcolors_from_gray(colorspec->value, &rgb255);
1006			GraphOp(graphwin, W_setcolor, (rgb255.g << 8) | rgb255.b, (rgb255.r), NULL);
1007			break;
1008		}
1009		case TC_RGB:
1010			/* highest byte of colorspec->lt contains alpha */
1011			GraphOp(graphwin, W_setcolor, (colorspec->lt) & 0xffff, (colorspec->lt >> 16) & 0xffff, NULL);
1012			break;
1013		case TC_LT:
1014			GraphOp(graphwin, W_setcolor, colorspec->lt, 0, (void *) &WIN_set_color);
1015			break;
1016		default:
1017			break;
1018	}
1019	WIN_last_linetype = LT_NODRAW;
1020}
1021
1022
1023TERM_PUBLIC void
1024WIN_filled_polygon(int points, gpiPoint *corners)
1025{
1026	int i;
1027
1028	GraphOp(graphwin, W_fillstyle, corners->style, 0, NULL);
1029
1030	/* Eliminate duplicate polygon points. */
1031	if ((corners[0].x == corners[points - 1].x) &&
1032	    (corners[0].y == corners[points - 1].y))
1033		points--;
1034
1035	for (i = 0; i < points; i++)
1036		GraphOp(graphwin, W_filled_polygon_pt, corners[i].x, corners[i].y, NULL);
1037	GraphOp(graphwin, W_filled_polygon_draw, points, 0, NULL);
1038}
1039
1040
1041TERM_PUBLIC void
1042WIN_boxfill(
1043    int style,
1044    unsigned int xleft, unsigned int ybottom,
1045    unsigned int width, unsigned int height)
1046{
1047	WIN_flush_line(&WIN_poly);
1048
1049	/* split into multiple commands to squeeze through all the necessary info */
1050	GraphOp(graphwin, W_fillstyle, style, 0, NULL);
1051	GraphOp(graphwin, W_move, xleft, ybottom, NULL);
1052	GraphOp(graphwin, W_boxfill, xleft + width, ybottom + height, NULL);
1053}
1054
1055
1056TERM_PUBLIC int
1057WIN_set_font(const char *font)
1058{
1059	/* Note: defer the determination of default font name and default
1060	   font size until drawgraph() is executed. */
1061	if ((font == NULL) || (font[0] == '\0')) {
1062		/* select default font */
1063		GraphOp(graphwin, W_font, 0, 0, NULL);
1064	} else {
1065		int  fontsize;
1066		char * size;
1067
1068		size = strrchr(font, ',');
1069		if (size == NULL) {
1070			/* only font name given */
1071			GraphOp(graphwin, W_font, 0, 0, font);
1072		} else if (size == font) {
1073			/* only font size given */
1074			sscanf(size + 1, "%i", &fontsize);
1075			GraphOp(graphwin, W_font, fontsize, 0, NULL);
1076		} else {
1077			/* full font information supplied */
1078			char fontname[MAXFONTNAME];
1079			memcpy(fontname, font, size - font);
1080			fontname[size-font] = '\0';
1081			sscanf(size + 1, "%i", &fontsize);
1082			GraphOp(graphwin, W_font, fontsize, 0, fontname);
1083		}
1084	}
1085	return TRUE;
1086}
1087
1088
1089/* BM: new callback functions for enhanced text
1090   These are only stubs that call functions in wgraph.c.
1091*/
1092
1093TERM_PUBLIC void
1094WIN_enhanced_open(
1095    char *fontname,
1096    double fontsize, double base,
1097    TBOOLEAN widthflag, TBOOLEAN showflag,
1098    int overprint)
1099{
1100	GraphEnhancedOpen(fontname, fontsize, base, widthflag, showflag, overprint);
1101}
1102
1103
1104TERM_PUBLIC void
1105WIN_enhanced_flush()
1106{
1107	GraphEnhancedFlush();
1108}
1109
1110
1111TERM_PUBLIC void
1112WIN_layer(t_termlayer syncpoint)
1113{
1114	WIN_flush_line(&WIN_poly);
1115
1116	/* ignore LAYER_RESET in multiplot mode */
1117	if (((syncpoint == TERM_LAYER_RESET) ||
1118	     (syncpoint == TERM_LAYER_RESET_PLOTNO)) &&
1119		multiplot)
1120		return;
1121	GraphOp(graphwin, W_layer, syncpoint, 0, NULL);
1122}
1123
1124
1125TERM_PUBLIC void
1126WIN_hypertext(int type, const char * text)
1127{
1128	WIN_flush_line(&WIN_poly);
1129	GraphOp(graphwin, W_hypertext, type, 0, text);
1130}
1131
1132
1133TERM_PUBLIC void
1134WIN_boxed_text(unsigned int x, unsigned int y, int option)
1135{
1136	GraphOp(graphwin, W_boxedtext, option, 0, NULL);
1137	GraphOp(graphwin, W_boxedtext, x, y, NULL);
1138}
1139
1140
1141TERM_PUBLIC void
1142WIN_modify_plots(unsigned int operations, int plotno)
1143{
1144	GraphModifyPlots(graphwin, operations, plotno);
1145}
1146
1147#endif /* TERM_BODY */
1148
1149#ifdef TERM_TABLE
1150
1151TERM_TABLE_START(win_driver)
1152    "windows", "Microsoft Windows",
1153    WIN_XMAX, WIN_YMAX, WIN_VCHAR, WIN_HCHAR,
1154    WIN_VTIC, WIN_HTIC, WIN_options, WIN_init, WIN_reset,
1155    WIN_text, null_scale, WIN_graphics, WIN_move, WIN_vector,
1156    WIN_linetype, WIN_put_text, WIN_text_angle,
1157    WIN_justify_text, WIN_point, do_arrow, WIN_set_font,
1158    WIN_set_pointsize,
1159    TERM_CAN_MULTIPLOT|TERM_NO_OUTPUTFILE|TERM_ALPHA_CHANNEL|TERM_CAN_DASH
1160        |TERM_LINEWIDTH|TERM_FONTSCALE|TERM_POINTSCALE|TERM_ENHANCED_TEXT,
1161    WIN_text /* suspend */ , WIN_resume,
1162    WIN_boxfill, WIN_linewidth,
1163#ifdef USE_MOUSE
1164# ifdef WGP_CONSOLE
1165    WIN_waitforinput ,
1166# else
1167    0 /* WIN_waitforinput */,
1168# endif /* WGP_CONSOLE */
1169    WIN_put_tmptext, WIN_set_ruler, WIN_set_cursor, WIN_set_clipboard,
1170#endif
1171    WIN_make_palette, 0 /* previous_palette */,
1172    WIN_set_color, WIN_filled_polygon,
1173    WIN_image,
1174    WIN_enhanced_open, WIN_enhanced_flush, do_enh_writec,
1175    WIN_layer,
1176    0, /* no term->path */
1177    0.0, /* Scale (unused) */
1178    WIN_hypertext,
1179    WIN_boxed_text,
1180    WIN_modify_plots, WIN_dashtype
1181TERM_TABLE_END(win_driver)
1182
1183#undef LAST_TERM
1184#define LAST_TERM win_driver
1185
1186#endif /* TERM_TABLE */
1187#endif /* TERM_PROTO_ONLY */
1188
1189#ifdef TERM_HELP
1190START_HELP(windows)
1191"1 windows",
1192"?commands set terminal windows",
1193"?set terminal windows",
1194"?set term windows",
1195"?terminal windows",
1196"?term windows",
1197"?windows",
1198" The `windows` terminal is a fast interactive terminal driver that uses the",
1199" Windows GDI to draw and write text. The cross-platform `terminal wxt` and",
1200" `terminal qt` are also supported on Windows.",
1201"",
1202" Syntax:",
1203"       set terminal windows {<n>}",
1204"                            {color | monochrome}",
1205"                            {solid | dashed}",
1206"                            {rounded | butt}",
1207"                            {enhanced | noenhanced}",
1208"                            {font <fontspec>}",
1209"                            {fontscale <scale>}",
1210"                            {linewidth <scale>}",
1211"                            {pointscale <scale>}",
1212"                            {background <rgb color>}",
1213"                            {title \"Plot Window Title\"}",
1214"                            {{size | wsize} <width>,<height>}",
1215"                            {position <x>,<y>}",
1216"                            {docked {layout <rows>,<cols>} | standalone}",
1217"                            {close}",
1218"",
1219" Multiple plot windows are supported: `set terminal win <n>` directs the",
1220" output to plot window number n.",
1221"",
1222" `color` and `monochrome` select colored or mono output,",
1223" `dashed` and `solid` select dashed or solid lines. Note that `color`",
1224" defaults to `solid`, whereas `monochrome` defaults to `dashed`.",
1225" `rounded` sets line caps and line joins to be rounded; `butt` is the",
1226" default, butt caps and mitered joins.",
1227" `enhanced` enables enhanced text mode features (subscripts,",
1228" superscripts and mixed fonts, see `enhanced text` for more information).",
1229" `<fontspec>` is in the format \"<fontface>,<fontsize>\", where \"<fontface>\"",
1230" is the name of a valid Windows font, and <fontsize> is the size of the font",
1231" in points and both components are optional.",
1232" Note that in previous versions of gnuplot the `font` statement could be left",
1233" out and <fontsize> could be given as a number without double quotes. This is",
1234" no longer supported.",
1235" `linewidth`, `fontscale`, `pointscale` can be used to scale the width of",
1236" lines, the size of text, or the size of the point symbols.",
1237" `title` changes the title of the graph window.",
1238" `size` defines the width and height of the window's drawing area in pixels,",
1239" `wsize` defines the actual size of the window itself and `position` defines",
1240" the origin of the window i.e. the position of the top left corner on the",
1241" screen (again in pixel). These options override any default settings",
1242" from the `wgnuplot.ini` file.",
1243"",
1244" `docked` embeds the graph window in the wgnuplot text window and the `size`",
1245" and `position` options are ignored.  Note that `docked` is not available for",
1246" console-mode gnuplot.  Setting this option changes the default for new"
1247" windows.  The initial default is `standalone`.  The `layout` option allows to",
1248" reserve a minimal number of columns and rows for graphs in docked mode.  If",
1249" there are more graphs than fit the given layout, additional rows will be added.",
1250" Graphs are sorted by the numerical id, filling rows first.",
1251"",
1252" Other options may be changed using the `graph-menu` or the initialization file",
1253" `wgnuplot.ini`.",
1254"",
1255/* FIXME:  Move to persist section */
1256" The Windows version normally terminates immediately as soon as the end of",
1257" any files given as command line arguments is reached (i.e. in non-interactive",
1258" mode), unless you specify `-` as the last command line option.",
1259" It will also not show the text-window at all, in this mode, only the plot.",
1260" By giving the optional argument `-persist` (same as for gnuplot under x11;",
1261" former Windows-only options `/noend` or `-noend` are still accepted as well),",
1262" will not close gnuplot. Contrary to gnuplot on other operating systems,",
1263" gnuplot's interactive command line is accessible after the -persist option.",
1264"",
1265" The plot window remains open when the gnuplot terminal is changed with a",
1266" `set term` command. The plot window can be closed with `set term windows close`.",
1267"",
1268" `gnuplot` supports different methods to create printed output on Windows,",
1269" see `windows printing`. The windows terminal supports data exchange with ",
1270" other programs via clipboard and EMF files, see `graph-menu`. You can also",
1271" use the `terminal emf` to create EMF files.",
1272"2 graph-menu",
1273"?commands set terminal windows graph-menu",
1274"?set terminal windows graph-menu",
1275"?set term windows graph-menu",
1276"?windows graph-menu",
1277"?graph-menu",
1278" The `gnuplot graph` window has the following options on a pop-up menu",
1279" accessed by pressing the right mouse button(*) or selecting `Options` from the",
1280" system menu or the toolbar:",
1281"",
1282" `Copy to Clipboard` copies a bitmap and an enhanced metafile picture.",
1283"",
1284" `Save as EMF...` allows the user to save the current graph window as",
1285" enhanced metafile (EMF or EMF+).",
1286"",
1287" `Save as Bitmap...` allows the user to save a copy of the graph as bitmap",
1288" file.",
1289"",
1290" `Print...` prints the graphics windows using a Windows printer driver and",
1291" allows selection of the printer and scaling of the output."
1292" See also `windows printing`.",
1293"",
1294" `Bring to Top` when checked raises the graph window to the top after every",
1295" plot.",
1296"",
1297" `Color` when checked enables color output.  When unchecked it forces",
1298" all grayscale output.  This is e.g. useful to test appearance of monochrome",
1299" printouts.",
1300"",
1301#ifdef USE_WINGDI
1302" `GDI backend` draws to the screen using Windows GDI. This is the classical",
1303" windows terminal, which is fast, but lacks many features such as",
1304" anti-aliasing, oversampling and full transparency support. It is now",
1305" deprecated.",
1306#else
1307" The `GDI backend` which uses the classic GDI API is deprecated and has been",
1308" disabled in this version.",
1309#endif
1310"",
1311" `GDI+ backend` draws to the screen using the GDI+ Windows API. It supports",
1312" full antialiasing, oversampling, transparency and custom dash patterns.",
1313" This was the default in versions 5.0 and 5.2.",
1314"",
1315" `Direct2D backend` uses Direct2D & DirectWrite APIs to draw. It uses graphic",
1316" card acceleration and is hence typically much faster.  Since Direct2D can"
1317" not create EMF data, saving and copying to clipboard of EMF data fall back"
1318" to GDI+ while bitmap data is generated by D2d.",
1319" This is the recommended and default backend since version 5.3.",
1320"",
1321" `Oversampling` draws diagonal lines at fractional pixel positions to avoid",
1322" \"wobbling\" effects.  Vertical or horizontal lines are still snapped",
1323" to integer pixel positions to avoid blurry lines.",
1324"",
1325" `Antialiasing` enables smoothing of lines and edges. Note that this slows",
1326" down drawing.  `Antialiasing of polygons` is enabled by default but might",
1327" slow down drawing with the GDI+ backend.",
1328"",
1329" `Fast rotation` switches antialiasing temporarily off while rotating the",
1330" graph with the mouse. This speeds up drawing considerably at the expense",
1331" of an additional redraw after releasing the mouse button.",
1332"",
1333" `Background...` sets the window background color.",
1334"",
1335" `Choose Font...` selects the font used in the graphics window.",
1336"",
1337#ifdef WIN_CUSTOM_PENS
1338" `Line Styles...` allows customization of the line colors and styles.",
1339"",
1340#endif
1341" `Update wgnuplot.ini` saves the current window locations, window sizes, text",
1342" window font, text window font size, graph window font, graph window font",
1343" size, background color to the initialization file `wgnuplot.ini`.",
1344"",
1345"^<HR align=\"left\" width=\"100\">",
1346" (*) Note that this menu is only available by pressing the right mouse button",
1347" with `unset mouse`.",
1348"2 printing",
1349"?commands set terminal windows printing",
1350"?set terminal windows printing",
1351"?set term windows printing",
1352"?windows printing",
1353"?printing",
1354"?screendump",
1355" In order of preference, graphs may be printed in the following ways:",
1356"",
1357" `1.` Use the `gnuplot` command `set terminal` to select a printer and `set",
1358" output` to redirect output to a file.",
1359"",
1360" `2.` Select the `Print...` command from the `gnuplot graph` window.  An extra",
1361" command `screendump` does this from the text window.",
1362"",
1363" `3.` If `set output \"PRN\"` is used, output will go to a temporary file.  When",
1364" you exit from `gnuplot` or when you change the output with another `set",
1365" output` command, a dialog box will appear for you to select a printer port.",
1366" If you choose OK, the output will be printed on the selected port, passing",
1367" unmodified through the print manager.  It is possible to accidentally (or",
1368" deliberately) send printer output meant for one printer to an incompatible",
1369" printer.",
1370"",
1371"2 text-menu", /* FIXME: this is not really related to the windows driver, but the windows platform */
1372"?commands set terminal windows text-menu",
1373"?set terminal windows text-menu",
1374"?set term windows text-menu",
1375"?windows text-menu",
1376"?text-menu",
1377" The `gnuplot text` window has the following options on a pop-up menu accessed",
1378" by pressing the right mouse button or selecting `Options` from the system",
1379" menu:",
1380"",
1381" `Copy to Clipboard` copies marked text to the clipboard.",
1382"",
1383" `Paste` copies text from the clipboard as if typed by the user.",
1384"",
1385" `Choose Font...` selects the font used in the text window.",
1386"",
1387" `System Colors` when selected makes the text window honor the System Colors",
1388" set using the Control Panel.  When unselected, text is black or blue on a",
1389" white background.",
1390"",
1391" `Wrap long lines` when selected lines longer than the current window width",
1392" are wrapped.",
1393"",
1394" `Update wgnuplot.ini` saves the current settings to the initialisation file",
1395" `wgnuplot.ini`, which is located in the user's application data directory.",
1396"",
1397"2 wgnuplot.mnu", /* FIXME: this is not really related to the windows driver, but the windows platform */
1398"?windows wgnuplot.mnu",
1399"?wgnuplot.mnu",
1400" If the menu file `wgnuplot.mnu` is found in the same directory as",
1401" `gnuplot`, then the menu specified in `wgnuplot.mnu` will be loaded.",
1402" Menu commands:",
1403"",
1404"  [Menu]      starts a new menu with the name on the following line.",
1405"  [EndMenu]   ends the current menu.",
1406"  [--]        inserts a horizontal menu separator.",
1407"  [|]         inserts a vertical menu separator.",
1408"  [Button]    puts the next macro on a push button instead of a menu.",
1409"",
1410" Macros take two lines with the macro name (menu entry) on the first line and",
1411" the macro on the second line.  Leading spaces are ignored.  Macro commands:",
1412"",
1413"  [INPUT]     Input string with prompt terminated by [EOS] or {ENTER}",
1414"  [EOS]       End Of String terminator. Generates no output.",
1415"  [OPEN]      Get name of a file to open, with the title of the dialog",
1416"              terminated by [EOS], followed by a default filename terminated",
1417"              by [EOS] or {ENTER}.",
1418"  [SAVE]      Get name of a file to save.  Parameters like [OPEN]",
1419"  [DIRECTORY] Get name of a directory, with the title of the dialog",
1420"              terminated by [EOS] or {ENTER}",
1421"",
1422" Macro character substitutions:",
1423"",
1424"  {ENTER}     Carriage Return '\\r'",
1425"  {TAB}       Tab '\\011'",
1426"  {ESC}       Escape '\\033'",
1427"  {^A}        '\\001'",
1428"  ...",
1429"  {^_}        '\\031'",
1430"",
1431" Macros are limited to 256 characters after expansion.",
1432"",
1433"2 wgnuplot.ini",
1434"?commands set terminal windows wgnuplot.ini",
1435"?set terminal windows wgnuplot.ini",
1436"?set term windows wgnuplot.ini",
1437"?windows wgnuplot.ini",
1438"?wgnuplot.ini",
1439" The Windows text window and the `windows` terminal will read some of their options from",
1440" the `[WGNUPLOT]` section of `wgnuplot.ini`.",
1441" This file is located in the user's application data directory. Here's a sample",
1442" `wgnuplot.ini` file:",
1443"",
1444"       [WGNUPLOT]",
1445"       TextOrigin=0 0",
1446"       TextSize=640 150",
1447"       TextFont=Consolas,9",
1448"       TextWrap=1",
1449"       TextLines=400",
1450"       TextMaximized=0",
1451"       SysColors=0",
1452"       GraphOrigin=0 150",
1453"       GraphSize=640 330",
1454"       GraphFont=Tahoma,10",
1455"       GraphColor=1",
1456"       GraphToTop=1",
1457"       GraphGDI+=1",
1458"       GraphD2D=0",
1459"       GraphGDI+Oversampling=1",
1460"       GraphAntialiasing=1",
1461"       GraphPolygonAA=1",
1462"       GraphFastRotation=1",
1463"       GraphBackground=255 255 255",
1464"       DockVerticalTextFrac=350",
1465"       DockHorizontalTextFrac=400",
1466#ifdef WIN_CUSTOM_PENS
1467"       Border=0 0 0 0 0",
1468"       Axis=192 192 192 2 2",
1469"       Line1=0 0 255 0 0",
1470"       Line2=0 255 0 0 1",
1471"       Line3=255 0 0 0 2",
1472"       Line4=255 0 255 0 3",
1473"       Line5=0 0 128 0 4",
1474#endif
1475"",
1476"^ <h3>Text window options</h3> ",
1477"",
1478" These settings apply to the wgnuplot text-window only."
1479"",
1480" The `TextOrigin` and `TextSize` entries specify the location and size of the",
1481" text window. If `TextMaximized` is non-zero, the window will be maximized.",
1482"",
1483" The `TextFont` entry specifies the text window font and size.",
1484"",
1485" The `TextWrap` entry selects wrapping of long text lines.",
1486"",
1487" The `TextLines` entry specifies the number of (unwrapped) lines the internal",
1488" buffer of the text window can hold. This value currently cannot be changed",
1489" from within wgnuplot.",
1490"",
1491" See `text-menu`.",
1492"",
1493"^ <h3>Docked graph options</h3>",
1494"",
1495" `DockVerticalTextFrac` and `DockHorizontalTextFrac` set the fraction of the",
1496" window reserved for the text window in permille of the vertical or horizontal",
1497" layout.",
1498"",
1499"^ <h3>Graph window options</h3>",
1500"",
1501" The `GraphFont` entry specifies the font name and size in points.",
1502#ifdef WIN_CUSTOM_PENS
1503"",
1504" The five",
1505" numbers given in the `Border`, `Axis` and `Line` entries are the `Red`",
1506" intensity (0--255), `Green` intensity, `Blue` intensity, `Color Linestyle`",
1507" and `Mono Linestyle`.  `Linestyles` are 0=SOLID, 1=DASH, 2=DOT, 3=DASHDOT,",
1508" 4=DASHDOTDOT.  In the sample `wgnuplot.ini` file above, Line 2 is a green",
1509" solid line in color mode, or a dashed line in monochrome mode.  The default",
1510" line width is 1 pixel.  If `Linestyle` is negative, it specifies the width of",
1511" a SOLID line in pixels.  Line1 and any linestyle used with the `points` style",
1512" must be SOLID with unit width.",
1513#endif
1514"",
1515" See `graph-menu`."
1516END_HELP(windows)
1517#endif /* TERM_HELP */
1518