1 /*
2    Copyright (c) 2001-2002 Andrew Bird  All rights reserved.
3    Distributed by Free Software Foundation, Inc.
4 
5 This file is part of HP2xx.
6 
7 HP2xx is distributed in the hope that it will be useful, but
8 WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
9 to anyone for the consequences of using it or for whether it serves any
10 particular purpose or works at all, unless he says so in writing.  Refer
11 to the GNU General Public License, Version 2 or later, for full details.
12 
13 Everyone is granted permission to copy, modify and redistribute
14 HP2xx, but only under the conditions described in the GNU General Public
15 License.  A copy of this license is supposed to have been
16 given to you along with HP2xx so you can know your rights and
17 responsibilities.  It should be in a file named COPYING.  Among other
18 things, the copyright notice and this notice must be preserved on all
19 copies.
20 
21 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22 */
23 
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <math.h>
28 #include "lindef.h"
29 #include "hpgl.h"
30 
31 
32 double CurrentLinePatLen;
33 /*LineType   CurrentLineType;*/
34 signed int CurrentLinePattern;
35 
36 LINESTYLE lt;
37 
38 LineAttr CurrentLineAttr;
39 LineEnds CurrentLineEnd;
40 
41 /********************************************
42  * Line Style
43  ********************************************/
44 
set_line_style(SCHAR index,...)45 void set_line_style(SCHAR index, ...)
46 {
47 	SCHAR count;
48 	double factor, percentage;
49 	va_list ap;
50 
51 	SCHAR val;
52 
53 	va_start(ap, index);
54 
55 	for (count = 0, percentage = 0; count < LT_ELEMENTS; count++) {
56 
57 		val = va_arg(ap, int);
58 
59 		if (val < 0) {
60 			break;
61 		} else {
62 			lt[index - LT_MIN][count] = (double) val;
63 			percentage += val;
64 		}
65 	}
66 
67 	lt[index - LT_MIN][count] = -1;
68 
69 	if (fabs(percentage - 100.) > 0.5) {
70 		factor = 100.0 / percentage;
71 		for (count = 0; count < LT_ELEMENTS; count++) {
72 			if (lt[index - LT_MIN][count] < 0) {
73 				break;
74 			} else {
75 				lt[index - LT_MIN][count] *= factor;
76 			}
77 		}
78 	}
79 
80 	va_end(ap);
81 
82 }
83 
set_line_style_by_UL(FILE * hd)84 void set_line_style_by_UL(FILE * hd)
85 {
86 	SCHAR index, pos_index, neg_index, count, i;
87 	double factor, percentage;
88 	float tmp;
89 
90 	if (read_float(&tmp, hd)) {
91 		set_line_style_defaults();	/* reset to defaults */
92 		return;
93 	} else {
94 		index = (int) tmp;
95 	}
96 
97 	pos_index = index - LT_MIN;
98 	neg_index = (index * -1) - LT_MIN;
99 
100 	for (count = 0, percentage = 0; (read_float(&tmp, hd) == 0); count++) {	/* while there is an argument */
101 		lt[pos_index][count] = (double) tmp;
102 		percentage += (int) tmp;
103 	}
104 
105 	lt[pos_index][count] = -1;
106 
107 	if (fabs(percentage - 100.) > 0.5) {
108 		factor = 100.0 / percentage;
109 		for (count = 0; count < LT_ELEMENTS; count++) {
110 			if (lt[pos_index][count] < 0) {
111 				break;
112 			} else {
113 				lt[pos_index][count] *= factor;
114 			}
115 		}
116 	}
117 	/* now derive the adaptive version */
118 
119 	count--;
120 
121 	if (count % 2) {	/* last value denotes a gap */
122 		lt[neg_index][0] = lt[pos_index][0] / 2;
123 		for (i = 1; i <= count; i++)
124 			lt[neg_index][i] = lt[pos_index][i];
125 		lt[neg_index][count + 1] = lt[pos_index][0] / 2;
126 		lt[neg_index][count + 2] = -1;
127 	} else {		/* last value denotes a line */
128 		lt[neg_index][0] =
129 		    (lt[pos_index][0] + lt[pos_index][count]) / 2;
130 		for (i = 1; i < count; i++)
131 			lt[neg_index][i] = lt[pos_index][i];
132 		lt[neg_index][count] = lt[neg_index][0];
133 		lt[neg_index][count + 1] = -1;
134 	}
135 
136 }
137 
138 
set_line_style_defaults()139 void set_line_style_defaults()
140 {
141 /*                 Line  gap   Line  gap   Line   gap   Line  TERM        */
142 
143 	set_line_style(-8, 25, 10, 0, 10, 10, 10, 0, 10, 25, -1);
144 	set_line_style(-7, 35, 10, 0, 10, 0, 10, 35, -1);
145 	set_line_style(-6, 25, 10, 10, 10, 10, 10, 25, -1);
146 	set_line_style(-5, 35, 10, 10, 10, 35, -1);
147 	set_line_style(-4, 40, 10, 0, 10, 40, -1);
148 	set_line_style(-3, 35, 30, 35, -1);
149 	set_line_style(-2, 25, 50, 25, -1);
150 	set_line_style(-1, 0, 100, 0, -1);
151 	set_line_style(0, 0, 100, -1);
152 	set_line_style(1, 0, 100, -1);
153 	set_line_style(2, 50, 50, -1);
154 	set_line_style(3, 70, 30, -1);
155 	set_line_style(4, 80, 10, 0, 10, -1);
156 	set_line_style(5, 70, 10, 10, 10, -1);
157 	set_line_style(6, 50, 10, 10, 10, 10, 10, -1);
158 	set_line_style(7, 70, 10, 0, 10, 0, 10, -1);
159 	set_line_style(8, 50, 10, 0, 10, 10, 10, 0, 10, -1);
160 }
161 
print_line_style(void)162 void print_line_style(void)
163 {
164 	int i, j;
165 
166 	printf("\n");
167 
168 	for (j = 0; j < LT_PATTERNS; j++) {
169 		if (lt[j][0] < 0)
170 			continue;
171 		else
172 			printf("LT %3d ", LT_MIN + j);
173 
174 		for (i = 0; i <= LT_ELEMENTS; i++) {
175 			if (lt[j][i] < 0)
176 				break;
177 			printf("%3.00f ", lt[j][i]);
178 		}
179 		printf("\n");
180 	}
181 }
182 
183 
184 /*************************************************
185  *  Line Attributes
186  *************************************************/
187 
set_line_attr_defaults(void)188 void set_line_attr_defaults(void)
189 {
190 	PlotCmd_to_tmpfile(DEF_LA);
191 	Line_Attr_to_tmpfile(LineAttrEnd, LAE_butt);
192 #define LA_JOINS_LIMIT_SUPPORT 1
193 #ifdef LA_JOINS_LIMIT_SUPPORT
194 	PlotCmd_to_tmpfile(DEF_LA);
195 	Line_Attr_to_tmpfile(LineAttrJoin, LAJ_plain_miter);
196 
197 	PlotCmd_to_tmpfile(DEF_LA);
198 	Line_Attr_to_tmpfile(LineAttrLimit, 5);	/* 5 times line width */
199 #endif
200 }
201 
set_line_attr(FILE * hd)202 void set_line_attr(FILE * hd)
203 {
204 	float ftmp1;
205 	float ftmp2;
206 
207 /*   LineEnds itmp;*/
208 	int itmp;
209 
210 	if (read_float(&ftmp1, hd)) {	/* No kind found        */
211 		set_line_attr_defaults();
212 		return;
213 	}
214 
215 	for (;;) {
216 
217 		if (read_float(&ftmp2, hd)) {	/* No value found       */
218 			/* do_error */
219 			return;
220 		}
221 		itmp = (int) ftmp2;
222 
223 		PlotCmd_to_tmpfile(DEF_LA);
224 
225 		switch ((int) ftmp1) {
226 		case 1:
227 			if ((itmp >= LAE_butt) && (itmp <= LAE_round)) {
228 				Line_Attr_to_tmpfile(LineAttrEnd, itmp);
229 			} else {
230 				Line_Attr_to_tmpfile(LineAttrEnd,
231 						     LAE_butt);
232 			}
233 			break;
234 		case 2:
235 			if ((itmp >= LAJ_plain_miter)
236 			    && (itmp <= LAJ_nojoin)) {
237 				Line_Attr_to_tmpfile(LineAttrJoin, itmp);
238 			} else {
239 				Line_Attr_to_tmpfile(LineAttrJoin,
240 						     LAJ_plain_miter);
241 			}
242 			break;
243 		case 3:
244 			Line_Attr_to_tmpfile(LineAttrLimit, itmp);
245 			break;
246 		}
247 		if (read_float(&ftmp1, hd)) {	/* No kind found        */
248 			return;
249 		}
250 	}
251 	return;
252 }
253 
Line_Attr_to_tmpfile(LineAttrKind kind,int value)254 void Line_Attr_to_tmpfile(LineAttrKind kind, int value)
255 {
256 	LineAttrKind tk = kind;
257 	LineEnds tv = value;
258 
259 	if (record_off)		/* return if current plot is not the selected one */
260 		return;		/* (of a multi-image file) */
261 
262 	if (kind == LineAttrEnd)	/* save this so we may save/restore the current state before character draw */
263 		CurrentLineEnd = value;
264 
265 	if (fwrite(&tk, sizeof(tk), 1, td) != 1) {
266 		PError("Line_Attr_to_tmpfile - kind");
267 		Eprintf("Error @ Cmd %ld\n", vec_cntr_w);
268 		exit(ERROR);
269 	}
270 
271 	if (fwrite(&tv, sizeof(tv), 1, td) != 1) {
272 		PError("Line_Attr_to_tmpfile - value");
273 		Eprintf("Error @ Cmd %ld\n", vec_cntr_w);
274 		exit(ERROR);
275 	}
276 
277 	return;
278 }
279 
load_line_attr(FILE * td)280 int load_line_attr(FILE * td)
281 {
282 	LineAttrKind kind;
283 	int value;
284 	static int FoundJoin = 0;
285 	static int FoundLimit = 0;
286 
287 	if (fread((void *) &kind, sizeof(kind), 1, td) != 1) {
288 		return (-1);
289 	}
290 
291 	if (fread((void *) &value, sizeof(value), 1, td) != 1) {
292 		return (-1);
293 	}
294 
295 	switch (kind) {
296 	case LineAttrEnd:
297 		CurrentLineAttr.End = value;
298 		break;
299 	case LineAttrJoin:
300 		if (!FoundJoin) {
301 			if (!silent_mode)
302 				fprintf(stderr,
303 					"\nLA - Joins not supported\n");
304 			FoundJoin = 1;
305 		}
306 		CurrentLineAttr.Join = value;
307 	case LineAttrLimit:
308 		if (!FoundLimit) {
309 			if (!silent_mode)
310 				fprintf(stderr,
311 					"\nLA - Limit not supported\n");
312 			FoundLimit = 1;
313 		}
314 		CurrentLineAttr.Limit = value;
315 		break;
316 	}
317 
318 	return (0);
319 }
320