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 #include "sys-defines.h"
20 #include "extern.h"
21 
22 bool
_pl_h_begin_page(S___ (Plotter * _plotter))23 _pl_h_begin_page (S___(Plotter *_plotter))
24 {
25   int i;
26 
27   /* With each call to openpl(), we reset our knowledge of the HP-GL
28      internal state, i.e. the dynamic derived-class-specific data members
29      of the HPGL or PCL Plotter.  The values are the same as are used in
30      initializing the Plotter (see h_defplot.c). */
31 
32   /* reset any soft-defined colors in the pen color array */
33   for (i = 0; i < HPGL2_MAX_NUM_PENS; i++)
34     if (_plotter->hpgl_pen_defined[i] == 1) /* i.e. soft-defined */
35       _plotter->hpgl_pen_defined[i] = 0; /* i.e. undefined */
36 
37   /* reset current pen */
38   _plotter->hpgl_pen = 1;
39 
40   /* if we can soft-define pen colors, reset free_pen data member by
41      determining what the next free pen is */
42   {
43     bool undefined_pen_seen = false;
44 
45     if (_plotter->hpgl_can_assign_colors) /* can soft-define pen colors */
46       for (i = 2; i < HPGL2_MAX_NUM_PENS; i++)
47 	{
48 	  if (_plotter->hpgl_pen_defined[i] == 0)
49 	    /* at least one pen with number > 1 is not yet defined */
50 	    {
51 	      /* record which such was encountered first */
52 	      _plotter->hpgl_free_pen = i;
53 	      undefined_pen_seen = true;
54 	      break;
55 	    }
56 	}
57     if (!undefined_pen_seen)
58       /* too many pens specified, can't soft-define colors */
59       _plotter->hpgl_can_assign_colors = false;
60   }
61 
62   /* reset additional data members of Plotter */
63   _plotter->hpgl_bad_pen = false;
64   _plotter->hpgl_pendown = false;
65   _plotter->hpgl_pen_width = 0.001;
66   _plotter->hpgl_line_type = HPGL_L_SOLID;
67   _plotter->hpgl_cap_style = HPGL_CAP_BUTT;
68   _plotter->hpgl_join_style = HPGL_JOIN_MITER;
69   _plotter->hpgl_miter_limit = 5.0; /* default HP-GL/2 value */
70   _plotter->hpgl_fill_type = HPGL_FILL_SOLID_BI;
71   _plotter->hpgl_fill_option1 = 0.0;
72   _plotter->hpgl_fill_option2 = 0.0;
73   _plotter->hpgl_symbol_set = PCL_ROMAN_8;
74   _plotter->hpgl_spacing = 0;
75   _plotter->hpgl_posture = 0;
76   _plotter->hpgl_stroke_weight = 0;
77   _plotter->hpgl_pcl_typeface = PCL_STICK_TYPEFACE;
78   _plotter->hpgl_charset_lower = HPGL_CHARSET_ASCII;
79   _plotter->hpgl_charset_upper = HPGL_CHARSET_ASCII;
80   _plotter->hpgl_rel_char_height = 0.0;
81   _plotter->hpgl_rel_char_width = 0.0;
82   _plotter->hpgl_rel_label_rise = 0.0;
83   _plotter->hpgl_rel_label_run = 0.0;
84   _plotter->hpgl_tan_char_slant = 0.0;
85   _plotter->hpgl_position_is_unknown = true;
86   _plotter->hpgl_pos.x = 0;
87   _plotter->hpgl_pos.y = 0;
88 
89   /* if a PCL Plotter, switch from PCL mode to HP-GL/2 mode */
90   _maybe_switch_to_hpgl (S___(_plotter));
91 
92   /* output HP-GL prologue */
93   if (_plotter->hpgl_version == 2)
94     {
95       sprintf (_plotter->data->page->point, "BP;IN;");
96       _update_buffer (_plotter->data->page);
97       /* include HP-GL/2 `plot length' directive; important mostly for roll
98 	 plotters */
99       sprintf (_plotter->data->page->point, "PS%d;",
100 	       IROUND(_plotter->hpgl_plot_length));
101       _update_buffer (_plotter->data->page);
102     }
103   else
104     {
105       sprintf (_plotter->data->page->point, "IN;");
106       _update_buffer (_plotter->data->page);
107     }
108 
109   /* make use of HP-GL's plotting-area rotation capability, if requested by
110      the HPGL_ROTATE parameter (this does not apply to PCL Plotters, for
111      which rotation=0 always) */
112   if (_plotter->hpgl_rotation != 0)
113     {
114       sprintf (_plotter->data->page->point, "RO%d;", _plotter->hpgl_rotation);
115       _update_buffer (_plotter->data->page);
116     }
117 
118   /* Set scaling points P1, P2 at lower left and upper right corners of our
119      viewport; or more accurately, at the two points that (0,0) and (1,1),
120      which are the lower right and upper right corners in NDC space, get
121      mapped to. */
122   sprintf (_plotter->data->page->point, "IP%d,%d,%d,%d;",
123 	   IROUND(_plotter->hpgl_p1.x), IROUND(_plotter->hpgl_p1.y),
124 	   IROUND(_plotter->hpgl_p2.x), IROUND(_plotter->hpgl_p2.y));
125   _update_buffer (_plotter->data->page);
126 
127   /* Set up `scaled device coordinates' within the viewport.  All
128      coordinates in the output file will be scaled device coordinates, not
129      physical device coordinates.  The range of scaled coordinates will be
130      independent of the viewport positioning, page size, etc.; see the
131      definitions of xmin,xmax,ymin,ymax in h_defplot.c. */
132   sprintf (_plotter->data->page->point, "SC%d,%d,%d,%d;",
133 	   IROUND (_plotter->data->xmin), IROUND (_plotter->data->xmax),
134 	   IROUND (_plotter->data->ymin), IROUND (_plotter->data->ymax));
135   _update_buffer (_plotter->data->page);
136 
137   if (_plotter->hpgl_version == 2)
138     {
139       /* Begin to define a palette, by specifying a number of logical pens.
140 	 (All HP-GL/2 devices should support the `NP' instruction, even
141 	 though many support only a default palette.) */
142       if (_plotter->hpgl_can_assign_colors)
143 	{
144 	  sprintf (_plotter->data->page->point, "NP%d;", HPGL2_MAX_NUM_PENS);
145 	  _update_buffer (_plotter->data->page);
146 	}
147       /* use relative units for pen width */
148       sprintf (_plotter->data->page->point, "WU1;");
149       _update_buffer (_plotter->data->page);
150     }
151 
152   /* select pen #1 (standard plotting convention) */
153   sprintf (_plotter->data->page->point, "SP1;");
154   _update_buffer (_plotter->data->page);
155 
156   /* For HP-GL/2 devices, set transparency mode to `opaque', if the user
157      allows it.  It should always be opaque to agree with libplot
158      conventions, but on some HP-GL/2 devices (mostly pen plotters) the
159      `TR' command allegedly does not NOP gracefully. */
160   if (_plotter->hpgl_version == 2 && _plotter->hpgl_use_opaque_mode)
161     {
162       sprintf (_plotter->data->page->point, "TR0;");
163       _update_buffer (_plotter->data->page);
164     }
165 
166   /* freeze contents of output buffer, i.e. the initialization code we've
167      just written to it, so that any later invocation of erase(), i.e.,
168      erase_page(), won't remove it */
169   _freeze_outbuf (_plotter->data->page);
170 
171   return true;
172 }
173 
174 void
_pl_h_maybe_switch_to_hpgl(S___ (Plotter * _plotter))175 _pl_h_maybe_switch_to_hpgl (S___(Plotter *_plotter))
176 {
177 }
178 
179 void
_pl_q_maybe_switch_to_hpgl(S___ (Plotter * _plotter))180 _pl_q_maybe_switch_to_hpgl (S___(Plotter *_plotter))
181 {
182   if (_plotter->data->page_number > 1) /* not first page */
183     /* eject previous page, by issuing PCL command */
184     {
185       strcpy (_plotter->data->page->point, "\f"); /* i.e. form feed */
186       _update_buffer (_plotter->data->page);
187     }
188   /* switch from PCL 5 to HP-GL/2 mode */
189   strcpy (_plotter->data->page->point, "\033%0B\n");
190   _update_buffer (_plotter->data->page);
191 }
192