]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/hpgl-config.c
Load cups into easysw/current.
[thirdparty/cups.git] / filter / hpgl-config.c
1 /*
2 * "$Id: hpgl-config.c 4494 2005-02-18 02:18:11Z mike $"
3 *
4 * HP-GL/2 configuration routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2005 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * update_transform() - Update the page transformation matrix as needed.
29 * BP_begin_plot() - Start a plot...
30 * DF_default_values() - Set all state info to the default values.
31 * IN_initialize() - Initialize the plotter.
32 * IP_input_absolute() - Set P1 and P2 values for the plot.
33 * IR_input_relative() - Update P1 and P2.
34 * IW_input_window() - Setup an input window.
35 * PG_advance_page() - Eject the current page.
36 * PS_plot_size() - Set the plot size.
37 * RO_rotate() - Rotate the plot.
38 * RP_replot() - Replot the current page.
39 * SC_scale() - Set user-defined scaling.
40 */
41
42 /*
43 * Include necessary headers...
44 */
45
46 #include "hpgltops.h"
47
48 #define max(a,b) ((a) < (b) ? (b) : (a))
49
50
51 /*
52 * 'update_transform()' - Update the page transformation matrix as needed.
53 */
54
55 void
56 update_transform(void)
57 {
58 float page_width, /* Actual page width */
59 page_height; /* Actual page height */
60 float scaling; /* Scaling factor */
61 float left, right, /* Scaling window */
62 bottom, top;
63 float width, height; /* Scaling width and height */
64 float iw1[2], iw2[2]; /* Clipping window */
65
66
67 /*
68 * Get the page and input window sizes...
69 */
70
71 if (FitPlot)
72 {
73 page_width = PageRight - PageLeft;
74 page_height = PageTop - PageBottom;
75 }
76 else
77 {
78 page_width = (P2[0] - P1[0]) * 72.0f / 1016.0f;
79 page_height = (P2[1] - P1[1]) * 72.0f / 1016.0f;
80 }
81
82 fprintf(stderr, "DEBUG: page_width = %.0f, page_height = %.0f\n",
83 page_width, page_height);
84
85 if (page_width == 0 || page_height == 0)
86 return;
87
88 /*
89 * Set the scaling window...
90 */
91
92 switch (ScalingType)
93 {
94 default : /* No user scaling */
95 left = P1[0];
96 bottom = P1[1];
97 right = P2[0];
98 top = P2[1];
99 break;
100
101 case 0 : /* Anisotropic (non-uniform) scaling */
102 left = Scaling1[0];
103 bottom = Scaling1[1];
104 right = Scaling2[0];
105 top = Scaling2[1];
106 break;
107
108 case 1 : /* Isotropic (uniform) scaling */
109 left = Scaling1[0];
110 bottom = Scaling1[1];
111 right = Scaling2[0];
112 top = Scaling2[1];
113
114 width = right - left;
115 height = top - bottom;
116
117 if (width == 0 || height == 0)
118 return;
119
120 if ((width * page_height) != (height * page_width))
121 {
122 scaling = height * page_width / page_height;
123 if (width < scaling)
124 {
125 width = scaling;
126 left = 0.5f * (left + right - width);
127 right = left + width;
128 }
129 else
130 {
131 height = width * page_height / page_width;
132 bottom = 0.5f * (bottom + top - height);
133 top = bottom + height;
134 }
135 }
136 break;
137
138 case 2 :
139 left = Scaling1[0];
140 bottom = Scaling1[1];
141 right = left + page_width * Scaling2[0] * 1016.0f / 72.0f;
142 top = bottom + page_height * Scaling2[1] * 1016.0f / 72.0f;
143 break;
144 }
145
146 width = right - left;
147 height = top - bottom;
148
149 if (width == 0 || height == 0)
150 return;
151
152 /*
153 * Scale the plot as needed...
154 */
155
156 if (Rotation == 0 || Rotation == 180)
157 scaling = page_width / width;
158 else
159 scaling = page_width / height;
160
161 if (FitPlot)
162 scaling *= max(page_width, page_height) / max(PlotSize[1], PlotSize[0]);
163
164 /*
165 * Offset for the current P1 location...
166 */
167
168 if (FitPlot)
169 {
170 left = 0;
171 bottom = 0;
172 }
173 else
174 {
175 left = P1[0] * 72.0f / 1016.0f;
176 bottom = P1[1] * 72.0f / 1016.0f;
177 }
178
179 /*
180 * Generate a new transformation matrix...
181 */
182
183 switch (Rotation)
184 {
185 default :
186 case 0 :
187 Transform[0][0] = scaling;
188 Transform[0][1] = 0.0;
189 Transform[0][2] = -left;
190 Transform[1][0] = 0.0;
191 Transform[1][1] = scaling;
192 Transform[1][2] = -bottom;
193 break;
194
195 case 90 :
196 Transform[0][0] = 0.0;
197 Transform[0][1] = -scaling;
198 Transform[0][2] = PageLength - left;
199 Transform[1][0] = scaling;
200 Transform[1][1] = 0.0;
201 Transform[1][2] = -bottom;
202 break;
203
204 case 180 :
205 Transform[0][0] = -scaling;
206 Transform[0][1] = 0.0;
207 Transform[0][2] = PageLength - left;
208 Transform[1][0] = 0.0;
209 Transform[1][1] = -scaling;
210 Transform[1][2] = PageWidth - bottom;
211 break;
212
213 case 270 :
214 Transform[0][0] = 0.0;
215 Transform[0][1] = scaling;
216 Transform[0][2] = -left;
217 Transform[1][0] = -scaling;
218 Transform[1][1] = 0.0;
219 Transform[1][2] = PageWidth - bottom;
220 break;
221 }
222
223 fprintf(stderr, "DEBUG: Transform = [ %.3f %.3f\n"
224 "DEBUG: %.3f %.3f\n"
225 "DEBUG: %.3f %.3f ]\n",
226 Transform[0][0], Transform[1][0], Transform[0][1],
227 Transform[1][1], Transform[0][2], Transform[1][2]);
228
229 if (FitPlot)
230 {
231 if (Rotation == 0 || Rotation == 180)
232 PenScaling = page_width / PlotSize[1];
233 else
234 PenScaling = page_width / PlotSize[0];
235 }
236 else
237 PenScaling = 1.0;
238
239 if (PenScaling < 0.0)
240 PenScaling = -PenScaling;
241
242 if (PageDirty)
243 {
244 printf("%.2f setlinewidth\n", Pens[PenNumber].width * PenScaling);
245
246 if (IW1[0] != IW2[0] && IW1[1] != IW2[1])
247 {
248 iw1[0] = IW1[0] * 72.0f / 1016.0f;
249 iw1[1] = IW1[1] * 72.0f / 1016.0f;
250 iw2[0] = IW2[0] * 72.0f / 1016.0f;
251 iw2[1] = IW2[1] * 72.0f / 1016.0f;
252
253 printf("initclip MP %.3f %.3f MO %.3f %.3f LI %.3f %.3f LI %.3f %.3f LI CP clip\n",
254 iw1[0], iw1[1], iw1[0], iw2[1], iw2[0], iw2[1], iw2[0], iw1[1]);
255 }
256 }
257 }
258
259
260 /*
261 * 'BP_begin_plot()' - Start a plot...
262 */
263
264 void
265 BP_begin_plot(int num_params, /* I - Number of parameters */
266 param_t *params) /* I - Parameters */
267 {
268 (void)num_params;
269 (void)params;
270 }
271
272
273 /*
274 * 'DF_default_values()' - Set all state info to the default values.
275 */
276
277 void
278 DF_default_values(int num_params, /* I - Number of parameters */
279 param_t *params) /* I - Parameters */
280 {
281 (void)num_params;
282 (void)params;
283
284 NP_number_pens(0, NULL);
285 AC_anchor_corner(0, NULL);
286 AD_define_alternate(0, NULL);
287 SD_define_standard(0, NULL);
288 CF_character_fill(0, NULL);
289 DI_absolute_direction(0, NULL);
290 DT_define_label_term(0, NULL);
291 DV_define_variable_path(0, NULL);
292 ES_extra_space(0, NULL);
293 FT_fill_type(0, NULL);
294 IW_input_window(0, NULL);
295 LA_line_attributes(0, NULL);
296 LO_label_origin(0, NULL);
297 LT_line_type(0, NULL);
298 PA_plot_absolute(0, NULL);
299 PolygonMode = 0;
300 RF_raster_fill(0, NULL);
301 SC_scale(0, NULL);
302 SM_symbol_mode(0, NULL);
303 SS_select_standard(0, NULL);
304 TD_transparent_data(0, NULL);
305 UL_user_line_type(0, NULL);
306 }
307
308
309 /*
310 * 'IN_initialize()' - Initialize the plotter.
311 */
312
313 void
314 IN_initialize(int num_params, /* I - Number of parameters */
315 param_t *params) /* I - Parameters */
316 {
317 (void)num_params;
318 (void)params;
319
320 DF_default_values(0, NULL);
321 PU_pen_up(0, NULL);
322 RO_rotate(0, NULL);
323 PS_plot_size(0, NULL);
324 WU_width_units(0, NULL);
325 PW_pen_width(0, NULL);
326
327 PenWidth = 1;
328
329 PenPosition[0] = PenPosition[1] = 0.0;
330 }
331
332
333 /*
334 * 'IP_input_absolute()' - Set P1 and P2 values for the plot.
335 */
336
337 void
338 IP_input_absolute(int num_params, /* I - Number of parameters */
339 param_t *params) /* I - Parameters */
340 {
341 if (num_params == 0)
342 {
343 P1[0] = PageLeft / 72.0f * 1016.0f;
344 P1[1] = PageBottom / 72.0f * 1016.0f;
345 P2[0] = PageRight / 72.0f * 1016.0f;
346 P2[1] = PageTop / 72.0f * 1016.0f;
347 }
348 else if (num_params == 2)
349 {
350 P2[0] -= P1[0];
351 P2[1] -= P1[1];
352 P1[0] = params[0].value.number;
353 P1[1] = params[1].value.number;
354 P2[0] += P1[0];
355 P2[1] += P1[1];
356 }
357 else if (num_params == 4)
358 {
359 P1[0] = params[0].value.number;
360 P1[1] = params[1].value.number;
361 P2[0] = params[2].value.number;
362 P2[1] = params[3].value.number;
363 }
364
365 IW1[0] = 0.0;
366 IW1[1] = 0.0;
367 IW2[0] = 0.0;
368 IW2[1] = 0.0;
369
370 if (ScalingType < 0)
371 {
372 Scaling1[0] = P1[0];
373 Scaling1[0] = P1[1];
374 Scaling2[0] = P2[0];
375 Scaling2[1] = P2[1];
376 }
377
378 update_transform();
379 }
380
381
382 /*
383 * 'IR_input_relative()' - Update P1 and P2.
384 */
385
386 void
387 IR_input_relative(int num_params, /* I - Number of parameters */
388 param_t *params) /* I - Parameters */
389 {
390 if (num_params == 0)
391 {
392 P1[0] = PageLeft / 72.0f * 1016.0f;
393 P1[1] = PageBottom / 72.0f * 1016.0f;
394 P2[0] = PageRight / 72.0f * 1016.0f;
395 P2[1] = PageTop / 72.0f * 1016.0f;
396 }
397 else if (num_params == 2)
398 {
399 P2[0] -= P1[0];
400 P2[1] -= P1[1];
401 P1[0] = params[0].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f;
402 P1[1] = params[1].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f;
403 P2[0] += P1[0];
404 P2[1] += P1[1];
405 }
406 else if (num_params == 4)
407 {
408 P1[0] = params[0].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f;
409 P1[1] = params[1].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f;
410 P2[0] = params[2].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f;
411 P2[1] = params[3].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f;
412 }
413
414 IW1[0] = 0.0;
415 IW1[1] = 0.0;
416 IW2[0] = 0.0;
417 IW2[1] = 0.0;
418
419 if (ScalingType < 0)
420 {
421 Scaling1[0] = P1[0];
422 Scaling1[0] = P1[1];
423 Scaling2[0] = P2[0];
424 Scaling2[1] = P2[1];
425 }
426
427 update_transform();
428 }
429
430
431 /*
432 * 'IW_input_window()' - Setup an input window.
433 */
434
435 void
436 IW_input_window(int num_params, /* I - Number of parameters */
437 param_t *params) /* I - Parameters */
438 {
439 if (num_params == 0)
440 {
441 IW1[0] = PageLeft / 72.0f * 1016.0f;
442 IW1[1] = PageBottom / 72.0f * 1016.0f;
443 IW2[0] = PageRight / 72.0f * 1016.0f;
444 IW2[1] = PageTop / 72.0f * 1016.0f;
445 }
446 else if (num_params == 4)
447 {
448
449 if (ScalingType < 0)
450 {
451 IW1[0] = params[0].value.number;
452 IW1[1] = params[1].value.number;
453 IW2[0] = params[2].value.number;
454 IW2[1] = params[3].value.number;
455 }
456 else
457 {
458 IW1[0] = (Transform[0][0] * params[0].value.number +
459 Transform[0][1] * params[1].value.number +
460 Transform[0][2]) / 72.0f * 1016.0f;
461 IW1[1] = (Transform[1][0] * params[0].value.number +
462 Transform[1][1] * params[1].value.number +
463 Transform[1][2]) / 72.0f * 1016.0f;
464 IW2[0] = (Transform[0][0] * params[2].value.number +
465 Transform[0][1] * params[3].value.number +
466 Transform[0][2]) / 72.0f * 1016.0f;
467 IW2[1] = (Transform[1][0] * params[2].value.number +
468 Transform[1][1] * params[3].value.number +
469 Transform[1][2]) / 72.0f * 1016.0f;
470 }
471
472 fprintf(stderr, "DEBUG: IW%.0f,%.0f,%.0f,%.0f = [ %.0f %.0f %.0f %.0f ]\n",
473 params[0].value.number, params[1].value.number,
474 params[2].value.number, params[3].value.number,
475 IW1[0], IW1[1], IW2[0], IW2[1]);
476 }
477
478
479 update_transform();
480 }
481
482
483 /*
484 * 'PG_advance_page()' - Eject the current page.
485 */
486
487 void
488 PG_advance_page(int num_params, /* I - Number of parameters */
489 param_t *params) /* I - Parameters */
490 {
491 (void)num_params;
492 (void)params;
493
494 if (PageDirty)
495 {
496 puts("grestore");
497 puts("showpage");
498
499 PageDirty = 0;
500 }
501 }
502
503
504 /*
505 * 'PS_plot_size()' - Set the plot size.
506 */
507
508 void
509 PS_plot_size(int num_params, /* I - Number of parameters */
510 param_t *params) /* I - Parameters */
511 {
512 switch (num_params)
513 {
514 case 0 : /* PS ; */
515 if (Rotation == 0 || Rotation == 180)
516 {
517 PlotSize[0] = PageWidth;
518 PlotSize[1] = PageLength;
519 }
520 else
521 {
522 PlotSize[0] = PageLength;
523 PlotSize[1] = PageWidth;
524 }
525
526 PlotSizeSet = 0;
527 break;
528 case 1 : /* PS length ; */
529 if (Rotation == 0 || Rotation == 180)
530 {
531 PlotSize[1] = 72.0f * params[0].value.number / 1016.0f;
532 PlotSize[0] = 0.75f * PlotSize[1];
533 }
534 else
535 {
536 PlotSize[0] = 72.0f * params[0].value.number / 1016.0f;
537 PlotSize[1] = 0.75f * PlotSize[0];
538 }
539
540 PlotSizeSet = 1;
541 break;
542 case 2 : /* PS length, width ; */
543 /*
544 * Unfortunately, it appears that NO application correctly
545 * sends a two-argument PS command as documented in the
546 * HP-GL/2 Reference Manual from HP. Instead, applications
547 * send the width before the length, which causes all sorts
548 * of problems when scaling.
549 *
550 * Rather than fight it, we now look for them as width,length
551 * instead of length,width.
552 *
553 * Don't like it? Send mail to the folks that make Ideas, Pro/E,
554 * AutoCAD, etc.
555 */
556
557 if (Rotation == 0 || Rotation == 180)
558 {
559 PlotSize[0] = 72.0f * params[0].value.number / 1016.0f;
560 PlotSize[1] = 72.0f * params[1].value.number / 1016.0f;
561 }
562 else
563 {
564 PlotSize[0] = 72.0f * params[1].value.number / 1016.0f;
565 PlotSize[1] = 72.0f * params[0].value.number / 1016.0f;
566 }
567
568 PlotSizeSet = 1;
569 break;
570 }
571
572 /*
573 * This is required for buggy files that don't set the input window.
574 */
575
576 IP_input_absolute(0, NULL);
577 }
578
579
580 /*
581 * 'RO_rotate()' - Rotate the plot.
582 */
583
584 void
585 RO_rotate(int num_params, /* I - Number of parameters */
586 param_t *params) /* I - Parameters */
587 {
588 if (num_params == 0)
589 Rotation = 0;
590 else
591 Rotation = (int)params[0].value.number;
592
593 update_transform();
594 }
595
596
597 /*
598 * 'RP_replot()' - Replot the current page.
599 */
600
601 void
602 RP_replot(int num_params, /* I - Number of parameters */
603 param_t *params) /* I - Parameters */
604 {
605 (void)num_params;
606 (void)params;
607 }
608
609
610 /*
611 * 'SC_scale()' - Set user-defined scaling.
612 */
613
614 void
615 SC_scale(int num_params, /* I - Number of parameters */
616 param_t *params) /* I - Parameters */
617 {
618 if (num_params == 0)
619 {
620 ScalingType = -1;
621 Scaling1[0] = P1[0];
622 Scaling1[0] = P1[1];
623 Scaling2[0] = P2[0];
624 Scaling2[1] = P2[1];
625 }
626 else if (num_params > 3)
627 {
628 Scaling1[0] = params[0].value.number;
629 Scaling2[0] = params[1].value.number;
630 Scaling1[1] = params[2].value.number;
631 Scaling2[1] = params[3].value.number;
632
633 if (num_params > 4)
634 ScalingType = (int)params[4].value.number;
635 else
636 ScalingType = 1;
637 }
638
639 update_transform();
640 }
641
642
643 /*
644 * End of "$Id: hpgl-config.c 4494 2005-02-18 02:18:11Z mike $".
645 */