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