1 /* This file is part of the GNU plotutils package.  Copyright (C) 1995,
2    1996, 1997, 1998, 1999, 2000, 2005, 2008, Free Software Foundation, Inc.
3 
4    The GNU plotutils package is free software.  You may redistribute it
5    and/or modify it under the terms of the GNU General Public License as
6    published by the Free Software foundation; either version 2, or (at your
7    option) any later version.
8 
9    The GNU plotutils package is distributed in the hope that it will be
10    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with the GNU plotutils package; see the file COPYING.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
17    Boston, MA 02110-1301, USA. */
18 
19 /* This is "plotter.h", the public header file for the C++ Plotter class
20    provided by GNU libplotter, a shared class library for 2-dimensional
21    vector graphics.
22 
23    This file should be included by any code that uses the Plotter class.
24    If the Plotter class was installed without X Window System support, be
25    sure to do "#define X_DISPLAY_MISSING" before including this file.
26 
27    From the base Plotter class, the BitmapPlotter, MetaPlotter, TekPlotter,
28    ReGISPlotter, HPGLPlotter, FigPlotter, CGMPlotter, PSPlotter, AIPlotter,
29    SVGPlotter, GIFPlotter, PNMPlotter, PNGPlotter, and XDrawablePlotter
30    classes are derived.  The PNMPlotter and PNGPlotter classes are derived
31    from the BitmapPlotter class, the PCLPlotter class is derived from the
32    HPGLPlotter class, and the XPlotter class is derived from the
33    XDrawablePlotter class. */
34 
35 /* If NOT_LIBPLOTTER is defined, this file magically becomes an internal
36    header file used in GNU libplot, the C version of libplotter.  libplot
37    has its own public header file, called "plot.h". */
38 
39 /* Implementation note: In libplot, a Plotter is a typedef'd structure
40    rather than a class instance.  Because of the need to support both
41    libplot and libplotter, i.e. C and C++, all data members of derived
42    Plotter classes are declared in this file twice: once in the Plotter
43    structure (for C), and once in each derived class declaration (for C++). */
44 
45 #ifndef _PLOTTER_H_
46 #define _PLOTTER_H_ 1
47 
48 /***********************************************************************/
49 
50 /* Version of GNU libplot/libplotter which this header file accompanies.
51    This information is included beginning with version 4.0.
52 
53    The PL_LIBPLOT_VER_STRING macro is compiled into the library, as
54    `pl_libplot_ver'.  The PL_LIBPLOT_VER macro is not compiled into it.
55    Both are available to applications that include this header file. */
56 
57 #define PL_LIBPLOT_VER_STRING "4.4"
58 #define PL_LIBPLOT_VER         404
59 
60 extern const char pl_libplot_ver[8];   /* need room for 99.99aa */
61 
62 /***********************************************************************/
63 
64 /* If we're supporting X, include X-related header files needed by the
65    class definition. */
66 #ifndef X_DISPLAY_MISSING
67 #include <X11/Xlib.h>
68 #include <X11/Intrinsic.h>
69 #endif /* not X_DISPLAY_MISSING */
70 
71 /* Include stdio and iostream support if this is libplotter rather than
72    libplot. */
73 #ifndef NOT_LIBPLOTTER
74 #include <cstdio>
75 #include <iostream>
76 using namespace std;
77 #endif
78 
79 /* THE GLOBAL VARIABLES IN GNU LIBPLOTTER */
80 /* There are two; both are user-settable error handlers. */
81 #ifndef NOT_LIBPLOTTER
82 extern int (*pl_libplotter_warning_handler) (const char *msg);
83 extern int (*pl_libplotter_error_handler) (const char *msg);
84 #endif
85 
86 
87 /***********************************************************************/
88 
89 /* Structures for points. */
90 
91 typedef struct
92 {
93   double x, y;
94 } plPoint;
95 
96 typedef struct
97 {
98   int x, y;
99 } plIntPoint;
100 
101 /* Structures for paths, as painted by any Plotter. */
102 
103 /* Normally, a simple path is a sequence of contiguous line segments,
104    circular arc segments, elliptic arc segments, quadratic Bezier segments,
105    or cubic Bezier segments.  All Plotters support line segments, but many
106    Plotters don't support the other types of segment.  Some Plotters also
107    support (closed) simple paths that are single circles, ellipses, or
108    "boxes" (rectangles aligned with the coordinate axes).
109 
110    A simple path that is a sequence of segments is represented internally
111    as a list of plPathSegments.  Each contains a single endpoint (x,y), and
112    specifies how to get there (e.g., via a pen-up motion, which is used for
113    the first point in a path, or via a line segment, or a curve defined by
114    control points).
115 
116    A well-formed simple path of this `segment list' type has the form:
117    { moveto { line | arc | ellarc | quad | cubic }* { closepath }? } */
118 
119 /* Allowed values for the path segment type field. */
120 typedef enum
121 {
122   S_MOVETO, S_LINE, S_ARC, S_ELLARC, S_QUAD, S_CUBIC, S_CLOSEPATH
123 } plPathSegmentType;
124 
125 /* Structure for a path segment. */
126 typedef struct
127 {
128   plPathSegmentType type;
129   plPoint p;			/* endpoint of segment */
130   plPoint pc;			/* intermediate control point (if any) */
131   plPoint pd;			/* additional control point (S_CUBIC only) */
132 } plPathSegment;
133 
134 /* Allowed values for the path type field in a plPath (see below). */
135 typedef enum
136 {
137   PATH_SEGMENT_LIST,		/* the default kind */
138   PATH_CIRCLE, PATH_ELLIPSE, PATH_BOX /* supported by some Plotters */
139 } plPathType;
140 
141 /* Structure for a simple path.  The default kind of simple path is a list
142    of segments.  However, a simple path may also be a circle, ellipse, or
143    box, which some Plotter support as primitive drawing elements, at least
144    under some circumstances.  Other Plotters automatically flatten these
145    built-in primitives into segment lists.  The advisory `primitive' flag
146    is set to `true' to indicate that a segment list is in fact such a
147    flattened object. */
148 
149 typedef struct
150 {
151   plPathType type;	/* PATH_{SEGMENT_LIST,CIRCLE,ELLIPSE,BOX} */
152   double llx, lly, urx, ury;    /* bounding box */
153   /* simple path of segment list type */
154   plPathSegment *segments;	/* list of path segments */
155   int num_segments;		/* number of segments in list */
156   int segments_len;		/* length of buffer for list storage (bytes) */
157   bool primitive;		/* advisory (see above; some Plotters use it)*/
158   /* simple path of built-in primitive type (circle/ellipse/box) */
159   plPoint pc;			/* CIRCLE/ELLIPSE: center */
160   double radius;		/* CIRCLE: radius */
161   double rx, ry;		/* ELLIPSE: semi-axes */
162   double angle;			/* ELLIPSE: angle of first axis */
163   plPoint p0, p1;		/* BOX: opposite vertices */
164   bool clockwise;		/* CIRCLE/ELLIPSE/BOX: clockwise? */
165 } plPath;
166 
167 /* An integer counterpart to plPathSegment, used by some Plotters during
168    the mapping of segment-list paths to the device frame.  This shouldn't
169    be defined here, since it's so Plotter-specific. */
170 typedef struct
171 {
172   plPathSegmentType type;
173   plIntPoint p;			/* endpoint of segment */
174   plIntPoint pc;		/* intermediate control point (if any) */
175   plIntPoint pd;		/* additional control point (S_CUBIC only) */
176   double angle;			/* subtended angle (for S_ARC, if used) */
177 } plIntPathSegment;
178 
179 /* Values for the parameters `allowed_{arc|ellarc|quad|cubic}_scaling' of
180    any Plotter.  Those parameters specify which sorts of user frame ->
181    device frame affine transformation are allowed, if an arc or Bezier that
182    is part of a path is to be placed in the path buffer's segment list as a
183    single segment, rather than approximated as a polyline.
184 
185    These are also the possible values for the parameters
186    allowed_{circle|ellipse|box}_scaling' of any Plotter, which specify
187    whether any circle/ellipse/box should be placed in the path buffer as a
188    primitive, rather than split into arc segments or line segments and
189    placed in the segment list.
190 
191    The reason for extensively parametrizing the internal operation of any
192    Plotter (i.e. restricting what gets placed in its path buffer) is that
193    for many Plotters, the Plotter-specific operation _paint_path(), which
194    is called by endpath(), can't handle arbitrary drawing primitives,
195    because the Plotter's output format doesn't support them.
196 
197    The values AS_UNIFORM and AS_AXES_PRESERVED aren't used for Beziers, but
198    they're used for the other primitives.  Also, insofar as ellipses go, a
199    value of AS_AXES_PRESERVED for the allowed scaling is intepreted as
200    meaning that not only should the affine map preserve coordinate axes,
201    but the ellipse itself, to be placed in the path buffer, should have its
202    major and minor axes aligned with the coordinate axes.  See g_ellipse.c.  */
203 
204 typedef enum
205 {
206   AS_NONE,			/* primitive not supported at all */
207   AS_UNIFORM,			/* supported only if transf. is uniform  */
208   AS_AXES_PRESERVED,		/* supported only if transf. preserves axes */
209   AS_ANY			/* supported irrespective of transformation */
210 } plScalingType;
211 
212 
213 /**********************************************************************/
214 
215 /* Structures for colors (we don't fully distinguish between 24-bit color
216    and 48-bit color, though we should). */
217 
218 /* RGB */
219 typedef struct
220 {
221   int red;
222   int green;
223   int blue;
224 } plColor;
225 
226 /* BitmapPlotters (including PNMPlotters and PNGPlotters, which are
227    derived) and GIFPlotters use the libxmi scan-conversion library, which
228    is compiled into libplot/libplotter.  libxmi writes into a pixmap that
229    is made up of the following type of pixel.  We use a struct containing a
230    union, so that the compiled-in libxmi can be used both by GIF Plotters
231    (in which pixel values are color indices) and by BitmapPlotters (in
232    which pixel values are 24-bit RGB values).  We distinguish them by the
233    `type' field. */
234 #define MI_PIXEL_TYPE struct \
235 { \
236   unsigned char type; \
237   union \
238     { \
239       unsigned char index; \
240       unsigned char rgb[3]; \
241     } u; \
242 }
243 
244 /* values for the `type' field */
245 #define MI_PIXEL_INDEX_TYPE 0
246 #define MI_PIXEL_RGB_TYPE 1
247 
248 #define MI_SAME_PIXEL(pixel1,pixel2) \
249   (((pixel1).type == MI_PIXEL_INDEX_TYPE \
250     && (pixel2).type == MI_PIXEL_INDEX_TYPE \
251     && (pixel1).u.index == (pixel2).u.index) \
252    || \
253   ((pixel1).type == MI_PIXEL_RGB_TYPE \
254     && (pixel2).type == MI_PIXEL_RGB_TYPE \
255     && (pixel1).u.rgb[0] == (pixel2).u.rgb[0] \
256     && (pixel1).u.rgb[1] == (pixel2).u.rgb[1] \
257     && (pixel1).u.rgb[2] == (pixel2).u.rgb[2]))
258 
259 
260 /**********************************************************************/
261 
262 /* Structure used for characterizing a page type (e.g. "letter", "a4"; see
263    our database of known page types in g_pagetype.h).  Any Plotter includes
264    a pointer to one of these.
265 
266    For all `physical' Plotters, i.e. those with a page type determined by
267    the PAGESIZE parameter, we map the window that the user specifies by
268    invoking space(), to a viewport whose default size is fixed and
269    Plotter-independent.  E.g., for any Plotter for which PAGESIZE is
270    "letter", the default viewport is a square of size 8.0in x 8.0in.
271 
272    All physical Plotters position this default viewport at the center of
273    the page, except that HPGLPlotters don't know exactly where the origin
274    of the device coordinate system is.  PCLPlotters do, though, when
275    they're emitting HP-GL/2 code (there's a field in the struct that
276    specifies that, see below).  See comments in g_pagetype.h. */
277 
278 typedef struct
279 {
280   const char *name;		/* official name, e.g. "a" */
281   const char *alt_name;		/* alternative name if any, e.g. "letter" */
282   const char *fig_name;		/* name used in Fig format (case-sensitive) */
283   bool metric;			/* metric vs. Imperial, advisory only */
284   double xsize, ysize;		/* width, height in inches */
285   double default_viewport_size;	/* size of default square viewport, in inches*/
286   double pcl_hpgl2_xorigin;	/* origin for HP-GL/2-in-PCL5 plotting */
287   double pcl_hpgl2_yorigin;
288   double hpgl2_plot_length;	/* plot length (for HP-GL/2 roll plotters) */
289 } plPageData;
290 
291 /* Structure in which the user->NDC and user->device affine coordinate
292    transformations are stored.  Any drawing state includes one of these
293    structures.  The user->NDC transformation is a bit more fundamental,
294    since it's used as an attribute of all objects that get drawn.
295 
296    The user->device transformation is the product of the user->NDC
297    transformation and the NDC->device transformation (stored in the Plotter
298    itself, since it never changes after being initialized at Plotter
299    creation time).  The reason we precompute the user->device
300    transformation and store it here is that we use it so frequently. */
301 
302 typedef struct
303 {
304   /* the user->NDC transformation */
305   double m_user_to_ndc[6];	/* 1. a linear transformation (4 elements) */
306   				/* 2. a translation (2 elements) */
307   /* the user->device transformation, precomputed for convenience */
308   double m[6];
309   /* data on user->device map, also precomputed for convenience */
310   bool uniform;			/* transf. scaling is uniform? */
311   bool axes_preserved;		/* transf. preserves axis directions? */
312   bool nonreflection;		/* transf. doesn't involve a reflection? */
313 } plTransform;
314 
315 
316 /**********************************************************************/
317 
318 /* Drawing state structure.  Includes drawing attributes, and the state of
319    any uncompleted path object.  When open, i.e., when drawing a page of
320    graphics, any Plotter maintains a stack of these things.  Many of the
321    data members are device-dependent, i.e., specific to individual derived
322    Plotter classes, but it's more efficient to keep them here, in a single
323    structure.  The device-independent data members are listed first. */
324 
325 typedef struct plDrawStateStruct
326 {
327 /***************** DEVICE-INDEPENDENT PART ***************************/
328 
329 /* graphics cursor position */
330   plPoint pos;			/* graphics cursor position in user space */
331 
332 /* affine transformation from user coordinates to normalized device
333    coordinates, and also to actual device coordinates (precomputed) */
334   plTransform transform;	/* see definition of structure above */
335 
336 /* the compound path being drawn, if any */
337   plPath *path;			/* simple path being drawn */
338   plPath **paths;		/* previously drawn simple paths */
339   int num_paths;		/* number of previously drawn simple paths */
340   plPoint start_point;		/* starting point (used by closepath()) */
341 
342 /* modal drawing attributes */
343   /* 1. path-related attributes */
344   const char *fill_rule;	/* fill rule */
345   int fill_rule_type;		/* one of PL_FILL_*, determined by fill rule */
346   const char *line_mode;	/* line mode */
347   int line_type;		/* one of PL_L_*, determined by line mode */
348   bool points_are_connected;	/* if not set, path displayed as points */
349   const char *cap_mode;		/* cap mode */
350   int cap_type;			/* one of PL_CAP_*, determined by cap mode */
351   const char *join_mode;	/* join mode */
352   int join_type;		/* one of PL_JOIN_*, determined by join mode */
353   double miter_limit;		/* miter limit for line joins */
354   double line_width;		/* width of lines in user coordinates */
355   bool line_width_is_default;	/* line width is (Plotter-specific) default? */
356   double device_line_width;	/* line width in device coordinates */
357   int quantized_device_line_width; /* line width, quantized to integer */
358   const double *dash_array;	/* array of dash on/off lengths (nonnegative)*/
359   int dash_array_len;		/* length of same */
360   double dash_offset;		/* offset distance into dash array (`phase') */
361   bool dash_array_in_effect;	/* dash array should override line mode? */
362   int pen_type;			/* pen type (0 = no pen, 1 = pen) */
363   int fill_type;		/* fill type (0 = no fill, 1 = fill, ...) */
364   int orientation;	        /* orientation of circles etc.(1=c'clockwise)*/
365   /* 2. text-related attributes */
366   const char *font_name;	/* font name */
367   double font_size;		/* font size in user coordinates */
368   bool font_size_is_default;	/* font size is (Plotter-specific) default? */
369   double text_rotation;		/* degrees counterclockwise, for labels */
370   const char *true_font_name;	/* true font name (as retrieved) */
371   double true_font_size;	/* true font size (as retrieved) */
372   double font_ascent;		/* font ascent (as retrieved) */
373   double font_descent;		/* font descent (as retrieved) */
374   double font_cap_height;	/* font capital height (as received) */
375   int font_type;		/* PL_F_{HERSHEY|POSTSCRIPT|PCL|STICK|OTHER} */
376   int typeface_index;		/* typeface index (in g_fontdb.h table) */
377   int font_index;		/* font index, within typeface */
378   bool font_is_iso8859_1;	/* whether font uses iso8859_1 encoding */
379   /* 3. color attributes (fgcolor and fillcolor are path-related; fgcolor
380      affects other primitives too) */
381   plColor fgcolor;		/* foreground color, i.e., pen color */
382   plColor fillcolor_base;	/* fill color (not affected by fill_type) */
383   plColor fillcolor;		/* fill color (takes fill_type into account) */
384   plColor bgcolor;		/* background color for graphics display */
385   bool bgcolor_suppressed;	/* no actual background color? */
386 
387 /* default values for certain attributes, used when an out-of-range value
388    is requested (these two are special because they're set by fsetmatrix()) */
389   double default_line_width;	/* width of lines in user coordinates */
390   double default_font_size;	/* font size in user coordinates */
391 
392 /****************** DEVICE-DEPENDENT PART ***************************/
393 
394 /* elements specific to the HPGL Plotter drawing state */
395   double hpgl_pen_width;	/* pen width (frac of diag dist betw P1,P2) */
396 
397 /* elements specific to the Fig Plotter drawing state */
398   int fig_font_point_size;	/* font size in fig's idea of points */
399   int fig_fill_level;		/* fig's fill level */
400   int fig_fgcolor;		/* fig's foreground color */
401   int fig_fillcolor;		/* fig's fill color */
402 
403 /* elements specific to the PS Plotter drawing state */
404   double ps_fgcolor_red;	/* RGB for fgcolor, each in [0.0,1.0] */
405   double ps_fgcolor_green;
406   double ps_fgcolor_blue;
407   double ps_fillcolor_red;	/* RGB for fillcolor, each in [0.0,1.0] */
408   double ps_fillcolor_green;
409   double ps_fillcolor_blue;
410   int ps_idraw_fgcolor;		/* index of idraw fgcolor in table */
411   int ps_idraw_bgcolor;		/* index of idraw bgcolor in table */
412   int ps_idraw_shading;		/* index of idraw shading in table */
413 
414 /* elements specific to the GIF Plotter drawing state */
415   plColor i_pen_color;		/* pen color (24-bit RGB) */
416   plColor i_fill_color;		/* fill color (24-bit RGB) */
417   plColor i_bg_color;		/* background color (24-bit RGB) */
418   unsigned char i_pen_color_index; /* pen color index */
419   unsigned char i_fill_color_index; /* fill color index */
420   unsigned char i_bg_color_index; /* bg color index */
421   bool i_pen_color_status;	/* foreground color index is genuine? */
422   bool i_fill_color_status;	/* fill color index is genuine? */
423   bool i_bg_color_status;	/* background color index is genuine? */
424 
425 #ifndef X_DISPLAY_MISSING
426 /* elements specific to the X Drawable Plotter drawing state */
427   unsigned int x_font_pixel_size; /* pixel size according to server */
428   XFontStruct *x_font_struct;	/* font structure (used in x_text.c) */
429   const unsigned char *x_label;	/* label (hint to _x_retrieve_font()) */
430   GC x_gc_fg;			/* graphics context, for drawing */
431   GC x_gc_fill;			/* graphics context, for filling */
432   GC x_gc_bg;			/* graphics context, for erasing */
433   plColor x_current_fgcolor;	/* pen color stored in GC (48-bit RGB) */
434   plColor x_current_fillcolor;	/* fill color stored in GC (48-bit RGB) */
435   plColor x_current_bgcolor;	/* bg color stored in GC (48-bit RGB) */
436   unsigned long x_gc_fgcolor;	/* color stored in drawing GC (pixel value) */
437   unsigned long x_gc_fillcolor;	/* color stored in filling GC (pixel value) */
438   unsigned long x_gc_bgcolor;	/* color stored in erasing GC (pixel value) */
439   bool x_gc_fgcolor_status;	/* pixel value in drawing GC is genuine? */
440   bool x_gc_fillcolor_status;	/* pixel value in filling GC is genuine? */
441   bool x_gc_bgcolor_status;	/* pixel value in erasing GC is genuine? */
442   int x_gc_line_style;		/* line style stored in drawing GC */
443   int x_gc_cap_style;		/* cap style stored in drawing GC */
444   int x_gc_join_style;		/* join style stored in drawing GC */
445   int x_gc_line_width;		/* line width stored in drawing GC */
446   const char *x_gc_dash_list;	/* dash list stored in drawing GC */
447   int x_gc_dash_list_len;	/* length of dash list stored in drawing GC */
448   int x_gc_dash_offset;		/* offset into dash sequence, in drawing GC */
449   int x_gc_fill_rule;		/* fill rule stored in filling GC */
450 #endif /* not X_DISPLAY_MISSING */
451 
452 /* pointer to previous drawing state */
453   struct plDrawStateStruct *previous;
454 
455 } plDrawState;
456 
457 
458 /**********************************************************************/
459 
460 /* An output buffer that may easily be resized.  Used by most Plotters that
461    do not do real-time output, to store device code for all graphical
462    objects plotted on a page, and page-specific data such as the bounding
463    box and `fonts used' information.  (See e.g. g_outbuf.c.)  Plotters that
464    wait until they are deleted before outputing graphics, e.g. PSPlotters
465    and CGMPlotters, maintain not just one of these things but rather a
466    linked list, one output buffer per page. */
467 
468 /* NUM_PS_FONTS and NUM_PCL_FONTS should agree with the number of fonts of
469    each type in g_fontdb.c.  These are also defined in libplot/extern.h. */
470 #define NUM_PS_FONTS 35
471 #define NUM_PCL_FONTS 45
472 
473 typedef struct plOutbufStruct
474 {
475   /* if non-NULL, a plOutbuf containing a page header */
476   struct plOutbufStruct *header;
477 
478   /* if non-NULL, a plOutbuf containing a page trailer */
479   struct plOutbufStruct *trailer;
480 
481   /* device code for the graphics on the page */
482   char *base;			/* start of buffer */
483   unsigned long len;		/* size of buffer */
484   char *point;			/* current point (high-water mark) */
485   char *reset_point;		/* point below which contents are frozen */
486   unsigned long contents;	/* size of contents */
487   unsigned long reset_contents;	/* size of frozen contents if any */
488 
489   /* page-specific information that some Plotters generate and use (this is
490      starting to look like a Christmas tree...) */
491   double xrange_min;		/* bounding box, in device coordinates */
492   double xrange_max;
493   double yrange_min;
494   double yrange_max;
495   bool ps_font_used[NUM_PS_FONTS]; /* PS fonts used on page */
496   bool pcl_font_used[NUM_PCL_FONTS]; /* PCL fonts used on page */
497   plColor bg_color;		/* background color for the page */
498   bool bg_color_suppressed;	/* background color is "none"? */
499 
500   /* a hook for Plotters to hang other page-specific data */
501   void * extra;
502 
503   /* pointer to previous Outbuf in page list if any */
504   struct plOutbufStruct *next;
505 } plOutbuf;
506 
507 /* Each Plotter caches the color names that have previously been mapped to
508    RGB triples via libplot's colorname database (see g_colorname.h).
509    For the cache, a linked list is currently used. */
510 
511 typedef struct
512 {
513   const char *name;
514   unsigned char red;
515   unsigned char green;
516   unsigned char blue;
517 } plColorNameInfo;
518 
519 typedef struct plCachedColorNameInfoStruct
520 {
521   const plColorNameInfo *info;
522   struct plCachedColorNameInfoStruct *next;
523 } plCachedColorNameInfo;
524 
525 typedef struct
526 {
527   plCachedColorNameInfo *cached_colors;	/* head of linked list */
528 } plColorNameCache;
529 
530 #ifndef X_DISPLAY_MISSING
531 /* Each X DrawablePlotter (or X Plotter) keeps track of which fonts have
532    been request from an X server, in any connection, by constructing a
533    linked list of these records.  A linked list is good enough if we don't
534    have huge numbers of font changes. */
535 typedef struct plXFontRecordStruct
536 {
537   char *x_font_name;		/* font name, preferably an XLFD name */
538   XFontStruct *x_font_struct;	/* font structure */
539   unsigned int x_font_pixel_size;
540   unsigned int x_font_cap_height;
541   bool x_font_is_iso8859_1;
542   bool subset;			/* did we retrieve a subset of the font? */
543   unsigned char subset_vector[32]; /* 256-bit vector, 1 bit per font char */
544   struct plXFontRecordStruct *next; /* most recently retrieved font */
545 } plXFontRecord;
546 
547 /* Allocated color cells are kept track of similarly */
548 typedef struct plColorRecordStruct
549 {
550   XColor rgb;			/* RGB value and pixel value (if any) */
551   bool allocated;		/* pixel value successfully allocated? */
552   int frame_number;		/* frame that cell was most recently used in*/
553   int page_number;		/* page that cell was most recently used in*/
554   struct plColorRecordStruct *next; /* most recently retrieved color cell */
555 } plColorRecord;
556 #endif /* not X_DISPLAY_MISSING */
557 
558 
559 /***********************************************************************/
560 
561 /* The Plotter class, and also its derived classes (in libplotter).  In
562    libplot, a Plotter is a struct, and there are no derived classes; the
563    data members of the derived classes are located inside the Plotter
564    structure. */
565 
566 /* A few miscellaneous constants that appear in the declaration of the
567    Plotter class (should be moved elsewhere if possible). */
568 
569 /* Number of recognized Plotter parameters (see g_params2.c). */
570 #define NUM_PLOTTER_PARAMETERS 33
571 
572 /* Maximum number of pens, or logical pens, for an HP-GL/2 device.  Some
573    such devices permit as many as 256, but all should permit at least 32.
574    Our pen numbering will range over 0..HPGL2_MAX_NUM_PENS-1. */
575 #define HPGL2_MAX_NUM_PENS 32
576 
577 /* Maximum number of non-builtin colors that can be specified in an xfig
578    input file.  See also FIG_NUM_STD_COLORS, defined in
579    libplot/extern.h. */
580 #define FIG_MAX_NUM_USER_COLORS 512
581 
582 /* Supported Plotter types.  These values are used in a `tag field', in
583    libplot but not libplotter.  (C++ doesn't have such things, at least it
584    didn't until RTTI was invented :-)). */
585 #ifdef NOT_LIBPLOTTER
586 typedef enum
587 {
588   PL_GENERIC,			/* instance of base Plotter class */
589   PL_BITMAP,			/* bitmap class, derived from by PNM and PNG */
590   PL_META,			/* GNU graphics metafile */
591   PL_TEK,			/* Tektronix 4014 with EGM */
592   PL_REGIS,			/* ReGIS (remote graphics instruction set) */
593   PL_HPGL,			/* HP-GL and HP-GL/2 */
594   PL_PCL,			/* PCL 5 (i.e. HP-GL/2 w/ header, trailer) */
595   PL_FIG,			/* xfig 3.2 */
596   PL_CGM,			/* CGM (Computer Graphics Metafile) */
597   PL_PS,			/* Postscript, with idraw support */
598   PL_AI,			/* Adobe Illustrator 5 (or 3) */
599   PL_SVG,			/* Scalable Vector Graphics */
600   PL_GIF,			/* GIF 87a or 89a */
601   PL_PNM			/* Portable Anymap Format (PBM/PGM/PPM) */
602 #ifdef INCLUDE_PNG_SUPPORT
603   , PL_PNG			/* PNG: Portable Network Graphics */
604 #endif
605 #ifndef X_DISPLAY_MISSING
606   , PL_X11_DRAWABLE		/* X11 Drawable */
607   , PL_X11			/* X11 (pops up, manages own window[s]) */
608 #endif
609 } plPlotterTag;
610 #endif /* NOT_LIBPLOTTER */
611 
612 /* Types of Plotter output model.  The `output_model' data element in any
613    Plotter class specifies the output model, and the libplot machinery
614    takes it from there.  In particular, plOutbuf structures (one per page)
615    are maintained if necessary, and written out at the appropriate time.
616 
617    Note: in the PAGES_ALL_AT_ONCE, OUTPUT_VIA_CUSTOM_ROUTINES* cases, the
618    Plotter is responsible for managing its own output.  In the
619    PAGES_ALL_AT_ONCE case, libplot maintains not just one but an entire
620    linked list of plOutbuf's, to be scanned over by the derived Plotter at
621    deletion time. */
622 
623 typedef enum
624 {
625   PL_OUTPUT_NONE,
626   /* No output at all; Plotter is used primarily for subclassing.  E.g.,
627      generic and Bitmap Plotters. */
628 
629   PL_OUTPUT_ONE_PAGE,
630   /* Plotter produces at most one page of output (the first), and uses
631      libplot's builtin plOutbuf-based output mechanism.  The first page,
632      which is written to a plOutbuf, is written out by the first invocation
633      of closepl(), and all later pages are ignored.  E.g., Fig,
634      Illustrator, and SVG Plotters. */
635 
636   PL_OUTPUT_ONE_PAGE_AT_A_TIME,
637   /* Plotter produces any number of pages of output, and uses libplot's
638      builtin plOutbuf-based output mechanism.  Each page is written out as
639      soon as closepl() is called on it.  E.g., HP-GL/PCL Plotters.  */
640 
641   PL_OUTPUT_PAGES_ALL_AT_ONCE,
642   /* Plotter produces any number of pages of output, and uses libplot's
643      builtin plOutbuf-based output mechanism.  But pages are written out
644      only when the Plotter is deleted, i.e., when the internal terminate()
645      function is called.  (Actually, it's the generic-class terminate(),
646      which any derived-class terminate() calls, that does it.)  Because all
647      pages need to be stored, a linked list of plOutbuf's is created, one
648      per page.  E.g., PS and CGM Plotters.  */
649 
650   PL_OUTPUT_VIA_CUSTOM_ROUTINES,
651   /* Plotter uses its own output routines to write one or possibly more
652      pages to its output stream, as whole pages (i.e., when closepl() is
653      called).  It doesn't use libplot's plOutbuf-based output routines.
654      E.g., PNM, GIF, and PNG Plotters (all of which output only 1 page). */
655 
656   PL_OUTPUT_VIA_CUSTOM_ROUTINES_IN_REAL_TIME,
657   /* Plotter uses its own output routines to write to its output stream, in
658      real time.  It doesn't use libplot's plOutbuf-based output routines.
659      E.g., Metafile, Tektronix, and ReGIS Plotters. */
660 
661   PL_OUTPUT_VIA_CUSTOM_ROUTINES_TO_NON_STREAM
662   /* Plotter uses its own output routines to write to something other than
663      an output stream, which must presumably be passed to it as a Plotter
664      parameter.  May or may not plot in real time.  E.g., X Drawable and X
665      Plotters (both of which plot in real time). */
666 } plPlotterOutputModel;
667 
668 /* Plotter data.  These data members of any Plotter object are stuffed into
669    a single struct, for convenience.  Most of them are initialized by the
670    initialize() method, and don't change thereafter.  So they're really
671    parameters: they define the functioning of any Plotter.
672 
673    A few of these, e.g. the `page' member, do change at later times.  But
674    it's the core Plotter code that changes them; not the device-specific
675    drivers.  They're flagged by D: (i.e. dynamic), in their description. */
676 
677 typedef struct
678 {
679   /* data members (a great many!) which are really Plotter parameters */
680 
681 #ifdef NOT_LIBPLOTTER
682   /* tag field */
683   plPlotterTag type;		/* Plotter type: one of PL_* defined above */
684 #endif /* NOT_LIBPLOTTER */
685 
686   /* low-level I/O issues */
687   plPlotterOutputModel output_model;/* one of PL_OUTPUT_* (see above) */
688   FILE *infp;			/* stdio-style input stream if any */
689   FILE *outfp;			/* stdio-style output stream if any */
690   FILE *errfp;			/* stdio-style error stream if any */
691 #ifndef NOT_LIBPLOTTER
692   istream *instream;		/* C++-style input stream if any */
693   ostream *outstream;		/* C++-style output stream if any */
694   ostream *errstream;		/* C++-style error stream if any */
695 #endif /* not NOT_LIBPLOTTER */
696 
697   /* device driver parameters (i.e., instance copies of class variables) */
698   void * params[NUM_PLOTTER_PARAMETERS];
699 
700   /* (mostly) user-queryable capabilities: 0/1/2 = no/yes/maybe */
701   int have_wide_lines;
702   int have_dash_array;
703   int have_solid_fill;
704   int have_odd_winding_fill;
705   int have_nonzero_winding_fill;
706   int have_settable_bg;
707   int have_escaped_string_support; /* can plot labels containing escapes? */
708   int have_ps_fonts;
709   int have_pcl_fonts;
710   int have_stick_fonts;
711   int have_extra_stick_fonts;
712   int have_other_fonts;
713 
714   /* text and font-related parameters (internal, not queryable by user) */
715   int default_font_type;	/* PL_F_{HERSHEY|POSTSCRIPT|PCL|STICK} */
716   bool pcl_before_ps;		/* PCL fonts searched first? (if applicable) */
717   bool have_horizontal_justification; /*device can justify text horizontally?*/
718   bool have_vertical_justification; /* device can justify text vertically? */
719   bool kern_stick_fonts;      /* device kerns variable-width HP vector fonts?*/
720   bool issue_font_warning;	/* issue warning on font substitution? */
721 
722   /* path-related parameters (also internal) */
723   int max_unfilled_path_length; /* user-settable, for unfilled polylines */
724   bool have_mixed_paths;	/* can mix arcs/Beziers and lines in paths? */
725   plScalingType allowed_arc_scaling; /* scaling allowed for circular arcs */
726   plScalingType allowed_ellarc_scaling;	/* scaling allowed for elliptic arcs */
727   plScalingType allowed_quad_scaling; /*scaling allowed for quadratic Beziers*/
728   plScalingType allowed_cubic_scaling; /* scaling allowed for cubic Beziers */
729   plScalingType allowed_box_scaling; /* scaling allowed for boxes */
730   plScalingType allowed_circle_scaling; /* scaling allowed for circles */
731   plScalingType allowed_ellipse_scaling; /* scaling allowed for ellipses */
732 
733   /* color-related parameters (also internal) */
734   bool emulate_color;		/* emulate color by grayscale? */
735 
736   /* cache of previously retrieved color names (used for speed) */
737   plColorNameCache *color_name_cache;/* pointer to color name cache */
738 
739   /* info on the device coordinate frame (ranges for viewport in terms of
740      native device coordinates, etc.; note that if flipped_y=true, then
741      jmax<jmin or ymax<ymin) */
742   int display_model_type;	/* one of DISP_MODEL_{PHYSICAL,VIRTUAL} */
743   int display_coors_type;	/* one of DISP_DEVICE_COORS_{REAL, etc.} */
744   bool flipped_y;		/* y increases downward? */
745   int imin, imax, jmin, jmax;	/* ranges, if virtual with integer coors */
746   double xmin, xmax, ymin, ymax; /* ranges, if physical with real coors */
747 
748   /* low-level page and viewport information, if display is physical.
749      Final six parameters are in terms of inches, and can be specified by
750      setting the PAGESIZE Plotter parameter. */
751   const plPageData *page_data;	/* page dimensions and other characteristics */
752   double viewport_xsize, viewport_ysize; /* viewport dimensions (inches) */
753   double viewport_xorigin, viewport_yorigin; /* viewport origin (inches) */
754   double viewport_xoffset, viewport_yoffset; /* viewport origin offset */
755 
756   /* affine transformation from NDC to device coordinates */
757   double m_ndc_to_device[6];	/*  1. a linear transformation (4 elements)
758   				    2. a translation (2 elements) */
759 
760 /* dynamic data members, which are updated during Plotter operation, unlike
761    the many data members above */
762 
763   bool open;			/* D: whether or not Plotter is open */
764   bool opened;			/* D: whether or not Plotter has been opened */
765   int page_number;		/* D: number of times it has been opened */
766   bool fontsize_invoked;	/* D: fontsize() invoked on this page? */
767   bool linewidth_invoked;	/* D: linewidth() invoked on this page? */
768   int frame_number;		/* D: number of frame in page */
769 
770   /* whether warning messages have been issued */
771   bool font_warning_issued;	/* D: issued warning on font substitution */
772   bool pen_color_warning_issued; /* D: issued warning on name substitution */
773   bool fill_color_warning_issued; /* D: issued warning on name substitution */
774   bool bg_color_warning_issued;	/* D: issued warning on name substitution */
775 
776   /* pointers to output buffers, containing graphics code */
777   plOutbuf *page;		/* D: output buffer for current page */
778   plOutbuf *first_page;		/* D: first page (if a linked list is kept) */
779 
780 } plPlotterData;
781 
782 /* The macro Q___ is used for declaring Plotter methods (as function
783    pointers for libplot, and as function members of the Plotter class, for
784    libplotter).  QQ___ is used for declaring PlotterParams methods.  It is
785    the same as Q___, but does not declare the function members as virtual
786    (the PlotterParams class is not derived from). */
787 #ifdef Q___
788 #undef Q___
789 #endif
790 #ifdef NOT_LIBPLOTTER
791 #define Q___(rettype,f) rettype (*f)
792 #define QQ___(rettype,f) rettype (*f)
793 #else  /* LIBPLOTTER */
794 #define Q___(rettype,f) virtual rettype f
795 #define QQ___(rettype,f) rettype f
796 #endif
797 
798 /* Methods of the Plotter class (and derived classes) all have a hidden
799    argument, called `this', which is a pointer to the invoking Plotter
800    instance.  That's a standard C++ convention.  In libplot, we must pass
801    such a pointer explicitly, as an extra argument; we call it `_plotter'.
802    In libplotter, each occurrence of `_plotter' in the body of a Plotter
803    method is mapped to `this'.
804 
805    Since the same code is used for both libplot and libplotter, we use a
806    macro, R___() or S___(), in the declaration and the definition of each
807    Plotter method.  In libplotter, they elide their arguments.  But in
808    libplot, they do not; also, R___() appends a comma.
809 
810    Methods of the PlotterParams helper class are handled similarly.  In
811    libplot, each of them has an extra argument, `_plotter_params'.  This is
812    arranged via R___() or S___().  In libplotter, each occurrence of
813    `_plotter_params' in the body of a PlotterParams method is mapped to
814    `this'. */
815 
816 #ifdef NOT_LIBPLOTTER
817 #define R___(arg1) arg1,
818 #define S___(arg1) arg1
819 #else  /* LIBPLOTTER */
820 #define _plotter this
821 #define _plotter_params this
822 #define R___(arg1)
823 #define S___(arg1)
824 #endif
825 
826 /* The PlotterParams class (or struct) definition.  This is a helper class.
827    Any instance of it holds parameters that are used when instantiating the
828    Plotter class.  */
829 
830 #ifndef NOT_LIBPLOTTER
831 class PlotterParams
832 #else
833 typedef struct plPlotterParamsStruct /* this tag is used only by libplot */
834 #endif
835 {
836 #ifndef NOT_LIBPLOTTER
837  public:
838   /* PlotterParams CTORS AND DTOR; copy constructor, assignment operator */
839   PlotterParams ();
840   ~PlotterParams ();
841   PlotterParams (const PlotterParams& oldPlotterParams);
842   PlotterParams& operator= (const PlotterParams& oldPlotterParams);
843 #endif
844 
845   /* PLOTTERPARAMS PUBLIC METHODS */
846   QQ___(int,setplparam) (R___(struct plPlotterParamsStruct *_plotter_params) const char *parameter, void * value);
847 
848   /* PUBLIC DATA: user-specified (recognized) Plotter parameters */
849   void * plparams[NUM_PLOTTER_PARAMETERS];
850 }
851 #ifdef NOT_LIBPLOTTER
852 PlotterParams;
853 #else  /* not NOT_LIBPLOTTER */
854 ;
855 #endif /* not NOT_LIBPLOTTER */
856 
857 /* The Plotter class (or struct) definition.  There are many members! */
858 
859 #ifndef NOT_LIBPLOTTER
860 class Plotter
861 #else
862 typedef struct plPlotterStruct	/* this tag is used only by libplot */
863 #endif
864 {
865 #ifndef NOT_LIBPLOTTER
866  private:
867   /* disallow copying and assignment */
868   Plotter (const Plotter& oldplotter);
869   Plotter& operator= (const Plotter& oldplotter);
870 
871   /* Private functions related to the drawing of text strings in Hershey
872      fonts (all defined in g_alab_her.c).  In libplot they're declared in
873      libplot/extern.h.  */
874   double _g_alabel_hershey (const unsigned char *s, int x_justify, int y_justify);
875   double _g_flabelwidth_hershey (const unsigned char *s);
876   void _g_draw_hershey_glyph (int num, double charsize, int type, bool oblique);
877   void _g_draw_hershey_penup_stroke (double dx, double dy, double charsize, bool oblique);
878   void _g_draw_hershey_string (const unsigned short *string);
879   void _g_draw_hershey_stroke (bool pendown, double deltax, double deltay);
880 
881   /* Other private functions (a mixed bag).  In libplot they're declared
882      in libplot/extern.h. */
883   double _g_render_non_hershey_string (const char *s, bool do_render, int x_justify, int y_justify);
884   double _g_render_simple_string (const unsigned char *s, bool do_render, int h_just, int v_just);
885   unsigned short * _g_controlify (const unsigned char *);
886   void _g_copy_params_to_plotter (const PlotterParams *params);
887   void _g_create_first_drawing_state (void);
888   void _g_delete_first_drawing_state (void);
889   void _g_free_params_in_plotter (void);
890   void _g_maybe_replace_arc (void);
891   void _g_set_font (void);
892 
893  public:
894   /* PLOTTER CTORS (old-style, not thread-safe) */
895   Plotter (FILE *infile, FILE *outfile, FILE *errfile);
896   Plotter (FILE *outfile);
897   Plotter (istream& in, ostream& out, ostream& err);
898   Plotter (ostream& out);
899   Plotter ();
900   /* PLOTTER CTORS (new-style, thread-safe) */
901   Plotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
902   Plotter (FILE *outfile, PlotterParams &params);
903   Plotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
904   Plotter (ostream& out, PlotterParams &params);
905   Plotter (PlotterParams &params);
906   /* PLOTTER DTOR */
907   virtual ~Plotter ();
908 
909   /* PLOTTER PUBLIC METHOD (static, used by old [non-thread-safe] bindings) */
910   static int parampl (const char *parameter, void * value);
911 
912   /* PLOTTER PUBLIC METHODS.
913 
914      The methods in the libplotter API.  (In libplot, these methods are
915      declared not here, but in extern.h.)
916 
917      Note that in the body of the code, these Plotter methods appear under
918      the names _API_alabel() etc.  Via #define's in extern.h, they're
919      renamed as _pl_alable_r() etc. in libplot, and as Plotter::alabel
920      etc. in libplotter. */
921 
922   int alabel (int x_justify, int y_justify, const char *s);
923   int arc (int xc, int yc, int x0, int y0, int x1, int y1);
924   int arcrel (int dxc, int dyc, int dx0, int dy0, int dx1, int dy1);
925   int bezier2 (int x0, int y0, int x1, int y1, int x2, int y2);
926   int bezier2rel (int dx0, int dy0, int dx1, int dy1, int dx2, int dy2);
927   int bezier3 (int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
928   int bezier3rel (int dx0, int dy0, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
929   int bgcolor (int red, int green, int blue);
930   int bgcolorname (const char *name);
931   int box (int x0, int y0, int x1, int y1);
932   int boxrel (int dx0, int dy0, int dx1, int dy1);
933   int capmod (const char *s);
934   int circle (int x, int y, int r);
935   int circlerel (int dx, int dy, int r);
936   int closepath (void);
937   int closepl (void);
938   int color (int red, int green, int blue);
939   int colorname (const char *name);
940   int cont (int x, int y);
941   int contrel (int dx, int dy);
942   int ellarc (int xc, int yc, int x0, int y0, int x1, int y1);
943   int ellarcrel (int dxc, int dyc, int dx0, int dy0, int dx1, int dy1);
944   int ellipse (int x, int y, int rx, int ry, int angle);
945   int ellipserel (int dx, int dy, int rx, int ry, int angle);
946   int endpath (void);
947   int endsubpath (void);
948   int erase (void);
949   int farc (double xc, double yc, double x0, double y0, double x1, double y1);
950   int farcrel (double dxc, double dyc, double dx0, double dy0, double dx1, double dy1);
951   int fbezier2 (double x0, double y0, double x1, double y1, double x2, double y2);
952   int fbezier2rel (double dx0, double dy0, double dx1, double dy1, double dx2, double dy2);
953   int fbezier3 (double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3);
954   int fbezier3rel (double dx0, double dy0, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3);
955   int fbox (double x0, double y0, double x1, double y1);
956   int fboxrel (double dx0, double dy0, double dx1, double dy1);
957   int fcircle (double x, double y, double r);
958   int fcirclerel (double dx, double dy, double r);
959   int fconcat (double m0, double m1, double m2, double m3, double m4, double m5);
960   int fcont (double x, double y);
961   int fcontrel (double dx, double dy);
962   int fellarc (double xc, double yc, double x0, double y0, double x1, double y1);
963   int fellarcrel (double dxc, double dyc, double dx0, double dy0, double dx1, double dy1);
964   int fellipse (double x, double y, double rx, double ry, double angle);
965   int fellipserel (double dx, double dy, double rx, double ry, double angle);
966   double ffontname (const char *s);
967   double ffontsize (double size);
968   int fillcolor (int red, int green, int blue);
969   int fillcolorname (const char *name);
970   int fillmod (const char *s);
971   int filltype (int level);
972   double flabelwidth (const char *s);
973   int fline (double x0, double y0, double x1, double y1);
974   int flinedash (int n, const double *dashes, double offset);
975   int flinerel (double dx0, double dy0, double dx1, double dy1);
976   int flinewidth (double size);
977   int flushpl (void);
978   int fmarker (double x, double y, int type, double size);
979   int fmarkerrel (double dx, double dy, int type, double size);
980   int fmiterlimit (double limit);
981   int fmove (double x, double y);
982   int fmoverel (double dx, double dy);
983   int fontname (const char *s);
984   int fontsize (int size);
985   int fpoint (double x, double y);
986   int fpointrel (double dx, double dy);
987   int frotate (double theta);
988   int fscale (double x, double y);
989   int fsetmatrix (double m0, double m1, double m2, double m3, double m4, double m5);
990   int fspace (double x0, double y0, double x1, double y1);
991   int fspace2 (double x0, double y0, double x1, double y1, double x2, double y2);
992   double ftextangle (double angle);
993   int ftranslate (double x, double y);
994   int havecap (const char *s);
995   int joinmod (const char *s);
996   int label (const char *s);
997   int labelwidth (const char *s);
998   int line (int x0, int y0, int x1, int y1);
999   int linedash (int n, const int *dashes, int offset);
1000   int linemod (const char *s);
1001   int linerel (int dx0, int dy0, int dx1, int dy1);
1002   int linewidth (int size);
1003   int marker (int x, int y, int type, int size);
1004   int markerrel (int dx, int dy, int type, int size);
1005   int move (int x, int y);
1006   int moverel (int dx, int dy);
1007   int openpl (void);
1008   int orientation (int direction);
1009   FILE* outfile (FILE* newstream); /* OBSOLESCENT */
1010   int pencolor (int red, int green, int blue);
1011   int pencolorname (const char *name);
1012   int pentype (int level);
1013   int point (int x, int y);
1014   int pointrel (int dx, int dy);
1015   int restorestate (void);
1016   int savestate (void);
1017   int space (int x0, int y0, int x1, int y1);
1018   int space2 (int x0, int y0, int x1, int y1, int x2, int y2);
1019   int textangle (int angle);
1020 
1021   /* Undocumented public methods that provide access to the font tables
1022      within libplot/libplotter.  They're used by the graphics programs in
1023      the plotutils package, to display lists of font names.  In libplot
1024      they're declared in libplot/extern.h, rather than here. */
1025   void *_get_hershey_font_info (void);
1026   void *_get_ps_font_info (void);
1027   void *_get_pcl_font_info (void);
1028   void *_get_stick_font_info (void);
1029 
1030  protected:
1031 #endif /* not NOT_LIBPLOTTER */
1032 
1033   /* PLOTTER PROTECTED METHODS.  All virtual, i.e. they're allowed to be
1034      Plotter-specific; the generic versions of these do nothing and are
1035      overridden in derived classes, to define what a Plotter does. */
1036 
1037   /* Initialization (after creation) and termination (before deletion).
1038      These are exceptions to the above rule: they're effectively
1039      constructors and destructors, so even in the generic Plotter class,
1040      they do useful work.  In derived classes they should always invoke
1041      their base counterparts. */
1042   Q___(void,initialize) (S___(struct plPlotterStruct *_plotter));
1043   Q___(void,terminate) (S___(struct plPlotterStruct *_plotter));
1044 
1045   /* Internal page-related methods, called by the API methods openpl(),
1046      erase() and closepl().  `true' return value indicates operation
1047      performed successfully. */
1048   Q___(bool,begin_page) (S___(struct plPlotterStruct *_plotter));
1049   Q___(bool,erase_page) (S___(struct plPlotterStruct *_plotter));
1050   Q___(bool,end_page) (S___(struct plPlotterStruct *_plotter));
1051 
1052   /* Internal `push state' method, called by the API method savestate().
1053      This is used by a very few types of Plotter to create or initialize
1054      Plotter-specific fields in a newly created drawing state.  Most
1055      Plotters don't override the generic version, which simply copies such
1056      Plotter-specific fields. */
1057   Q___(void,push_state) (S___(struct plPlotterStruct *_plotter));
1058 
1059   /* Internal `pop state' method, called by the API method restorestate().
1060      This is used by a very few types of Plotter to delete or tear down
1061      Plotter-specific fields in a drawing state about to be destroyed.
1062      Most Plotters don't override the generic version, which does nothing
1063      to such fields. */
1064   Q___(void,pop_state) (S___(struct plPlotterStruct *_plotter));
1065 
1066   /* Internal `paint path' method, called when the API method endpath() is
1067      invoked, to draw any path that has been built up in a Plotter's
1068      drawing state.  It should paint a single simple path.  The generic
1069      version of course does nothing. */
1070   Q___(void,paint_path) (S___(struct plPlotterStruct *_plotter));
1071 
1072   /* Another internal method, called by endpath() first, if the path to
1073      paint is compound rather than simple.  If the Plotter can paint the
1074      compound path, this should return `true'; if `false' is returned,
1075      endpath() will paint using compound path emulation instead.  The
1076      generic version does nothing, but returns `true'. */
1077   Q___(bool,paint_paths) (S___(struct plPlotterStruct *_plotter));
1078 
1079   /* Support for flushing out the path buffer when it gets too long.  In
1080      any Plotter, this predicate is evaluated after any path element is
1081      added to the path buffer, provided (1) the path buffer has become
1082      greater than or equal to the `max_unfilled_path_length' Plotter
1083      parameter, and (2) the path isn't to be filled.  In most Plotters,
1084      including generic Plotters, this simply returns `true', to indicate
1085      that the path should be flushed out by invoking endpath().  But in
1086      Plotters that plot in real time under some circumstances (see below),
1087      this normally returns `false' under those circumstances. */
1088   Q___(bool,path_is_flushable) (S___(struct plPlotterStruct *_plotter));
1089 
1090   /* Support for real-time plotting, if desired.  An internal `prepaint
1091      segments' method, called not when a path is finished by endpath()
1092      being called, but rather when any single segment is added to it.  (Or
1093      when several segments, obtained by polygonalizing a higher-level
1094      primitive, are added to it.)  Only in Plotters that plot in real time
1095      (by definition!) is this not a no-op. */
1096   Q___(void,maybe_prepaint_segments) (R___(struct plPlotterStruct *_plotter) int prev_num_segments);
1097 
1098   /* Internal `draw marker' method, called when the API method marker() is
1099      invoked.  Only a very few types of Plotter use this.  Return value
1100      should indicate whether the marker was drawn; `false' means that a
1101      generic drawing routine, which creates a marker from other libplot
1102      primitives, should be used.  (Yes, some Plotter output formats support
1103      some types of marker but not others!).  The generic version does nothing,
1104      but returns `false'. */
1105   Q___(bool,paint_marker) (R___(struct plPlotterStruct *_plotter) int type, double size);
1106 
1107   /* Internal `draw point' method, called when the API method point() is
1108      invoked.  There's no standard definition of a `point', so Plotters are
1109      free to implement this as they see fit. */
1110   Q___(void,paint_point) (S___(struct plPlotterStruct *_plotter));
1111 
1112   /* Internal, Plotter-specific versions of the `alabel' and `flabelwidth'
1113      methods, which are applied to single-line text strings in a single
1114      font (no escape sequences, etc.).  The API methods alabel and
1115      flabelwidth are wrappers around these.
1116 
1117      The argument h_just specifies the justification to be used when
1118      rendering (PL_JUST_LEFT, PL_JUST_RIGHT, or PL_JUST_CENTER).  If a
1119      display device provides low-level support for non-default
1120      (i.e. non-left) justification, the Plotter's
1121      have_horizontal_justification flag (see below) should be set.
1122      Similarly, v_just specifies vertical justification (PL_JUST_TOP,
1123      PL_JUST_HALF, PL_JUST_BASE, PL_JUST_BOTTOM, or PL_JUST_CAP). */
1124 
1125   /* The first of these is special, for use by Metafile Plotters only.  Any
1126      Metafile Plotter has low-level support for drawing labels that include
1127      any of our many escape sequences.  (Actually, a Metafile Plotter just
1128      dumps them to the output stream, unchanged. :-)).  So the Metafile
1129      Plotter class has a special _m_paint_text_string_with_escapes method.
1130      In all other Plotters, the paint_text_string_with_escapes method
1131      should be set to the dummy _g_paint_text_string_with_escapes method,
1132      which does nothing; it'll never be invoked.  Our code recognizes that
1133      a Metafile Plotter is special by looking at the Plotter's
1134      `have_escaped_string_support' capability, which is `1' for a Metafile
1135      Plotter and `0' for all others. */
1136 
1137   Q___(void,paint_text_string_with_escapes) (R___(struct plPlotterStruct *_plotter) const unsigned char *s, int x_justify, int y_justify);
1138 
1139   Q___(double,paint_text_string) (R___(struct plPlotterStruct *_plotter) const unsigned char *s, int h_just, int v_just);
1140   Q___(double,get_text_width) (R___(struct plPlotterStruct *_plotter) const unsigned char *s);
1141 
1142   /* Low-level, Plotter-specific `retrieve font' function; called by the
1143      internal _set_font() function, which in turn is called by the API
1144      methods alabel() and labelwidth(), and by the API methods
1145      fontname()/fontsize()/textwidth(), but only because they need to
1146      return a font size.  retrieve_font() is called only if the
1147      user-specified font is a non-Hershey font.  If it returns false, a
1148      default font, e.g., a Hershey font, will be substituted. */
1149   Q___(bool,retrieve_font) (S___(struct plPlotterStruct *_plotter));
1150 
1151   /* Internal `flush output' method, called by the API method flushpl().
1152      This is called only if the Plotter does its own output, i.e., does not
1153      write to an output stream.  I.e., only if the Plotter's `output_model'
1154      data element is PL_OUTPUT_VIA_CUSTOM_ROUTINES_TO_NON_STREAM.  Return
1155      value indicates whether flushing worked. */
1156   Q___(bool,flush_output) (S___(struct plPlotterStruct *_plotter));
1157 
1158   /* error handlers */
1159   Q___(void,warning) (R___(struct plPlotterStruct *_plotter) const char *msg);
1160   Q___(void,error) (R___(struct plPlotterStruct *_plotter) const char *msg);
1161 
1162   /* PLOTTER DATA MEMBERS (not specific to any one device driver).  These
1163      are protected rather than private, so they can be accessed by derived
1164      classes. */
1165 
1166   /* Basic data members: many parameters affecting Plotter operation, which
1167      are set by the initialize() method and not changed thereafter, plus a
1168      few (e.g., pointers to plOutbuf's for holding graphics code) which may
1169      change at later times. */
1170   plPlotterData *data;
1171 
1172   /* drawing state stack (pointer to top) */
1173   plDrawState *drawstate;
1174 
1175 #ifdef NOT_LIBPLOTTER
1176   /* PLOTTER DATA MEMBERS (device driver-specific). */
1177   /* In libplot, they appear here, i.e., in the Plotter struct.  But in
1178      libplotter, they don't appear here, i.e. they don't appear in the base
1179      Plotter class: they appear, more logically, as private or protected
1180      data members of the appropriate derived classes (for the definitions
1181      of which, see further below in this file). */
1182 
1183   /* Some of these are constant over the usable lifetime of the Plotter,
1184      and are set, at latest, in the first call to begin_page().  They are
1185      just parameters.  Other data members may change, since they represent
1186      our knowledge of the display device's internal state.  Each of the
1187      latter is flagged by "D:" (i.e. "dynamic") in its comment line. */
1188 
1189   /* data members specific to Bitmap Plotters */
1190   void * b_arc_cache_data;	/* pointer to cache (used by miPolyArc_r) */
1191   int b_xn, b_yn;		/* bitmap dimensions */
1192   void * b_painted_set;	/* D: libxmi's canvas (a (miPaintedSet *)) */
1193   void * b_canvas;		/* D: libxmi's canvas (a (miCanvas *)) */
1194   /* data members specific to Metafile Plotters */
1195   /* 0. parameters */
1196   bool meta_portable_output;	/* portable, not binary output format? */
1197   /* 1. dynamic attributes, general */
1198   plPoint meta_pos;		/* graphics cursor position */
1199   bool meta_position_is_unknown; /* position is unknown? */
1200   double meta_m_user_to_ndc[6];	/* user->NDC transformation matrix */
1201   /* 2. dynamic attributes, path-related */
1202   int meta_fill_rule_type;	/* one of PL_FILL_*, determined by fill rule */
1203   int meta_line_type;		/* one of PL_L_*, determined by line mode */
1204   bool meta_points_are_connected; /* if not set, path displayed as points */
1205   int meta_cap_type;		/* one of PL_CAP_*, determined by cap mode */
1206   int meta_join_type;		/* one of PL_JOIN_*, determined by join mode */
1207   double meta_miter_limit;	/* miter limit for line joins */
1208   double meta_line_width;	/* width of lines in user coordinates */
1209   bool meta_line_width_is_default; /* line width is default value? */
1210   const double *meta_dash_array; /* array of dash on/off lengths(nonnegative)*/
1211   int meta_dash_array_len;	/* length of same */
1212   double meta_dash_offset;	/* offset distance into dash array (`phase') */
1213   bool meta_dash_array_in_effect; /* dash array should override line mode? */
1214   int meta_pen_type;		/* pen type (0 = no pen, 1 = pen) */
1215   int meta_fill_type;		/* fill type (0 = no fill, 1 = fill, ...) */
1216   int meta_orientation;	        /* orientation of circles etc.(1=c'clockwise)*/
1217   /* 3. dynamic attributes, text-related */
1218   const char *meta_font_name;	/* font name */
1219   double meta_font_size;	/* font size in user coordinates */
1220   bool meta_font_size_is_default; /* font size is Plotter default? */
1221   double meta_text_rotation;	/* degrees counterclockwise, for labels */
1222   /* 4. dynamic color attributes (fgcolor and fillcolor are path-related;
1223      fgcolor affects other primitives too) */
1224   plColor meta_fgcolor;		/* foreground color, i.e., pen color */
1225   plColor meta_fillcolor_base;	/* fill color */
1226   plColor meta_bgcolor;		/* background color for graphics display */
1227   /* data members specific to Tektronix Plotters */
1228   int tek_display_type;		/* which sort of Tektronix? (one of TEK_DPY_*) */
1229   int tek_mode;			/* D: one of TEK_MODE_* */
1230   int tek_line_type;		/* D: one of PL_L_* */
1231   bool tek_mode_is_unknown;	/* D: tek mode unknown? */
1232   bool tek_line_type_is_unknown; /* D: tek line type unknown? */
1233   int tek_kermit_fgcolor;	/* D: kermit's foreground color */
1234   int tek_kermit_bgcolor;	/* D: kermit's background color */
1235   bool tek_position_is_unknown;	/* D: cursor position is unknown? */
1236   plIntPoint tek_pos;		/* D: Tektronix cursor position */
1237   /* data members specific to ReGIS Plotters */
1238   plIntPoint regis_pos;		/* D: ReGIS graphics cursor position */
1239   bool regis_position_is_unknown; /* D: graphics cursor position is unknown? */
1240   int regis_line_type;		/* D: native ReGIS line type */
1241   bool regis_line_type_is_unknown; /* D: ReGIS line type is unknown? */
1242   int regis_fgcolor;		/* D: ReGIS foreground color, in range 0..7 */
1243   int regis_bgcolor;		/* D: ReGIS background color, in range 0..7 */
1244   bool regis_fgcolor_is_unknown; /* D: foreground color unknown? */
1245   bool regis_bgcolor_is_unknown; /* D: background color unknown? */
1246   /* data members specific to HP-GL (and PCL) Plotters */
1247   int hpgl_version;		/* version: 0=HP-GL, 1=HP7550A, 2=HP-GL/2 */
1248   int hpgl_rotation;		/* rotation angle (0, 90, 180, or 270) */
1249   double hpgl_plot_length;	/* plot length (for HP-GL/2 roll plotters) */
1250   plPoint hpgl_p1;		/* scaling point P1 in native HP-GL coors */
1251   plPoint hpgl_p2;		/* scaling point P2 in native HP-GL coors */
1252   bool hpgl_have_screened_vectors; /* can shade pen marks? (HP-GL/2 only) */
1253   bool hpgl_have_char_fill;	/* can shade char interiors? (HP-GL/2 only) */
1254   bool hpgl_can_assign_colors;	/* can assign pen colors? (HP-GL/2 only) */
1255   bool hpgl_use_opaque_mode;	/* pen marks sh'd be opaque? (HP-GL/2 only) */
1256   plColor hpgl_pen_color[HPGL2_MAX_NUM_PENS]; /* D: color array for pens */
1257   int hpgl_pen_defined[HPGL2_MAX_NUM_PENS];/*D:0=none,1=soft-defd,2=hard-defd*/
1258   int hpgl_pen;			/* D: number of currently selected pen */
1259   int hpgl_free_pen;		/* D: pen to be assigned a color next */
1260   bool hpgl_bad_pen;		/* D: bad pen (advisory, see h_color.c) */
1261   bool hpgl_pendown;		/* D: pen down rather than up? */
1262   double hpgl_pen_width;	/* D: pen width(frac of diag dist betw P1,P2)*/
1263   int hpgl_line_type;		/* D: line type(HP-GL numbering,solid = -100)*/
1264   int hpgl_cap_style;		/* D: cap style for lines (HP-GL/2 numbering)*/
1265   int hpgl_join_style;		/* D: join style for lines(HP-GL/2 numbering)*/
1266   double hpgl_miter_limit;	/* D: miterlimit for line joins(HP-GL/2 only)*/
1267   int hpgl_pen_type;		/* D: sv type (e.g. HPGL_PEN_{SOLID|SHADED}) */
1268   double hpgl_pen_option1;	/* D: used for some screened vector types */
1269   double hpgl_pen_option2;	/* D: used for some screened vector types */
1270   int hpgl_fill_type;		/* D: fill type (one of FILL_SOLID_UNI etc.) */
1271   double hpgl_fill_option1;	/* D: used for some fill types */
1272   double hpgl_fill_option2;	/* D: used for some fill types */
1273   int hpgl_char_rendering_type;	/* D: character rendering type (fill/edge) */
1274   int hpgl_symbol_set;		/* D: encoding, 14=ISO-Latin-1 (HP-GL/2 only)*/
1275   int hpgl_spacing;		/* D: fontspacing,0=fixed,1=not(HP-GL/2 only)*/
1276   int hpgl_posture;		/* D: posture,0=uprite,1=italic(HP-GL/2 only)*/
1277   int hpgl_stroke_weight;	/* D: weight,0=normal,3=bold,..(HP-GL/2only)*/
1278   int hpgl_pcl_typeface;	/* D: PCL typeface, see g_fontdb.c (HP-GL/2) */
1279   int hpgl_charset_lower;	/* D: HP lower-half charset no. (pre-HP-GL/2)*/
1280   int hpgl_charset_upper;	/* D: HP upper-half charset no. (pre-HP-GL/2)*/
1281   double hpgl_rel_char_height;	/* D: char ht., % of p2y-p1y (HP-GL/2 only) */
1282   double hpgl_rel_char_width;	/* D: char width, % of p2x-p1x (HP-GL/2 only)*/
1283   double hpgl_rel_label_rise;	/* D: label rise, % of p2y-p1y (HP-GL/2 only)*/
1284   double hpgl_rel_label_run;	/* D: label run, % of p2x-p1x (HP-GL/2 only) */
1285   double hpgl_tan_char_slant;	/* D: tan of character slant (HP-GL/2 only)*/
1286   bool hpgl_position_is_unknown; /* D: HP-GL[/2] cursor position is unknown? */
1287   plIntPoint hpgl_pos;		/* D: cursor position (integer HP-GL coors) */
1288 /* data members specific to Fig Plotters */
1289   int fig_drawing_depth;	/* D: fig's curr value for `depth' attribute */
1290   int fig_num_usercolors;	/* D: number of colors currently defined */
1291   long int fig_usercolors[FIG_MAX_NUM_USER_COLORS]; /* D: colors we've def'd */
1292   bool fig_colormap_warning_issued; /* D: issued warning on colormap filling up*/
1293 /* data members specific to CGM Plotters */
1294   int cgm_encoding;		/* CGM_ENCODING_{BINARY,CHARACTER,CLEAR_TEXT}*/
1295   int cgm_max_version;		/* upper bound on CGM version number */
1296   int cgm_version;		/* D: CGM version for file (1, 2, 3, or 4) */
1297   int cgm_profile;		/* D: CGM_PROFILE_{WEB,MODEL,NONE} */
1298   int cgm_need_color;		/* D: non-monochrome? */
1299   int cgm_page_version;		/* D: CGM version for current page */
1300   int cgm_page_profile;		/* D: CGM_PROFILE_{WEB,MODEL,NONE} */
1301   bool cgm_page_need_color;	/* D: current page is non-monochrome? */
1302   plColor cgm_line_color;	/* D: line pen color (24-bit or 48-bit RGB) */
1303   plColor cgm_edge_color;	/* D: edge pen color (24-bit or 48-bit RGB) */
1304   plColor cgm_fillcolor;	/* D: fill color (24-bit or 48-bit RGB) */
1305   plColor cgm_marker_color;	/* D: marker pen color (24-bit or 48-bit RGB)*/
1306   plColor cgm_text_color;	/* D: text pen color (24-bit or 48-bit RGB) */
1307   plColor cgm_bgcolor;		/* D: background color (24-bit or 48-bit RGB)*/
1308   bool cgm_bgcolor_suppressed;	/* D: background color suppressed? */
1309   int cgm_line_type;		/* D: one of CGM_L_{SOLID, etc.} */
1310   double cgm_dash_offset;	/* D: offset into dash array (`phase') */
1311   int cgm_join_style;		/* D: join style for lines (CGM numbering)*/
1312   int cgm_cap_style;		/* D: cap style for lines (CGM numbering)*/
1313   int cgm_dash_cap_style;	/* D: dash cap style for lines(CGM numbering)*/
1314   int cgm_line_width;		/* D: line width in CGM coordinates */
1315   int cgm_interior_style;	/* D: one of CGM_INT_STYLE_{EMPTY, etc.} */
1316   int cgm_edge_type;		/* D: one of CGM_L_{SOLID, etc.} */
1317   double cgm_edge_dash_offset;	/* D: offset into dash array (`phase') */
1318   int cgm_edge_join_style;	/* D: join style for edges (CGM numbering)*/
1319   int cgm_edge_cap_style;	/* D: cap style for edges (CGM numbering)*/
1320   int cgm_edge_dash_cap_style;	/* D: dash cap style for edges(CGM numbering)*/
1321   int cgm_edge_width;		/* D: edge width in CGM coordinates */
1322   bool cgm_edge_is_visible;	/* D: filled regions have edges? */
1323   double cgm_miter_limit;	/* D: CGM's miter limit */
1324   int cgm_marker_type;		/* D: one of CGM_M_{DOT, etc.} */
1325   int cgm_marker_size;		/* D: marker size in CGM coordinates */
1326   int cgm_char_height;		/* D: character height */
1327   int cgm_char_base_vector_x;	/* D: character base vector */
1328   int cgm_char_base_vector_y;
1329   int cgm_char_up_vector_x;	/* D: character up vector */
1330   int cgm_char_up_vector_y;
1331   int cgm_horizontal_text_alignment; /* D: one of CGM_ALIGN_* */
1332   int cgm_vertical_text_alignment; /* D: one of CGM_ALIGN_* */
1333   int cgm_font_id;		/* D: PS font in range 0..34 */
1334   int cgm_charset_lower;	/* D: lower charset (index into defined list)*/
1335   int cgm_charset_upper;	/* D: upper charset (index into defined list)*/
1336   int cgm_restricted_text_type;	/* D: one of CGM_RESTRICTED_TEXT_TYPE_* */
1337 /* data members specific to Illustrator Plotters */
1338   int ai_version;		/* AI version 3 or AI version 5? */
1339   double ai_pen_cyan;		/* D: pen color (in CMYK space) */
1340   double ai_pen_magenta;
1341   double ai_pen_yellow;
1342   double ai_pen_black;
1343   double ai_fill_cyan;		/* D: fill color (in CMYK space) */
1344   double ai_fill_magenta;
1345   double ai_fill_yellow;
1346   double ai_fill_black;
1347   bool ai_cyan_used;		/* D: C, M, Y, K have been used? */
1348   bool ai_magenta_used;
1349   bool ai_yellow_used;
1350   bool ai_black_used;
1351   int ai_cap_style;		/* D: cap style for lines (PS numbering) */
1352   int ai_join_style;		/* D: join style for lines (PS numbering) */
1353   double ai_miter_limit;	/* D: miterlimit for line joins */
1354   int ai_line_type;		/* D: one of PL_L_* */
1355   double ai_line_width;		/* D: line width in printer's points */
1356   int ai_fill_rule_type;	/* D: fill rule (AI_FILL_{ODD|NONZERO}_WINDING) */
1357 /* data members specific to SVG Plotters */
1358   double s_matrix[6];		/* D: default transformation matrix for page */
1359   bool s_matrix_is_unknown;	/* D: matrix has not yet been set? */
1360   bool s_matrix_is_bogus;	/* D: matrix has been set, but is bogus? */
1361   plColor s_bgcolor;		/* D: background color (RGB) */
1362   bool s_bgcolor_suppressed;	/* D: background color suppressed? */
1363 /* data members specific to PNM Plotters (derived from Bitmap Plotters) */
1364   bool n_portable_output;	/* portable, not binary output format? */
1365 #ifdef INCLUDE_PNG_SUPPORT
1366 /* data members specific to PNG Plotters (derived from Bitmap Plotters) */
1367   bool z_interlace;		/* interlaced PNG? */
1368   bool z_transparent;		/* transparent PNG? */
1369   plColor z_transparent_color;	/* if so, transparent color (24-bit RGB) */
1370 #endif /* INCLUDE_PNG_SUPPORT */
1371 /* data members specific to GIF Plotters */
1372   int i_xn, i_yn;		/* bitmap dimensions */
1373   int i_num_pixels;		/* total pixels (used by scanner) */
1374   bool i_animation;		/* animated (multi-image) GIF? */
1375   int i_iterations;		/* number of times GIF should be looped */
1376   int i_delay;			/* delay after image, in 1/100 sec units */
1377   bool i_interlace;		/* interlaced GIF? */
1378   bool i_transparent;		/* transparent GIF? */
1379   plColor i_transparent_color;	/* if so, transparent color (24-bit RGB) */
1380   void * i_arc_cache_data;	/* pointer to cache (used by miPolyArc_r) */
1381   int i_transparent_index;	/* D: transparent color index (if any) */
1382   void * i_painted_set;	/* D: libxmi's canvas (a (miPaintedSet *)) */
1383   void * i_canvas;		/* D: libxmi's canvas (a (miCanvas *)) */
1384   plColor i_colormap[256];	/* D: frame colormap (containing 24-bit RGBs)*/
1385   int i_num_color_indices;	/* D: number of color indices allocated */
1386   bool i_frame_nonempty;	/* D: something drawn in current frame? */
1387   int i_bit_depth;		/* D: bit depth (ceil(log2(num_indices))) */
1388   int i_pixels_scanned;		/* D: number that scanner has scanned */
1389   int i_pass;			/* D: scanner pass (used if interlacing) */
1390   plIntPoint i_hot;		/* D: scanner hot spot */
1391   plColor i_global_colormap[256]; /* D: colormap for first frame (stashed) */
1392   int i_num_global_color_indices;/* D: number of indices in global colormap */
1393   bool i_header_written;	/* D: GIF header written yet? */
1394 #ifndef X_DISPLAY_MISSING
1395 /* data members specific to X Drawable Plotters and X Plotters */
1396   Display *x_dpy;		/* X display */
1397   Visual *x_visual;		/* X visual */
1398   Drawable x_drawable1;		/* an X drawable (e.g. a pixmap) */
1399   Drawable x_drawable2;		/* an X drawable (e.g. a window) */
1400   Drawable x_drawable3;		/* graphics buffer, if double buffering */
1401   int x_double_buffering;	/* double buffering type (if any) */
1402   long int x_max_polyline_len;	/* limit on polyline len (X display-specific)*/
1403   plXFontRecord *x_fontlist;	/* D: head of list of retrieved X fonts */
1404   plColorRecord *x_colorlist;	/* D: head of list of retrieved X color cells*/
1405   Colormap x_cmap;		/* D: colormap */
1406   int x_cmap_type;		/* D: colormap type (orig./copied/bad) */
1407   bool x_colormap_warning_issued; /* D: issued warning on colormap filling up*/
1408   bool x_bg_color_warning_issued; /* D: issued warning on bg color */
1409   int x_paint_pixel_count;	/* D: times point() is invoked to set a pixel*/
1410 /* additional data members specific to X Plotters */
1411   XtAppContext y_app_con;	/* application context */
1412   Widget y_toplevel;		/* toplevel widget */
1413   Widget y_canvas;		/* Label widget */
1414   Drawable y_drawable4;		/* used for server-side double buffering */
1415   bool y_auto_flush;		/* do an XFlush() after each drawing op? */
1416   bool y_vanish_on_delete;	/* window(s) disappear on Plotter deletion? */
1417   pid_t *y_pids;		/* D: list of pids of forked-off processes */
1418   int y_num_pids;		/* D: number of pids in list */
1419   int y_event_handler_count;	/* D: times that event handler is invoked */
1420 #endif /* not X_DISPLAY_MISSING */
1421 #endif /* NOT_LIBPLOTTER */
1422 
1423 #ifndef NOT_LIBPLOTTER
1424   /* STATIC DATA MEMBERS, protected, which are defined in g_defplot.c.  (In
1425      libplot, these variables are globals, rather than static members of
1426      the Plotter class.  That's arranged by #ifdef's in libplot/extern.h.)  */
1427 
1428   /* These maintain a sparse array of pointers to Plotter instances. */
1429   static Plotter **_plotters;	/* D: sparse array of Plotter instances */
1430   static int _plotters_len;	/* D: length of sparse array */
1431 
1432   /* This stores the global Plotter parameters used by the old,
1433      non-thread-safe C++ binding (the user specifies them with
1434      Plotter::parampl). */
1435   static PlotterParams *_old_api_global_plotter_params;
1436 #endif /* not NOT_LIBPLOTTER */
1437 
1438   /* PLOTTER PROTECTED FUNCTIONS.  In libplotter they're declared here, as
1439      protected members of the base Plotter class.  (In libplot they're
1440      declared in libplot/extern.h.)  Since they're protected, derived
1441      classes can access them, i.e. call them.  */
1442 
1443 #ifndef NOT_LIBPLOTTER
1444   void _flush_plotter_outstreams (void);
1445 #endif /* NOT_LIBPLOTTER */
1446 
1447 }
1448 #ifdef NOT_LIBPLOTTER
1449 Plotter;
1450 #else  /* not NOT_LIBPLOTTER */
1451 ;
1452 #endif /* not NOT_LIBPLOTTER */
1453 
1454 #undef Q___
1455 
1456 
1457 #ifndef NOT_LIBPLOTTER
1458 /****************** DERIVED CLASSES (libplotter only) ********************/
1459 
1460 /* The derived Plotter classes extensively override the generic Plotter
1461    methods; the non-private ones, at least.  Note that in libplot, this
1462    overriding is accomplished differently: `derived' Plotter structs are
1463    initialized to contain function pointers that may point to the
1464    non-generic methods.  The files ?_defplot.c contain the structures
1465    which, in libplot, are used to initialize the function-pointer part of
1466    the derived Plotter structs.
1467 
1468    The device-specific data members which, in libplot, all appear in every
1469    Plotter struct, are in libplotter spread among the derived Plotter
1470    classes, as they logically should be.  */
1471 
1472 /* The MetaPlotter class, which produces GNU metafile output */
1473 class MetaPlotter : public Plotter
1474 {
1475  private:
1476   /* disallow copying and assignment */
1477   MetaPlotter (const MetaPlotter& oldplotter);
1478   MetaPlotter& operator= (const MetaPlotter& oldplotter);
1479  public:
1480   /* ctors (old-style, not thread-safe) */
1481   MetaPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1482   MetaPlotter (FILE *outfile);
1483   MetaPlotter (istream& in, ostream& out, ostream& err);
1484   MetaPlotter (ostream& out);
1485   MetaPlotter ();
1486   /* ctors (new-style, thread-safe) */
1487   MetaPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1488   MetaPlotter (FILE *outfile, PlotterParams &params);
1489   MetaPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1490   MetaPlotter (ostream& out, PlotterParams &params);
1491   MetaPlotter (PlotterParams &params);
1492   /* dtor */
1493   virtual ~MetaPlotter ();
1494  protected:
1495   /* protected methods (overriding Plotter methods) */
1496   bool begin_page (void);
1497   bool end_page (void);
1498   bool erase_page (void);
1499   bool paint_marker (int type, double size);
1500   bool paint_paths (void);
1501   bool path_is_flushable (void);
1502   void paint_text_string_with_escapes (const unsigned char *s, int h_just, int v_just);
1503   void initialize (void);
1504   void maybe_prepaint_segments (int prev_num_segments);
1505   void paint_path (void);
1506   void paint_point (void);
1507   void terminate (void);
1508   /* MetaPlotter-specific internal functions */
1509   void _m_emit_integer (int x);
1510   void _m_emit_float (double x);
1511   void _m_emit_op_code (int c);
1512   void _m_emit_string (const char *s);
1513   void _m_emit_terminator (void);
1514   void _m_paint_path_internal (const plPath *path);
1515   void _m_set_attributes (unsigned int mask);
1516   /* MetaPlotter-specific data members */
1517   /* 0. parameters */
1518   bool meta_portable_output;	/* portable, not binary output format? */
1519   /* 1. dynamic attributes, general */
1520   plPoint meta_pos;		/* graphics cursor position */
1521   bool meta_position_is_unknown; /* position is unknown? */
1522   double meta_m_user_to_ndc[6];	/* user->NDC transformation matrix */
1523   /* 2. dynamic attributes, path-related */
1524   int meta_fill_rule_type;	/* one of PL_FILL_*, determined by fill rule */
1525   int meta_line_type;		/* one of L_*, determined by line mode */
1526   bool meta_points_are_connected; /* if not set, path displayed as points */
1527   int meta_cap_type;		/* one of PL_CAP_*, determined by cap mode */
1528   int meta_join_type;		/* one of PL_JOIN_*, determined by join mode */
1529   double meta_miter_limit;	/* miter limit for line joins */
1530   double meta_line_width;	/* width of lines in user coordinates */
1531   bool meta_line_width_is_default; /* line width is default value? */
1532   const double *meta_dash_array; /* array of dash on/off lengths(nonnegative)*/
1533   int meta_dash_array_len;	/* length of same */
1534   double meta_dash_offset;	/* offset distance into dash array (`phase') */
1535   bool meta_dash_array_in_effect; /* dash array should override line mode? */
1536   int meta_pen_type;		/* pen type (0 = no pen, 1 = pen) */
1537   int meta_fill_type;		/* fill type (0 = no fill, 1 = fill, ...) */
1538   int meta_orientation;	        /* orientation of circles etc.(1=c'clockwise)*/
1539   /* 3. dynamic attributes, text-related */
1540   const char *meta_font_name;	/* font name */
1541   double meta_font_size;	/* font size in user coordinates */
1542   bool meta_font_size_is_default; /* font size is Plotter default? */
1543   double meta_text_rotation;	/* degrees counterclockwise, for labels */
1544   /* 4. dynamic color attributes (fgcolor and fillcolor are path-related;
1545      fgcolor affects other primitives too) */
1546   plColor meta_fgcolor;		/* foreground color, i.e., pen color */
1547   plColor meta_fillcolor_base;	/* fill color */
1548   plColor meta_bgcolor;		/* background color for graphics display */
1549 };
1550 
1551 /* The BitmapPlotter class, from which PNMPlotter and PNGPlotter are derived */
1552 class BitmapPlotter : public Plotter
1553 {
1554  private:
1555   /* disallow copying and assignment */
1556   BitmapPlotter (const BitmapPlotter& oldplotter);
1557   BitmapPlotter& operator= (const BitmapPlotter& oldplotter);
1558  public:
1559   /* ctors (old-style, not thread-safe) */
1560   BitmapPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1561   BitmapPlotter (FILE *outfile);
1562   BitmapPlotter (istream& in, ostream& out, ostream& err);
1563   BitmapPlotter (ostream& out);
1564   BitmapPlotter ();
1565   /* ctors (new-style, thread-safe) */
1566   BitmapPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1567   BitmapPlotter (FILE *outfile, PlotterParams &params);
1568   BitmapPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1569   BitmapPlotter (ostream& out, PlotterParams &params);
1570   BitmapPlotter (PlotterParams &params);
1571   /* dtor */
1572   virtual ~BitmapPlotter ();
1573  protected:
1574   /* protected methods (overriding Plotter methods) */
1575   bool begin_page (void);
1576   bool erase_page (void);
1577   bool end_page (void);
1578   void paint_point (void);
1579   void initialize (void);
1580   void terminate (void);
1581   void paint_path (void);
1582   bool paint_paths (void);
1583   /* internal functions that are overridden in derived classes (crocks) */
1584   virtual int _maybe_output_image (void);
1585   /* BitmapPlotter-specific internal functions */
1586   void _b_delete_image (void);
1587   void _b_draw_elliptic_arc (plPoint p0, plPoint p1, plPoint pc);
1588   void _b_draw_elliptic_arc_2 (plPoint p0, plPoint p1, plPoint pc);
1589   void _b_draw_elliptic_arc_internal (int xorigin, int yorigin, unsigned int squaresize_x, unsigned int squaresize_y, int startangle, int anglerange);
1590   void _b_new_image (void);
1591   /* BitmapPlotter-specific data members */
1592   void * b_arc_cache_data;	/* pointer to cache (used by miPolyArc_r) */
1593   int b_xn, b_yn;		/* bitmap dimensions */
1594   void * b_painted_set;	/* D: libxmi's canvas (a (miPaintedSet *)) */
1595   void * b_canvas;		/* D: libxmi's canvas (a (miCanvas *)) */
1596 };
1597 
1598 /* The TekPlotter class, which produces Tektronix output */
1599 class TekPlotter : public Plotter
1600 {
1601  private:
1602   /* disallow copying and assignment */
1603   TekPlotter (const TekPlotter& oldplotter);
1604   TekPlotter& operator= (const TekPlotter& oldplotter);
1605  public:
1606   /* ctors (old-style, not thread-safe) */
1607   TekPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1608   TekPlotter (FILE *outfile);
1609   TekPlotter (istream& in, ostream& out, ostream& err);
1610   TekPlotter (ostream& out);
1611   TekPlotter ();
1612   /* ctors (new-style, thread-safe) */
1613   TekPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1614   TekPlotter (FILE *outfile, PlotterParams &params);
1615   TekPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1616   TekPlotter (ostream& out, PlotterParams &params);
1617   TekPlotter (PlotterParams &params);
1618   /* dtor */
1619   virtual ~TekPlotter ();
1620  protected:
1621   /* protected methods (overriding Plotter methods) */
1622   bool begin_page (void);
1623   bool erase_page (void);
1624   bool end_page (void);
1625   bool path_is_flushable (void);
1626   void paint_point (void);
1627   void initialize (void);
1628   void terminate (void);
1629   void maybe_prepaint_segments (int prev_num_segments);
1630   /* TekPlotter-specific internal functions */
1631   void _t_set_attributes (void);
1632   void _t_set_bg_color (void);
1633   void _t_set_pen_color (void);
1634   void _t_tek_mode (int newmode);
1635   void _t_tek_move (int xx, int yy);
1636   void _t_tek_vector (int xx, int yy);
1637   void _t_tek_vector_compressed (int xx, int yy, int oldxx, int oldyy, bool force);
1638   /* TekPlotter-specific data members */
1639   int tek_display_type;		/* which sort of Tektronix? (one of TEK_DPY_*) */
1640   int tek_mode;			/* D: one of TEK_MODE_* */
1641   int tek_line_type;		/* D: one of PL_L_* */
1642   bool tek_mode_is_unknown;	/* D: tek mode unknown? */
1643   bool tek_line_type_is_unknown; /* D: tek line type unknown? */
1644   int tek_kermit_fgcolor;	/* D: kermit's foreground color */
1645   int tek_kermit_bgcolor;	/* D: kermit's background color */
1646   bool tek_position_is_unknown;	/* D: cursor position is unknown? */
1647   plIntPoint tek_pos;		/* D: Tektronix cursor position */
1648 };
1649 
1650 /* The ReGISPlotter class, which produces ReGIS output */
1651 class ReGISPlotter : public Plotter
1652 {
1653  private:
1654   /* disallow copying and assignment */
1655   ReGISPlotter (const ReGISPlotter& oldplotter);
1656   ReGISPlotter& operator= (const ReGISPlotter& oldplotter);
1657  public:
1658   /* ctors (old-style, not thread-safe) */
1659   ReGISPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1660   ReGISPlotter (FILE *outfile);
1661   ReGISPlotter (istream& in, ostream& out, ostream& err);
1662   ReGISPlotter (ostream& out);
1663   ReGISPlotter ();
1664   /* ctors (new-style, thread-safe) */
1665   ReGISPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1666   ReGISPlotter (FILE *outfile, PlotterParams &params);
1667   ReGISPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1668   ReGISPlotter (ostream& out, PlotterParams &params);
1669   ReGISPlotter (PlotterParams &params);
1670   /* dtor */
1671   virtual ~ReGISPlotter ();
1672  protected:
1673   /* protected methods (overriding Plotter methods) */
1674   bool begin_page (void);
1675   bool erase_page (void);
1676   bool end_page (void);
1677   void paint_point (void);
1678   bool path_is_flushable (void);
1679   void initialize (void);
1680   void terminate (void);
1681   void maybe_prepaint_segments (int prev_num_segments);
1682   void paint_path (void);
1683   bool paint_paths (void);
1684   /* ReGISPlotter-specific internal functions */
1685   void _r_set_attributes (void);
1686   void _r_set_bg_color (void);
1687   void _r_set_fill_color (void);
1688   void _r_set_pen_color (void);
1689   void _r_regis_move (int xx, int yy);
1690   /* ReGISPlotter-specific data members */
1691   plIntPoint regis_pos;		/* D: ReGIS graphics cursor position */
1692   bool regis_position_is_unknown; /* D: graphics cursor position is unknown? */
1693   int regis_line_type;		/* D: native ReGIS line type */
1694   bool regis_line_type_is_unknown; /* D: ReGIS line type is unknown? */
1695   int regis_fgcolor;		/* D: ReGIS foreground color, in range 0..7 */
1696   int regis_bgcolor;		/* D: ReGIS background color, in range 0..7 */
1697   bool regis_fgcolor_is_unknown; /* D: foreground color unknown? */
1698   bool regis_bgcolor_is_unknown; /* D: background color unknown? */
1699 };
1700 
1701 /* The HPGLPlotter class, which produces HP-GL or HP-GL/2 output */
1702 class HPGLPlotter : public Plotter
1703 {
1704  private:
1705   /* disallow copying and assignment */
1706   HPGLPlotter (const HPGLPlotter& oldplotter);
1707   HPGLPlotter& operator= (const HPGLPlotter& oldplotter);
1708  public:
1709   /* ctors (old-style, not thread-safe) */
1710   HPGLPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1711   HPGLPlotter (FILE *outfile);
1712   HPGLPlotter (istream& in, ostream& out, ostream& err);
1713   HPGLPlotter (ostream& out);
1714   HPGLPlotter ();
1715   /* ctors (new-style, thread-safe) */
1716   HPGLPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1717   HPGLPlotter (FILE *outfile, PlotterParams &params);
1718   HPGLPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1719   HPGLPlotter (ostream& out, PlotterParams &params);
1720   HPGLPlotter (PlotterParams &params);
1721   /* dtor */
1722   virtual ~HPGLPlotter ();
1723  protected:
1724   /* protected methods (overriding Plotter methods, overridden in
1725      PCLPlotter class */
1726   void initialize (void);
1727   void terminate (void);
1728   /* protected methods (overriding Plotter methods) */
1729   bool begin_page (void);
1730   bool erase_page (void);
1731   bool end_page (void);
1732   void paint_point (void);
1733   void paint_path (void);
1734   bool paint_paths (void);
1735   double paint_text_string (const unsigned char *s, int h_just, int v_just);
1736   /* internal functions that are overridden in the PCLPlotter class */
1737   virtual void _maybe_switch_to_hpgl (void);
1738   virtual void _maybe_switch_from_hpgl (void);
1739   /* other HPGLPlotter-specific internal functions */
1740   bool _h_hpgl2_maybe_update_font (void);
1741   bool _h_hpgl_maybe_update_font (void);
1742   bool _h_parse_pen_string (const char *pen_s);
1743   int _h_hpgl_pseudocolor (int red, int green, int blue, bool restrict_white);
1744   void _h_set_attributes (void);
1745   void _h_set_fill_color (bool force_pen_color);
1746   void _h_set_font (void);
1747   void _h_set_pen_color (int hpgl_object_type);
1748   void _h_set_position (void);
1749   void _h_hpgl_shaded_pseudocolor (int red, int green, int blue, int *pen, double *shading);
1750   void _h_set_hpgl_fill_type (int fill_type, double option1, double option2);
1751   void _h_set_hpgl_pen_type (int pen_type, double option1, double option2);
1752   void _h_set_hpgl_pen (int pen);
1753   /* HPGLPlotter-specific data members */
1754   int hpgl_version;		/* version: 0=HP-GL, 1=HP7550A, 2=HP-GL/2 */
1755   int hpgl_rotation;		/* rotation angle (0, 90, 180, or 270) */
1756   double hpgl_plot_length;	/* plot length (for HP-GL/2 roll plotters) */
1757   plPoint hpgl_p1;		/* scaling point P1 in native HP-GL coors */
1758   plPoint hpgl_p2;		/* scaling point P2 in native HP-GL coors */
1759   bool hpgl_have_screened_vectors; /* can shade pen marks? (HP-GL/2 only) */
1760   bool hpgl_have_char_fill;	/* can shade char interiors? (HP-GL/2 only) */
1761   bool hpgl_can_assign_colors;	/* can assign pen colors? (HP-GL/2 only) */
1762   bool hpgl_use_opaque_mode;	/* pen marks sh'd be opaque? (HP-GL/2 only) */
1763   plColor hpgl_pen_color[HPGL2_MAX_NUM_PENS]; /* D: color array for pens */
1764   int hpgl_pen_defined[HPGL2_MAX_NUM_PENS];/*D:0=none,1=soft-defd,2=hard-defd*/
1765   int hpgl_pen;			/* D: number of currently selected pen */
1766   int hpgl_free_pen;		/* D: pen to be assigned a color next */
1767   bool hpgl_bad_pen;		/* D: bad pen (advisory, see h_color.c) */
1768   bool hpgl_pendown;		/* D: pen down rather than up? */
1769   double hpgl_pen_width;	/* D: pen width(frac of diag dist betw P1,P2)*/
1770   int hpgl_line_type;		/* D: line type(HP-GL numbering,solid = -100)*/
1771   int hpgl_cap_style;		/* D: cap style for lines (HP-GL/2 numbering)*/
1772   int hpgl_join_style;		/* D: join style for lines(HP-GL/2 numbering)*/
1773   double hpgl_miter_limit;	/* D: miterlimit for line joins(HP-GL/2 only)*/
1774   int hpgl_pen_type;		/* D: sv type (e.g. HPGL_PEN_{SOLID|SHADED}) */
1775   double hpgl_pen_option1;	/* D: used for some screened vector types */
1776   double hpgl_pen_option2;	/* D: used for some screened vector types */
1777   int hpgl_fill_type;		/* D: fill type (one of FILL_SOLID_UNI etc.) */
1778   double hpgl_fill_option1;	/* D: used for some fill types */
1779   double hpgl_fill_option2;	/* D: used for some fill types */
1780   int hpgl_char_rendering_type;	/* D: character rendering type (fill/edge) */
1781   int hpgl_symbol_set;		/* D: encoding, 14=ISO-Latin-1 (HP-GL/2 only)*/
1782   int hpgl_spacing;		/* D: fontspacing,0=fixed,1=not(HP-GL/2 only)*/
1783   int hpgl_posture;		/* D: posture,0=uprite,1=italic(HP-GL/2 only)*/
1784   int hpgl_stroke_weight;	/* D: weight,0=normal,3=bold,..(HP-GL/2only)*/
1785   int hpgl_pcl_typeface;	/* D: typeface, see g_fontdb.c (HP-GL/2) */
1786   int hpgl_charset_lower;	/* D: HP lower-half charset no. (pre-HP-GL/2)*/
1787   int hpgl_charset_upper;	/* D: HP upper-half charset no. (pre-HP-GL/2)*/
1788   double hpgl_rel_char_height;	/* D: char ht., % of p2y-p1y (HP-GL/2 only) */
1789   double hpgl_rel_char_width;	/* D: char width, % of p2x-p1x (HP-GL/2 only)*/
1790   double hpgl_rel_label_rise;	/* D: label rise, % of p2y-p1y (HP-GL/2 only)*/
1791   double hpgl_rel_label_run;	/* D: label run, % of p2x-p1x (HP-GL/2 only) */
1792   double hpgl_tan_char_slant;	/* D: tan of character slant (HP-GL/2 only)*/
1793   bool hpgl_position_is_unknown; /* D: HP-GL[/2] cursor position is unknown? */
1794   plIntPoint hpgl_pos;		/* D: cursor position (integer HP-GL coors) */
1795 };
1796 
1797 /* The PCLPlotter class, which produces PCL 5 output */
1798 class PCLPlotter : public HPGLPlotter
1799 {
1800  private:
1801   /* disallow copying and assignment */
1802   PCLPlotter (const PCLPlotter& oldplotter);
1803   PCLPlotter& operator= (const PCLPlotter& oldplotter);
1804  public:
1805   /* ctors (old-style, not thread-safe) */
1806   PCLPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1807   PCLPlotter (FILE *outfile);
1808   PCLPlotter (istream& in, ostream& out, ostream& err);
1809   PCLPlotter (ostream& out);
1810   PCLPlotter ();
1811   /* ctors (new-style, thread-safe) */
1812   PCLPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1813   PCLPlotter (FILE *outfile, PlotterParams &params);
1814   PCLPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1815   PCLPlotter (ostream& out, PlotterParams &params);
1816   PCLPlotter (PlotterParams &params);
1817   /* dtor */
1818   virtual ~PCLPlotter ();
1819  protected:
1820   /* protected methods (overriding HPGLPlotter methods) */
1821   void initialize (void);
1822   void terminate (void);
1823   /* internal functions that override HPGLPlotter internal functions */
1824   void _maybe_switch_to_hpgl (void);
1825   void _maybe_switch_from_hpgl (void);
1826 };
1827 
1828 /* The FigPlotter class, which produces Fig-format output for xfig */
1829 class FigPlotter : public Plotter
1830 {
1831  private:
1832   /* disallow copying and assignment */
1833   FigPlotter (const FigPlotter& oldplotter);
1834   FigPlotter& operator= (const FigPlotter& oldplotter);
1835  public:
1836   /* ctors (old-style, not thread-safe) */
1837   FigPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1838   FigPlotter (FILE *outfile);
1839   FigPlotter (istream& in, ostream& out, ostream& err);
1840   FigPlotter (ostream& out);
1841   FigPlotter ();
1842   /* ctors (new-style, thread-safe) */
1843   FigPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1844   FigPlotter (FILE *outfile, PlotterParams &params);
1845   FigPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1846   FigPlotter (ostream& out, PlotterParams &params);
1847   FigPlotter (PlotterParams &params);
1848   /* dtor */
1849   virtual ~FigPlotter ();
1850  protected:
1851   /* protected methods (overriding Plotter methods) */
1852   bool begin_page (void);
1853   bool erase_page (void);
1854   bool end_page (void);
1855   void paint_point (void);
1856   void initialize (void);
1857   void terminate (void);
1858   void paint_path (void);
1859   bool paint_paths (void);
1860   double paint_text_string (const unsigned char *s, int h_just, int v_just);
1861   bool retrieve_font (void);
1862   /* FigPlotter-specific internal functions */
1863   int _f_fig_color (int red, int green, int blue);
1864   void _f_compute_line_style (int *style, double *spacing);
1865   void _f_draw_arc_internal (double xc, double yc, double x0, double y0, double x1, double y1);
1866   void _f_draw_box_internal (plPoint p0, plPoint p1);
1867   void _f_draw_ellipse_internal (double x, double y, double rx, double ry, double angle, int subtype);
1868   void _f_set_fill_color (void);
1869   void _f_set_pen_color (void);
1870   /* FigPlotter-specific data members */
1871   int fig_drawing_depth;	/* D: fig's curr value for `depth' attribute */
1872   int fig_num_usercolors;	/* D: number of colors currently defined */
1873   long int fig_usercolors[FIG_MAX_NUM_USER_COLORS]; /* D: colors we've def'd */
1874   bool fig_colormap_warning_issued; /* D: issued warning on colormap filling up*/
1875 };
1876 
1877 /* The CGMPlotter class, which produces CGM (Computer Graphics Metafile)
1878    output */
1879 class CGMPlotter : public Plotter
1880 {
1881  private:
1882   /* disallow copying and assignment */
1883   CGMPlotter (const CGMPlotter& oldplotter);
1884   CGMPlotter& operator= (const CGMPlotter& oldplotter);
1885  public:
1886   /* ctors (old-style, not thread-safe) */
1887   CGMPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1888   CGMPlotter (FILE *outfile);
1889   CGMPlotter (istream& in, ostream& out, ostream& err);
1890   CGMPlotter (ostream& out);
1891   CGMPlotter ();
1892   /* ctors (new-style, thread-safe) */
1893   CGMPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1894   CGMPlotter (FILE *outfile, PlotterParams &params);
1895   CGMPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1896   CGMPlotter (ostream& out, PlotterParams &params);
1897   CGMPlotter (PlotterParams &params);
1898   /* dtor */
1899   virtual ~CGMPlotter ();
1900  protected:
1901   /* protected methods (overriding Plotter methods) */
1902   bool begin_page (void);
1903   bool erase_page (void);
1904   bool end_page (void);
1905   void paint_point (void);
1906   void initialize (void);
1907   void terminate (void);
1908   void paint_path (void);
1909   bool paint_marker (int type, double size);
1910   bool paint_paths (void);
1911   double paint_text_string (const unsigned char *s, int h_just, int v_just);
1912   /* internal functions */
1913   void _c_set_attributes (int cgm_object_type);
1914   void _c_set_bg_color (void);
1915   void _c_set_fill_color (int cgm_object_type);
1916   void _c_set_pen_color (int cgm_object_type);
1917   /* CGMPlotter-specific data members */
1918   int cgm_encoding;		/* CGM_ENCODING_{BINARY,CHARACTER,CLEAR_TEXT}*/
1919   int cgm_max_version;		/* upper bound on CGM version number */
1920   int cgm_version;		/* D: CGM version for file (1, 2, 3, or 4) */
1921   int cgm_profile;		/* D: CGM_PROFILE_{WEB,MODEL,NONE} */
1922   int cgm_need_color;		/* D: non-monochrome? */
1923   int cgm_page_version;		/* D: CGM version for current page */
1924   int cgm_page_profile;		/* D: CGM_PROFILE_{WEB,MODEL,NONE} */
1925   bool cgm_page_need_color;	/* D: current page is non-monochrome? */
1926   plColor cgm_line_color;	/* D: line pen color (24-bit or 48-bit RGB) */
1927   plColor cgm_edge_color;	/* D: edge pen color (24-bit or 48-bit RGB) */
1928   plColor cgm_fillcolor;	/* D: fill color (24-bit or 48-bit RGB) */
1929   plColor cgm_marker_color;	/* D: marker pen color (24-bit or 48-bit RGB)*/
1930   plColor cgm_text_color;	/* D: text pen color (24-bit or 48-bit RGB) */
1931   plColor cgm_bgcolor;		/* D: background color (24-bit or 48-bit RGB)*/
1932   bool cgm_bgcolor_suppressed;	/* D: background color suppressed? */
1933   int cgm_line_type;		/* D: one of CGM_L_{SOLID, etc.} */
1934   double cgm_dash_offset;	/* D: offset into dash array (`phase') */
1935   int cgm_join_style;		/* D: join style for lines (CGM numbering)*/
1936   int cgm_cap_style;		/* D: cap style for lines (CGM numbering)*/
1937   int cgm_dash_cap_style;	/* D: dash cap style for lines(CGM numbering)*/
1938   int cgm_line_width;		/* D: line width in CGM coordinates */
1939   int cgm_interior_style;	/* D: one of CGM_INT_STYLE_{EMPTY, etc.} */
1940   int cgm_edge_type;		/* D: one of CGM_L_{SOLID, etc.} */
1941   double cgm_edge_dash_offset;	/* D: offset into dash array (`phase') */
1942   int cgm_edge_join_style;	/* D: join style for edges (CGM numbering)*/
1943   int cgm_edge_cap_style;	/* D: cap style for edges (CGM numbering)*/
1944   int cgm_edge_dash_cap_style;	/* D: dash cap style for edges(CGM numbering)*/
1945   int cgm_edge_width;		/* D: edge width in CGM coordinates */
1946   bool cgm_edge_is_visible;	/* D: filled regions have edges? */
1947   double cgm_miter_limit;	/* D: CGM's miter limit */
1948   int cgm_marker_type;		/* D: one of CGM_M_{DOT, etc.} */
1949   int cgm_marker_size;		/* D: marker size in CGM coordinates */
1950   int cgm_char_height;		/* D: character height */
1951   int cgm_char_base_vector_x;	/* D: character base vector */
1952   int cgm_char_base_vector_y;
1953   int cgm_char_up_vector_x;	/* D: character up vector */
1954   int cgm_char_up_vector_y;
1955   int cgm_horizontal_text_alignment; /* D: one of CGM_ALIGN_* */
1956   int cgm_vertical_text_alignment; /* D: one of CGM_ALIGN_* */
1957   int cgm_font_id;		/* D: PS font in range 0..34 */
1958   int cgm_charset_lower;	/* D: lower charset (index into defined list)*/
1959   int cgm_charset_upper;	/* D: upper charset (index into defined list)*/
1960   int cgm_restricted_text_type;	/* D: one of CGM_RESTRICTED_TEXT_TYPE_* */
1961 };
1962 
1963 /* The PSPlotter class, which produces idraw-editable PS output */
1964 class PSPlotter : public Plotter
1965 {
1966  private:
1967   /* disallow copying and assignment */
1968   PSPlotter (const PSPlotter& oldplotter);
1969   PSPlotter& operator= (const PSPlotter& oldplotter);
1970  public:
1971   /* ctors (old-style, not thread-safe) */
1972   PSPlotter (FILE *infile, FILE *outfile, FILE *errfile);
1973   PSPlotter (FILE *outfile);
1974   PSPlotter (istream& in, ostream& out, ostream& err);
1975   PSPlotter (ostream& out);
1976   PSPlotter ();
1977   /* ctors (new-style, thread-safe) */
1978   PSPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
1979   PSPlotter (FILE *outfile, PlotterParams &params);
1980   PSPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
1981   PSPlotter (ostream& out, PlotterParams &params);
1982   PSPlotter (PlotterParams &params);
1983   /* dtor */
1984   virtual ~PSPlotter ();
1985  protected:
1986   /* protected methods (overriding Plotter methods) */
1987   bool begin_page (void);
1988   bool erase_page (void);
1989   bool end_page (void);
1990   void paint_point (void);
1991   void initialize (void);
1992   void terminate (void);
1993   void paint_path (void);
1994   bool paint_paths (void);
1995   double paint_text_string (const unsigned char *s, int h_just, int v_just);
1996   /* PSPlotter-specific internal functions */
1997   double _p_emit_common_attributes (void);
1998   void _p_compute_idraw_bgcolor (void);
1999   void _p_fellipse_internal (double x, double y, double rx, double ry, double angle, bool circlep);
2000   void _p_set_fill_color (void);
2001   void _p_set_pen_color (void);
2002 };
2003 
2004 /* The AIPlotter class, which produces output editable by Adobe Illustrator */
2005 class AIPlotter : public Plotter
2006 {
2007  private:
2008   /* disallow copying and assignment */
2009   AIPlotter (const AIPlotter& oldplotter);
2010   AIPlotter& operator= (const AIPlotter& oldplotter);
2011  public:
2012   /* ctors (old-style, not thread-safe) */
2013   AIPlotter (FILE *infile, FILE *outfile, FILE *errfile);
2014   AIPlotter (FILE *outfile);
2015   AIPlotter (istream& in, ostream& out, ostream& err);
2016   AIPlotter (ostream& out);
2017   AIPlotter ();
2018   /* ctors (new-style, thread-safe) */
2019   AIPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
2020   AIPlotter (FILE *outfile, PlotterParams &params);
2021   AIPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
2022   AIPlotter (ostream& out, PlotterParams &params);
2023   AIPlotter (PlotterParams &params);
2024   /* dtor */
2025   virtual ~AIPlotter ();
2026  protected:
2027   /* protected methods (overriding Plotter methods) */
2028   bool begin_page (void);
2029   bool erase_page (void);
2030   bool end_page (void);
2031   void paint_point (void);
2032   void initialize (void);
2033   void terminate (void);
2034   void paint_path (void);
2035   bool paint_paths (void);
2036   double paint_text_string (const unsigned char *s, int h_just, int v_just);
2037   /* internal functions */
2038   void _a_set_attributes (void);
2039   void _a_set_fill_color (bool force_pen_color);
2040   void _a_set_pen_color (void);
2041   /* AIPlotter-specific data members */
2042   int ai_version;		/* AI3 or AI5? */
2043   double ai_pen_cyan;		/* D: pen color (in CMYK space) */
2044   double ai_pen_magenta;
2045   double ai_pen_yellow;
2046   double ai_pen_black;
2047   double ai_fill_cyan;		/* D: fill color (in CMYK space) */
2048   double ai_fill_magenta;
2049   double ai_fill_yellow;
2050   double ai_fill_black;
2051   bool ai_cyan_used;		/* D: C, M, Y, K have been used? */
2052   bool ai_magenta_used;
2053   bool ai_yellow_used;
2054   bool ai_black_used;
2055   int ai_cap_style;		/* D: cap style for lines (PS numbering)*/
2056   int ai_join_style;		/* D: join style for lines(PS numbering)*/
2057   double ai_miter_limit;	/* D: miterlimit for line joins */
2058   int ai_line_type;		/* D: one of PL_L_* */
2059   double ai_line_width;		/* D: line width in printer's points */
2060   int ai_fill_rule_type;	/* D: fill rule (AI_FILL_{ODD|NONZERO}_WINDING) */
2061 };
2062 
2063 /* The SVGPlotter class, which produces SVG output for the Web */
2064 class SVGPlotter : public Plotter
2065 {
2066  private:
2067   /* disallow copying and assignment */
2068   SVGPlotter (const SVGPlotter& oldplotter);
2069   SVGPlotter& operator= (const SVGPlotter& oldplotter);
2070  public:
2071   /* ctors (old-style, not thread-safe) */
2072   SVGPlotter (FILE *infile, FILE *outfile, FILE *errfile);
2073   SVGPlotter (FILE *outfile);
2074   SVGPlotter (istream& in, ostream& out, ostream& err);
2075   SVGPlotter (ostream& out);
2076   SVGPlotter ();
2077   /* ctors (new-style, thread-safe) */
2078   SVGPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
2079   SVGPlotter (FILE *outfile, PlotterParams &params);
2080   SVGPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
2081   SVGPlotter (ostream& out, PlotterParams &params);
2082   SVGPlotter (PlotterParams &params);
2083   /* dtor */
2084   virtual ~SVGPlotter ();
2085  protected:
2086   /* protected methods (overriding Plotter methods) */
2087   bool begin_page (void);
2088   bool erase_page (void);
2089   bool end_page (void);
2090   void paint_point (void);
2091   void initialize (void);
2092   void terminate (void);
2093   void paint_path (void);
2094   bool paint_paths (void);
2095   double paint_text_string (const unsigned char *s, int h_just, int v_just);
2096   /* SVGPlotter-specific internal functions */
2097   void _s_set_matrix (const double m_local[6]);
2098   /* SVGPlotter-specific data members */
2099   double s_matrix[6];		/* D: default transformation matrix for page */
2100   bool s_matrix_is_unknown;	/* D: matrix has not yet been set? */
2101   bool s_matrix_is_bogus;	/* D: matrix has been set, but is bogus? */
2102   plColor s_bgcolor;		/* D: background color (RGB) */
2103   bool s_bgcolor_suppressed;	/* D: background color suppressed? */
2104 };
2105 
2106 /* The PNMPlotter class, which produces PBM/PGM/PPM output; derived from
2107    the BitmapPlotter class */
2108 class PNMPlotter : public BitmapPlotter
2109 {
2110  private:
2111   /* disallow copying and assignment */
2112   PNMPlotter (const PNMPlotter& oldplotter);
2113   PNMPlotter& operator= (const PNMPlotter& oldplotter);
2114  public:
2115   /* ctors (old-style, not thread-safe) */
2116   PNMPlotter (FILE *infile, FILE *outfile, FILE *errfile);
2117   PNMPlotter (FILE *outfile);
2118   PNMPlotter (istream& in, ostream& out, ostream& err);
2119   PNMPlotter (ostream& out);
2120   PNMPlotter ();
2121   /* ctors (new-style, thread-safe) */
2122   PNMPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
2123   PNMPlotter (FILE *outfile, PlotterParams &params);
2124   PNMPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
2125   PNMPlotter (ostream& out, PlotterParams &params);
2126   PNMPlotter (PlotterParams &params);
2127   /* dtor */
2128   virtual ~PNMPlotter ();
2129  protected:
2130   /* protected methods (overriding BitmapPlotter methods) */
2131   void initialize (void);
2132   void terminate (void);
2133   /* internal functions that override BitmapPlotter functions (crocks) */
2134   int _maybe_output_image (void);
2135   /* other PNMPlotter-specific internal functions */
2136   void _n_write_pnm (void);
2137   void _n_write_pbm (void);
2138   void _n_write_pgm (void);
2139   void _n_write_ppm (void);
2140   /* PNMPlotter-specific data members */
2141   bool n_portable_output;	/* portable, not binary output format? */
2142 };
2143 
2144 #ifdef INCLUDE_PNG_SUPPORT
2145 /* The PNGPlotter class, which produces PNG output; derived from the
2146    BitmapPlotter class */
2147 class PNGPlotter : public BitmapPlotter
2148 {
2149  private:
2150   /* disallow copying and assignment */
2151   PNGPlotter (const PNGPlotter& oldplotter);
2152   PNGPlotter& operator= (const PNGPlotter& oldplotter);
2153  public:
2154   /* ctors (old-style, not thread-safe) */
2155   PNGPlotter (FILE *infile, FILE *outfile, FILE *errfile);
2156   PNGPlotter (FILE *outfile);
2157   PNGPlotter (istream& in, ostream& out, ostream& err);
2158   PNGPlotter (ostream& out);
2159   PNGPlotter ();
2160   /* ctors (new-style, thread-safe) */
2161   PNGPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
2162   PNGPlotter (FILE *outfile, PlotterParams &params);
2163   PNGPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
2164   PNGPlotter (ostream& out, PlotterParams &params);
2165   PNGPlotter (PlotterParams &params);
2166   /* dtor */
2167   virtual ~PNGPlotter ();
2168  protected:
2169   /* protected methods (overriding BitmapPlotter methods) */
2170   void initialize (void);
2171   void terminate (void);
2172   /* internal functions that override BitmapPlotter functions (crocks) */
2173   int _maybe_output_image (void);
2174   /* PNGPlotter-specific data members */
2175   bool z_interlace;		/* interlaced PNG? */
2176   bool z_transparent;		/* transparent PNG? */
2177   plColor z_transparent_color;	/* if so, transparent color (24-bit RGB) */
2178 };
2179 #endif /* INCLUDE_PNG_SUPPORT */
2180 
2181 /* The GIFPlotter class, which produces pseudo-GIF output */
2182 class GIFPlotter : public Plotter
2183 {
2184  private:
2185   /* disallow copying and assignment */
2186   GIFPlotter (const GIFPlotter& oldplotter);
2187   GIFPlotter& operator= (const GIFPlotter& oldplotter);
2188  public:
2189   /* ctors (old-style, not thread-safe) */
2190   GIFPlotter (FILE *infile, FILE *outfile, FILE *errfile);
2191   GIFPlotter (FILE *outfile);
2192   GIFPlotter (istream& in, ostream& out, ostream& err);
2193   GIFPlotter (ostream& out);
2194   GIFPlotter ();
2195   /* ctors (new-style, thread-safe) */
2196   GIFPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
2197   GIFPlotter (FILE *outfile, PlotterParams &params);
2198   GIFPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
2199   GIFPlotter (ostream& out, PlotterParams &params);
2200   GIFPlotter (PlotterParams &params);
2201   /* dtor */
2202   virtual ~GIFPlotter ();
2203  protected:
2204   /* protected methods (overriding Plotter methods) */
2205   bool begin_page (void);
2206   bool erase_page (void);
2207   bool end_page (void);
2208   void paint_point (void);
2209   void initialize (void);
2210   void terminate (void);
2211   void paint_path (void);
2212   bool paint_paths (void);
2213   /* GIFPlotter-specific internal functions */
2214   unsigned char _i_new_color_index (int red, int green, int blue);
2215   int _i_scan_pixel (void);
2216   void _i_delete_image (void);
2217   void _i_draw_elliptic_arc (plPoint p0, plPoint p1, plPoint pc);
2218   void _i_draw_elliptic_arc_2 (plPoint p0, plPoint p1, plPoint pc);
2219   void _i_draw_elliptic_arc_internal (int xorigin, int yorigin, unsigned int squaresize_x, unsigned int squaresize_y, int startangle, int anglerange);
2220   void _i_new_image (void);
2221   void _i_set_bg_color (void);
2222   void _i_set_fill_color (void);
2223   void _i_set_pen_color (void);
2224   void _i_start_scan (void);
2225   void _i_write_gif_header (void);
2226   void _i_write_gif_image (void);
2227   void _i_write_gif_trailer (void);
2228   void _i_write_short_int (unsigned int i);
2229   /* GIFPlotter-specific data members */
2230   int i_xn, i_yn;		/* bitmap dimensions */
2231   int i_num_pixels;		/* total pixels (used by scanner) */
2232   bool i_animation;		/* animated (multi-image) GIF? */
2233   int i_iterations;		/* number of times GIF should be looped */
2234   int i_delay;			/* delay after image, in 1/100 sec units */
2235   bool i_interlace;		/* interlaced GIF? */
2236   bool i_transparent;		/* transparent GIF? */
2237   plColor i_transparent_color;	/* if so, transparent color (24-bit RGB) */
2238   void * i_arc_cache_data;	/* pointer to cache (used by miPolyArc_r) */
2239   int i_transparent_index;	/* D: transparent color index (if any) */
2240   void * i_painted_set;	        /* D: libxmi's canvas (a (miPaintedSet *)) */
2241   void * i_canvas;		/* D: libxmi's canvas (a (miCanvas *)) */
2242   plColor i_colormap[256];	/* D: frame colormap (containing 24-bit RGBs)*/
2243   int i_num_color_indices;	/* D: number of color indices allocated */
2244   bool i_frame_nonempty;	/* D: something drawn in current frame? */
2245   int i_bit_depth;		/* D: bit depth (ceil(log2(num_indices))) */
2246   int i_pixels_scanned;		/* D: number that scanner has scanned */
2247   int i_pass;			/* D: scanner pass (used if interlacing) */
2248   plIntPoint i_hot;		/* D: scanner hot spot */
2249   plColor i_global_colormap[256]; /* D: colormap for first frame (stashed) */
2250   int i_num_global_color_indices;/* D: number of indices in global colormap */
2251   bool i_header_written;	/* D: GIF header written yet? */
2252 };
2253 
2254 #ifndef X_DISPLAY_MISSING
2255 /* The XDrawablePlotter class, which draws into one or two X drawables */
2256 class XDrawablePlotter : public Plotter
2257 {
2258  private:
2259   /* disallow copying and assignment */
2260   XDrawablePlotter (const XDrawablePlotter& oldplotter);
2261   XDrawablePlotter& operator= (const XDrawablePlotter& oldplotter);
2262  public:
2263   /* ctors (old-style, not thread-safe) */
2264   XDrawablePlotter (FILE *infile, FILE *outfile, FILE *errfile);
2265   XDrawablePlotter (FILE *outfile);
2266   XDrawablePlotter (istream& in, ostream& out, ostream& err);
2267   XDrawablePlotter (ostream& out);
2268   XDrawablePlotter ();
2269   /* ctors (new-style, thread-safe) */
2270   XDrawablePlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
2271   XDrawablePlotter (FILE *outfile, PlotterParams &params);
2272   XDrawablePlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
2273   XDrawablePlotter (ostream& out, PlotterParams &params);
2274   XDrawablePlotter (PlotterParams &params);
2275   /* dtor */
2276   virtual ~XDrawablePlotter ();
2277  protected:
2278   /* protected methods (overriding Plotter methods) */
2279   bool begin_page (void);
2280   bool erase_page (void);
2281   bool end_page (void);
2282   bool flush_output (void);
2283   bool path_is_flushable (void);
2284   void push_state (void);
2285   void pop_state (void);
2286   void paint_point (void);
2287   void initialize (void);
2288   void terminate (void);
2289   void paint_path (void);
2290   bool paint_paths (void);
2291   void maybe_prepaint_segments (int prev_num_segments);
2292   double paint_text_string (const unsigned char *s, int h_just, int v_just);
2293   double get_text_width (const unsigned char *s);
2294   bool retrieve_font (void);
2295   /* internal functions that are overridden in the XPlotter class (crocks) */
2296   virtual void _maybe_get_new_colormap (void);
2297   virtual void _maybe_handle_x_events (void);
2298   /* other XDrawablePlotter-specific internal functions */
2299   bool _x_retrieve_color (XColor *rgb_ptr);
2300   bool _x_select_font_carefully (const char *name, const unsigned char *s, bool subsetting);
2301   bool _x_select_xlfd_font_carefully (const char *x_name, const char *x_name_alt, const char *x_name_alt2, const char *x_name_alt3);
2302   void _x_add_gcs_to_first_drawing_state (void);
2303   void _x_delete_gcs_from_first_drawing_state (void);
2304   void _x_draw_elliptic_arc (plPoint p0, plPoint p1, plPoint pc);
2305   void _x_draw_elliptic_arc_2 (plPoint p0, plPoint p1, plPoint pc);
2306   void _x_draw_elliptic_arc_internal (int xorigin, int yorigin, unsigned int squaresize_x, unsigned int squaresize_y, int startangle, int anglerange);
2307   void _x_set_attributes (int x_gc_type);
2308   void _x_set_bg_color (void);
2309   void _x_set_fill_color (void);
2310   void _x_set_pen_color (void);
2311   /* XDrawablePlotter-specific data members */
2312   Display *x_dpy;		/* X display */
2313   Visual *x_visual;		/* X visual */
2314   Drawable x_drawable1;		/* an X drawable (e.g. a pixmap) */
2315   Drawable x_drawable2;		/* an X drawable (e.g. a window) */
2316   Drawable x_drawable3;		/* graphics buffer, if double buffering */
2317   int x_double_buffering;	/* double buffering type (if any) */
2318   long int x_max_polyline_len;	/* limit on polyline len (X display-specific)*/
2319   plXFontRecord *x_fontlist;	/* D: head of list of retrieved X fonts */
2320   plColorRecord *x_colorlist;	/* D: head of list of retrieved X color cells*/
2321   Colormap x_cmap;		/* D: colormap (dynamic only for XPlotters) */
2322   int x_cmap_type;		/* D: colormap type (orig./copied/bad) */
2323   bool x_colormap_warning_issued; /* D: issued warning on colormap filling up*/
2324   bool x_bg_color_warning_issued; /* D: issued warning on bg color */
2325   int x_paint_pixel_count;	/* D: times point() is invoked to set a pixel*/
2326 };
2327 
2328 /* The XPlotter class, which pops up a window and draws into it */
2329 class XPlotter : public XDrawablePlotter
2330 {
2331  private:
2332   /* disallow copying and assignment */
2333   XPlotter (const XPlotter& oldplotter);
2334   XPlotter& operator= (const XPlotter& oldplotter);
2335  public:
2336   /* ctors (old-style, not thread-safe) */
2337   XPlotter (FILE *infile, FILE *outfile, FILE *errfile);
2338   XPlotter (FILE *outfile);
2339   XPlotter (istream& in, ostream& out, ostream& err);
2340   XPlotter (ostream& out);
2341   XPlotter ();
2342   /* ctors (new-style, thread-safe) */
2343   XPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &params);
2344   XPlotter (FILE *outfile, PlotterParams &params);
2345   XPlotter (istream& in, ostream& out, ostream& err, PlotterParams &params);
2346   XPlotter (ostream& out, PlotterParams &params);
2347   XPlotter (PlotterParams &params);
2348   /* dtor */
2349   virtual ~XPlotter ();
2350  protected:
2351   /* protected methods (overriding XDrawablePlotter methods) */
2352   bool begin_page (void);
2353   bool erase_page (void);
2354   bool end_page (void);
2355   void initialize (void);
2356   void terminate (void);
2357   /* internal functions that override XDrawablePlotter functions (crocks) */
2358   void _maybe_get_new_colormap (void);
2359   void _maybe_handle_x_events (void);
2360   /* other XPlotter-specific internal functions */
2361   void _y_set_data_for_quitting (void);
2362   /* XPlotter-specific data members (non-static) */
2363   XtAppContext y_app_con;	/* application context */
2364   Widget y_toplevel;		/* toplevel widget */
2365   Widget y_canvas;		/* Label widget */
2366   Drawable y_drawable4;		/* used for server-side double buffering */
2367   bool y_auto_flush;		/* do an XFlush() after each drawing op? */
2368   bool y_vanish_on_delete;	/* window(s) disappear on Plotter deletion? */
2369   pid_t *y_pids;		/* D: list of pids of forked-off processes */
2370   int y_num_pids;		/* D: number of pids in list */
2371   int y_event_handler_count;	/* D: times that event handler is invoked */
2372   /* XPlotter-specific data members (static) */
2373   static XPlotter **_xplotters;	/* D: sparse array of XPlotter instances */
2374   static int _xplotters_len;	/* D: length of sparse array */
2375 };
2376 #endif /* not X_DISPLAY_MISSING */
2377 #endif /* not NOT_LIBPLOTTER */
2378 
2379 
2380 /***********************************************************************/
2381 
2382 /* Useful definitions, included in both plot.h and plotter.h. */
2383 
2384 #ifndef _PL_LIBPLOT_USEFUL_DEFS
2385 #define _PL_LIBPLOT_USEFUL_DEFS 1
2386 
2387 /* Symbol types for the marker() function, extending over the range 0..31.
2388    (1 through 5 are the same as in the GKS [Graphical Kernel System].)
2389 
2390    These are now defined as enums rather than ints.  Cast them to ints if
2391    necessary. */
2392 enum
2393 { M_NONE, M_DOT, M_PLUS, M_ASTERISK, M_CIRCLE, M_CROSS,
2394   M_SQUARE, M_TRIANGLE, M_DIAMOND, M_STAR, M_INVERTED_TRIANGLE,
2395   M_STARBURST, M_FANCY_PLUS, M_FANCY_CROSS, M_FANCY_SQUARE,
2396   M_FANCY_DIAMOND, M_FILLED_CIRCLE, M_FILLED_SQUARE, M_FILLED_TRIANGLE,
2397   M_FILLED_DIAMOND, M_FILLED_INVERTED_TRIANGLE, M_FILLED_FANCY_SQUARE,
2398   M_FILLED_FANCY_DIAMOND, M_HALF_FILLED_CIRCLE, M_HALF_FILLED_SQUARE,
2399   M_HALF_FILLED_TRIANGLE, M_HALF_FILLED_DIAMOND,
2400   M_HALF_FILLED_INVERTED_TRIANGLE, M_HALF_FILLED_FANCY_SQUARE,
2401   M_HALF_FILLED_FANCY_DIAMOND, M_OCTAGON, M_FILLED_OCTAGON
2402 };
2403 
2404 /* ONE-BYTE OPERATION CODES FOR GNU METAFILE FORMAT. These are now defined
2405    as enums rather than ints.  Cast them to ints if necessary.
2406 
2407    There are 85 currently recognized op codes.  The first 10 date back to
2408    Unix plot(5) format. */
2409 
2410 enum
2411 {
2412 /* 10 op codes for primitive graphics operations, as in Unix plot(5) format. */
2413   O_ARC		=	'a',
2414   O_CIRCLE	=	'c',
2415   O_CONT	=	'n',
2416   O_ERASE	=	'e',
2417   O_LABEL	=	't',
2418   O_LINEMOD	=	'f',
2419   O_LINE	=	'l',
2420   O_MOVE	=	'm',
2421   O_POINT	=	'p',
2422   O_SPACE	=	's',
2423 
2424 /* 42 op codes that are GNU extensions */
2425   O_ALABEL	=	'T',
2426   O_ARCREL	=	'A',
2427   O_BEZIER2	=       'q',
2428   O_BEZIER2REL	=       'r',
2429   O_BEZIER3	=       'y',
2430   O_BEZIER3REL	=       'z',
2431   O_BGCOLOR	=	'~',
2432   O_BOX		=	'B',	/* not an op code in Unix plot(5) */
2433   O_BOXREL	=	'H',
2434   O_CAPMOD	=	'K',
2435   O_CIRCLEREL	=	'G',
2436   O_CLOSEPATH	=	'k',
2437   O_CLOSEPL	=	'x',	/* not an op code in Unix plot(5) */
2438   O_COMMENT	=	'#',
2439   O_CONTREL	=	'N',
2440   O_ELLARC	=	'?',
2441   O_ELLARCREL	=	'/',
2442   O_ELLIPSE	=	'+',
2443   O_ELLIPSEREL	=	'=',
2444   O_ENDPATH	=	'E',
2445   O_ENDSUBPATH	=	']',
2446   O_FILLTYPE	=	'L',
2447   O_FILLCOLOR	=	'D',
2448   O_FILLMOD	=	'g',
2449   O_FONTNAME	=	'F',
2450   O_FONTSIZE	=	'S',
2451   O_JOINMOD	=	'J',
2452   O_LINEDASH	= 	'd',
2453   O_LINEREL	=	'I',
2454   O_LINEWIDTH	=	'W',
2455   O_MARKER	=	'Y',
2456   O_MARKERREL	=	'Z',
2457   O_MOVEREL	=	'M',
2458   O_OPENPL	=	'o',	/* not an op code in Unix plot(5) */
2459   O_ORIENTATION	=	'b',
2460   O_PENCOLOR	=	'-',
2461   O_PENTYPE	=	'h',
2462   O_POINTREL	=	'P',
2463   O_RESTORESTATE=	'O',
2464   O_SAVESTATE	=	'U',
2465   O_SPACE2	=	':',
2466   O_TEXTANGLE	=	'R',
2467 
2468 /* 30 floating point counterparts to many of the above.  They are not even
2469    slightly mnemonic. */
2470   O_FARC	=	'1',
2471   O_FARCREL	=	'2',
2472   O_FBEZIER2	=       '`',
2473   O_FBEZIER2REL	=       '\'',
2474   O_FBEZIER3	=       ',',
2475   O_FBEZIER3REL	=       '.',
2476   O_FBOX	=	'3',
2477   O_FBOXREL	=	'4',
2478   O_FCIRCLE	=	'5',
2479   O_FCIRCLEREL	=	'6',
2480   O_FCONT	=	')',
2481   O_FCONTREL	=	'_',
2482   O_FELLARC	=	'}',
2483   O_FELLARCREL	=	'|',
2484   O_FELLIPSE	=	'{',
2485   O_FELLIPSEREL	=	'[',
2486   O_FFONTSIZE	=	'7',
2487   O_FLINE	=	'8',
2488   O_FLINEDASH	= 	'w',
2489   O_FLINEREL	=	'9',
2490   O_FLINEWIDTH	=	'0',
2491   O_FMARKER	=	'!',
2492   O_FMARKERREL	=	'@',
2493   O_FMOVE	=	'$',
2494   O_FMOVEREL	=	'%',
2495   O_FPOINT	=	'^',
2496   O_FPOINTREL	=	'&',
2497   O_FSPACE	=	'*',
2498   O_FSPACE2	=	';',
2499   O_FTEXTANGLE	=	'(',
2500 
2501 /* 3 op codes for floating point operations with no integer counterpart */
2502   O_FCONCAT		=	'\\',
2503   O_FMITERLIMIT		=	'i',
2504   O_FSETMATRIX		=	'j'
2505 };
2506 
2507 #endif /* not _PL_LIBPLOT_USEFUL_DEFS */
2508 
2509 /***********************************************************************/
2510 
2511 #endif /* not _PLOTTER_H_ */
2512