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 file defines the initialization for any Bitmap Plotter object,
20    including both private data and public methods.  There is a one-to-one
21    correspondence between public methods and user-callable functions in the
22    C API. */
23 
24 #include "sys-defines.h"
25 #include "extern.h"
26 #include "xmi.h"		/* use libxmi scan conversion module */
27 
28 /* forward references */
29 static bool parse_bitmap_size (const char *bitmap_size_s, int *width, int *height);
30 
31 #ifndef LIBPLOTTER
32 /* In libplot, this is the initialization for the function-pointer part of
33    a BitmapPlotter struct. */
34 const Plotter _pl_b_default_plotter =
35 {
36   /* initialization (after creation) and termination (before deletion) */
37   _pl_b_initialize, _pl_b_terminate,
38   /* page manipulation */
39   _pl_b_begin_page, _pl_b_erase_page, _pl_b_end_page,
40   /* drawing state manipulation */
41   _pl_g_push_state, _pl_g_pop_state,
42   /* internal path-painting methods (endpath() is a wrapper for the first) */
43   _pl_b_paint_path, _pl_b_paint_paths, _pl_g_path_is_flushable, _pl_g_maybe_prepaint_segments,
44   /* internal methods for drawing of markers and points */
45   _pl_g_paint_marker, _pl_b_paint_point,
46   /* internal methods that plot strings in Hershey, non-Hershey fonts */
47   _pl_g_paint_text_string_with_escapes, _pl_g_paint_text_string,
48   _pl_g_get_text_width,
49   /* private low-level `retrieve font' method */
50   _pl_g_retrieve_font,
51   /* `flush output' method, called only if Plotter handles its own output */
52   _pl_g_flush_output,
53   /* error handlers */
54   _pl_g_warning,
55   _pl_g_error,
56 };
57 #endif /* not LIBPLOTTER */
58 
59 /* The private `initialize' method, which is invoked when a Plotter is
60    created.  It is used for such things as initializing capability flags
61    from the values of class variables, allocating storage, etc.  When this
62    is invoked, _plotter points to the Plotter that has just been
63    created. */
64 
65 void
_pl_b_initialize(S___ (Plotter * _plotter))66 _pl_b_initialize (S___(Plotter *_plotter))
67 {
68 #ifndef LIBPLOTTER
69   /* in libplot, manually invoke superclass initialization method */
70   _pl_g_initialize (S___(_plotter));
71 #endif
72 
73   /* override superclass initializations, as necessary */
74 
75 #ifndef LIBPLOTTER
76   /* tag field, differs in derived classes */
77   _plotter->data->type = PL_BITMAP;
78 #endif
79 
80   /* output model */
81   _plotter->data->output_model = PL_OUTPUT_NONE;
82 
83   /* user-queryable capabilities: 0/1/2 = no/yes/maybe */
84   _plotter->data->have_wide_lines = 1;
85   _plotter->data->have_dash_array = 1;
86   _plotter->data->have_solid_fill = 1;
87   _plotter->data->have_odd_winding_fill = 1;
88   _plotter->data->have_nonzero_winding_fill = 1;
89   _plotter->data->have_settable_bg = 1;
90   _plotter->data->have_escaped_string_support = 0;
91   _plotter->data->have_ps_fonts = 0;
92   _plotter->data->have_pcl_fonts = 0;
93   _plotter->data->have_stick_fonts = 0;
94   _plotter->data->have_extra_stick_fonts = 0;
95   _plotter->data->have_other_fonts = 0;
96 
97   /* text and font-related parameters (internal, not queryable by user);
98      note that we don't set kern_stick_fonts, because it was set by the
99      superclass initialization (and it's irrelevant for this Plotter type,
100      anyway) */
101   _plotter->data->default_font_type = PL_F_HERSHEY;
102   _plotter->data->pcl_before_ps = false;
103   _plotter->data->have_horizontal_justification = false;
104   _plotter->data->have_vertical_justification = false;
105   _plotter->data->issue_font_warning = true;
106 
107   /* path-related parameters (also internal); note that we
108      don't set max_unfilled_path_length, because it was set by the
109      superclass initialization */
110   _plotter->data->have_mixed_paths = false;
111   _plotter->data->allowed_arc_scaling = AS_AXES_PRESERVED;
112   _plotter->data->allowed_ellarc_scaling = AS_AXES_PRESERVED;
113   _plotter->data->allowed_quad_scaling = AS_NONE;
114   _plotter->data->allowed_cubic_scaling = AS_NONE;
115   _plotter->data->allowed_box_scaling = AS_NONE;
116   _plotter->data->allowed_circle_scaling = AS_NONE;
117   _plotter->data->allowed_ellipse_scaling = AS_AXES_PRESERVED;
118 
119   /* dimensions */
120   _plotter->data->display_model_type = (int)DISP_MODEL_VIRTUAL;
121   _plotter->data->display_coors_type = (int)DISP_DEVICE_COORS_INTEGER_LIBXMI;
122   _plotter->data->flipped_y = true;
123   _plotter->data->imin = 0;
124   _plotter->data->imax = 569;
125   _plotter->data->jmin = 569;
126   _plotter->data->jmax = 0;
127   _plotter->data->xmin = 0.0;
128   _plotter->data->xmax = 0.0;
129   _plotter->data->ymin = 0.0;
130   _plotter->data->ymax = 0.0;
131   _plotter->data->page_data = (plPageData *)NULL;
132 
133   /* initialize data members specific to this derived class */
134   _plotter->b_xn = _plotter->data->imax + 1;
135   _plotter->b_yn = _plotter->data->jmin + 1;
136   _plotter->b_painted_set = (void *)NULL;
137   _plotter->b_canvas = (void *)NULL;
138 
139   /* initialize storage used by libxmi's reentrant miDrawArcs_r() function
140      for cacheing rasterized ellipses */
141   _plotter->b_arc_cache_data = (void *)miNewEllipseCache ();
142 
143   /* determine the range of device coordinates over which the graphics
144      display will extend (and hence the transformation from user to device
145      coordinates). */
146   {
147     const char *bitmap_size_s;
148     int width = 1, height = 1;
149 
150     bitmap_size_s = (const char *)_get_plot_param (_plotter->data, "BITMAPSIZE");
151     if (bitmap_size_s && parse_bitmap_size (bitmap_size_s, &width, &height)
152 	/* insist on >=1 */
153 	&& width >= 1 && height >= 1)
154       /* override defaults above */
155       {
156 	_plotter->data->imax = width - 1;
157 	_plotter->data->jmin = height - 1;
158 	_plotter->b_xn = width;
159 	_plotter->b_yn = height;
160       }
161   }
162 
163   /* compute the NDC to device-frame affine map, set it in Plotter */
164   _compute_ndc_to_device_map (_plotter->data);
165 
166   /* initialize certain data members from device driver parameters */
167 
168   /* for this class, there are none */
169 }
170 
171 static bool
parse_bitmap_size(const char * bitmap_size_s,int * width,int * height)172 parse_bitmap_size (const char *bitmap_size_s, int *width, int *height)
173 {
174   int local_width = 1, local_height = 1;
175 
176   if (bitmap_size_s
177       /* should parse this better */
178       && sscanf (bitmap_size_s, "%dx%d", &local_width, &local_height) == 2
179       && local_width > 0 && local_height > 0)
180     {
181       *width = local_width;
182       *height = local_height;
183       return true;
184     }
185   else
186     return false;
187 }
188 
189 /* The private `terminate' method, which is invoked when a Plotter is
190    deleted.  It may do such things as write to an output stream from
191    internal storage, deallocate storage, etc.  When this is invoked,
192    _plotter points (temporarily) to the Plotter that is about to be
193    deleted. */
194 
195 void
_pl_b_terminate(S___ (Plotter * _plotter))196 _pl_b_terminate (S___(Plotter *_plotter))
197 {
198   /* free storage used by libxmi's reentrant miDrawArcs_r() function */
199   miDeleteEllipseCache ((miEllipseCache *)_plotter->b_arc_cache_data);
200 
201 #ifndef LIBPLOTTER
202   /* in libplot, manually invoke superclass termination method */
203   _pl_g_terminate (S___(_plotter));
204 #endif
205 }
206 
207 #ifdef LIBPLOTTER
BitmapPlotter(FILE * infile,FILE * outfile,FILE * errfile)208 BitmapPlotter::BitmapPlotter (FILE *infile, FILE *outfile, FILE *errfile)
209 	:Plotter (infile, outfile, errfile)
210 {
211   _pl_b_initialize ();
212 }
213 
BitmapPlotter(FILE * outfile)214 BitmapPlotter::BitmapPlotter (FILE *outfile)
215 	:Plotter (outfile)
216 {
217   _pl_b_initialize ();
218 }
219 
BitmapPlotter(istream & in,ostream & out,ostream & err)220 BitmapPlotter::BitmapPlotter (istream& in, ostream& out, ostream& err)
221 	: Plotter (in, out, err)
222 {
223   _pl_b_initialize ();
224 }
225 
BitmapPlotter(ostream & out)226 BitmapPlotter::BitmapPlotter (ostream& out)
227 	: Plotter (out)
228 {
229   _pl_b_initialize ();
230 }
231 
BitmapPlotter()232 BitmapPlotter::BitmapPlotter ()
233 {
234   _pl_b_initialize ();
235 }
236 
BitmapPlotter(FILE * infile,FILE * outfile,FILE * errfile,PlotterParams & parameters)237 BitmapPlotter::BitmapPlotter (FILE *infile, FILE *outfile, FILE *errfile, PlotterParams &parameters)
238 	:Plotter (infile, outfile, errfile, parameters)
239 {
240   _pl_b_initialize ();
241 }
242 
BitmapPlotter(FILE * outfile,PlotterParams & parameters)243 BitmapPlotter::BitmapPlotter (FILE *outfile, PlotterParams &parameters)
244 	:Plotter (outfile, parameters)
245 {
246   _pl_b_initialize ();
247 }
248 
BitmapPlotter(istream & in,ostream & out,ostream & err,PlotterParams & parameters)249 BitmapPlotter::BitmapPlotter (istream& in, ostream& out, ostream& err, PlotterParams &parameters)
250 	: Plotter (in, out, err, parameters)
251 {
252   _pl_b_initialize ();
253 }
254 
BitmapPlotter(ostream & out,PlotterParams & parameters)255 BitmapPlotter::BitmapPlotter (ostream& out, PlotterParams &parameters)
256 	: Plotter (out, parameters)
257 {
258   _pl_b_initialize ();
259 }
260 
BitmapPlotter(PlotterParams & parameters)261 BitmapPlotter::BitmapPlotter (PlotterParams &parameters)
262 	: Plotter (parameters)
263 {
264   _pl_b_initialize ();
265 }
266 
~BitmapPlotter()267 BitmapPlotter::~BitmapPlotter ()
268 {
269   /* if luser left the Plotter open, close it */
270   if (_plotter->data->open)
271     _API_closepl ();
272 
273   _pl_b_terminate ();
274 }
275 #endif
276 
277 #ifndef LIBPLOTTER
278 /* The following forwarding functions provide special support in libplot
279    for deriving classes such as the PNMPlotter and PNGPlotter classes from
280    the BitmapPlotter class.  In libplotter, forwarding is implemented by a
281    virtual function; see plotter.h. */
282 
283 /* Forwarding function called by any BitmapPlotter in closepl.  See
284    b_closepl.c, n_write.c, z_write.c for the forwarded-to functions.  The
285    first is currently a no-op. */
286 int
_maybe_output_image(Plotter * _plotter)287 _maybe_output_image (Plotter *_plotter)
288 {
289   int retval;
290 
291   switch ((int)(_plotter->data->type))
292     {
293     case (int)PL_BITMAP:
294     default:
295       retval = _pl_b_maybe_output_image (_plotter);
296       break;
297     case (int)PL_PNM:
298       retval = _pl_n_maybe_output_image (_plotter);
299       break;
300 #ifdef INCLUDE_PNG_SUPPORT
301     case (int)PL_PNG:
302       retval = _pl_z_maybe_output_image (_plotter);
303       break;
304 #endif
305     }
306 
307   return retval;
308 }
309 #endif /* not LIBPLOTTER */
310