]>
git.ipfire.org Git - thirdparty/cups.git/blob - filter/hpgl-vector.c
2 * "$Id: hpgl-vector.c 6649 2007-07-11 21:46:42Z mike $"
4 * HP-GL/2 vector routines for the Common UNIX Printing System (CUPS).
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1993-2007 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
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/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * AA_arc_absolute() - Draw an arc.
20 * AR_arc_relative() - Draw an arc relative to the current pen
21 * AT_arc_absolute3() - Draw an arc using 3 points.
22 * CI_circle() - Draw a circle.
23 * PA_plot_absolute() - Plot a line using absolute coordinates.
24 * PD_pen_down() - Start drawing.
25 * PE_polygon_encoded() - Draw an encoded polyline.
26 * PR_plot_relative() - Plot a line using relative coordinates.
27 * PU_pen_up() - Stop drawing.
28 * RT_arc_relative3() - Draw an arc through 3 points relative to the
29 * decode_number() - Decode an encoded number.
30 * plot_points() - Plot the specified points.
34 * Include necessary headers...
44 static double decode_number(unsigned char **, int, double);
45 static void plot_points(int, param_t
*);
49 * 'AA_arc_absolute()' - Draw an arc.
53 AA_arc_absolute(int num_params
, /* I - Number of parameters */
54 param_t
*params
) /* I - Parameters */
56 float x
, y
, /* Transformed coordinates */
57 dx
, dy
; /* Distance from current pen */
58 float start
, end
, /* Start and end angles */
59 theta
, /* Current angle */
60 dt
, /* Step between points */
61 radius
; /* Radius of arc */
67 x
= Transform
[0][0] * params
[0].value
.number
+
68 Transform
[0][1] * params
[1].value
.number
+
70 y
= Transform
[1][0] * params
[0].value
.number
+
71 Transform
[1][1] * params
[1].value
.number
+
74 dx
= PenPosition
[0] - x
;
75 dy
= PenPosition
[1] - y
;
77 start
= (float)(180.0 * atan2(dy
, dx
) / M_PI
);
81 end
= start
+ params
[2].value
.number
;
82 radius
= (float)hypot(dx
, dy
);
86 if (num_params
> 3 && params
[3].value
.number
> 0.0)
87 dt
= (float)fabs(params
[3].value
.number
);
96 Outputf("%.3f %.3f MO\n", PenPosition
[0], PenPosition
[1]);
99 for (theta
= start
+ dt
; theta
< end
; theta
+= dt
)
101 PenPosition
[0] = (float)(x
+ radius
* cos(M_PI
* theta
/ 180.0));
102 PenPosition
[1] = (float)(y
+ radius
* sin(M_PI
* theta
/ 180.0));
104 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
107 for (theta
= start
- dt
; theta
> end
; theta
-= dt
)
109 PenPosition
[0] = (float)(x
+ radius
* cos(M_PI
* theta
/ 180.0));
110 PenPosition
[1] = (float)(y
+ radius
* sin(M_PI
* theta
/ 180.0));
112 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
116 PenPosition
[0] = (float)(x
+ radius
* cos(M_PI
* end
/ 180.0));
117 PenPosition
[1] = (float)(y
+ radius
* sin(M_PI
* end
/ 180.0));
121 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
130 * 'AR_arc_relative()' - Draw an arc relative to the current pen
135 AR_arc_relative(int num_params
, /* I - Number of parameters */
136 param_t
*params
) /* I - Parameters */
138 float x
, y
, /* Transformed coordinates */
139 dx
, dy
; /* Distance from current pen */
140 float start
, end
, /* Start and end angles */
141 theta
, /* Current angle */
142 dt
, /* Step between points */
143 radius
; /* Radius of arc */
149 x
= Transform
[0][0] * params
[0].value
.number
+
150 Transform
[0][1] * params
[1].value
.number
+
152 y
= Transform
[1][0] * params
[0].value
.number
+
153 Transform
[1][1] * params
[1].value
.number
+
156 dx
= PenPosition
[0] - x
;
157 dy
= PenPosition
[1] - y
;
159 start
= (float)(180.0 * atan2(dy
, dx
) / M_PI
);
163 end
= start
+ params
[2].value
.number
;
164 radius
= (float)hypot(dx
, dy
);
168 if (num_params
> 3 && params
[3].value
.number
> 0.0)
169 dt
= (float)fabs(params
[3].value
.number
);
178 Outputf("%.3f %.3f MO\n", PenPosition
[0], PenPosition
[1]);
181 for (theta
= start
+ dt
; theta
< end
; theta
+= dt
)
183 PenPosition
[0] = (float)(x
+ radius
* cos(M_PI
* theta
/ 180.0));
184 PenPosition
[1] = (float)(y
+ radius
* sin(M_PI
* theta
/ 180.0));
186 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
189 for (theta
= start
- dt
; theta
> end
; theta
-= dt
)
191 PenPosition
[0] = (float)(x
+ radius
* cos(M_PI
* theta
/ 180.0));
192 PenPosition
[1] = (float)(y
+ radius
* sin(M_PI
* theta
/ 180.0));
194 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
198 PenPosition
[0] = (float)(x
+ radius
* cos(M_PI
* end
/ 180.0));
199 PenPosition
[1] = (float)(y
+ radius
* sin(M_PI
* end
/ 180.0));
203 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
212 * 'AT_arc_absolute3()' - Draw an arc using 3 points.
216 * Currently this only draws two line segments through the
221 AT_arc_absolute3(int num_params
, /* I - Number of parameters */
222 param_t
*params
) /* I - Parameters */
234 Outputf("%.3f %.3f MO\n", PenPosition
[0], PenPosition
[1]);
236 PenPosition
[0] = Transform
[0][0] * params
[0].value
.number
+
237 Transform
[0][1] * params
[1].value
.number
+
239 PenPosition
[1] = Transform
[1][0] * params
[0].value
.number
+
240 Transform
[1][1] * params
[1].value
.number
+
243 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
246 PenPosition
[0] = Transform
[0][0] * params
[2].value
.number
+
247 Transform
[0][1] * params
[3].value
.number
+
249 PenPosition
[1] = Transform
[1][0] * params
[2].value
.number
+
250 Transform
[1][1] * params
[3].value
.number
+
255 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
264 * 'CI_circle()' - Draw a circle.
268 CI_circle(int num_params
, /* I - Number of parameters */
269 param_t
*params
) /* I - Parameters */
271 float x
, y
; /* Transformed coordinates */
272 float theta
, /* Current angle */
273 dt
, /* Step between points */
274 radius
; /* Radius of circle */
283 radius
= params
[0].value
.number
;
286 dt
= (float)fabs(params
[1].value
.number
);
295 for (theta
= 0.0; theta
< 360.0; theta
+= dt
)
297 x
= (float)(PenPosition
[0] +
298 radius
* cos(M_PI
* theta
/ 180.0) * Transform
[0][0] +
299 radius
* sin(M_PI
* theta
/ 180.0) * Transform
[0][1]);
300 y
= (float)(PenPosition
[1] +
301 radius
* cos(M_PI
* theta
/ 180.0) * Transform
[1][0] +
302 radius
* sin(M_PI
* theta
/ 180.0) * Transform
[1][1]);
304 Outputf("%.3f %.3f %s\n", x
, y
, theta
== 0.0 ? "MO" : "LI");
314 * 'PA_plot_absolute()' - Plot a line using absolute coordinates.
318 PA_plot_absolute(int num_params
, /* I - Number of parameters */
319 param_t
*params
) /* I - Parameters */
324 plot_points(num_params
, params
);
329 * 'PD_pen_down()' - Start drawing.
333 PD_pen_down(int num_params
, /* I - Number of parameters */
334 param_t
*params
) /* I - Parameters */
339 plot_points(num_params
, params
);
344 * 'PE_polygon_encoded()' - Draw an encoded polyline.
348 PE_polyline_encoded(int num_params
, /* I - Number of parameters */
349 param_t
*params
) /* I - Parameters */
351 unsigned char *s
; /* Pointer into string */
352 int temp
, /* Temporary value */
353 base_bits
, /* Data bits per byte */
354 draw
, /* Draw or move */
355 abscoords
; /* Use absolute coordinates */
356 double tx
, ty
, /* Transformed coordinates */
357 x
, y
, /* Raw coordinates */
358 frac_bits
; /* Multiplier for encoded number */
377 Outputf("%.3f %.3f MO\n", PenPosition
[0], PenPosition
[1]);
381 for (s
= (unsigned char *)params
[0].value
.string
; *s
!= '\0';)
389 fputs("DEBUG: 7-bit\n", stderr
);
392 Outputf("%% PE: 7-bit\n");
394 case ':' : /* Select pen */
396 PenNumber
= (int)decode_number(&s
, base_bits
, 1.0);
399 fprintf(stderr
, "DEBUG: set pen #%d\n", PenNumber
);
402 Outputf("%% PE: set pen #%d\n", PenNumber
);
405 printf("%.3f %.3f %.3f %.2f SP\n", Pens
[PenNumber
].rgb
[0],
406 Pens
[PenNumber
].rgb
[1], Pens
[PenNumber
].rgb
[2],
407 Pens
[PenNumber
].width
* PenScaling
);
409 case '<' : /* Next coords are a move-to */
414 fputs("DEBUG: moveto\n", stderr
);
417 Outputf("%% PE: moveto\n");
419 case '>' : /* Set fractional bits */
421 temp
= (int)decode_number(&s
, base_bits
, 1.0);
422 frac_bits
= 1.0 / (1 << temp
);
425 fprintf(stderr
, "DEBUG: set fractional bits %d\n", temp
);
428 Outputf("%% PE: set fractional bits %d\n", temp
);
430 case '=' : /* Next coords are absolute */
435 fputs("DEBUG: absolute\n", stderr
);
438 Outputf("%% PE: absolute\n");
447 x
= decode_number(&s
, base_bits
, frac_bits
);
448 y
= decode_number(&s
, base_bits
, frac_bits
);
451 fprintf(stderr
, "DEBUG: coords %.3f %.3f\n", x
, y
);
454 Outputf("%% PE: coords %.3f %.3f\n", x
, y
);
458 tx
= Transform
[0][0] * x
+ Transform
[0][1] * y
+
460 ty
= Transform
[1][0] * x
+ Transform
[1][1] * y
+
463 else if (x
== 0.0 && y
== 0.0)
470 tx
= Transform
[0][0] * x
+ Transform
[0][1] * y
+
472 ty
= Transform
[1][0] * x
+ Transform
[1][1] * y
+
478 if (fabs(PenPosition
[0] - tx
) > 0.001 ||
479 fabs(PenPosition
[1] - ty
) > 0.001)
480 Outputf("%.3f %.3f LI\n", tx
, ty
);
483 Outputf("%.3f %.3f MO\n", tx
, ty
);
485 PenPosition
[0] = (float)tx
;
486 PenPosition
[1] = (float)ty
;
497 if (*s
!= '\n' && *s
!= '\r')
498 fprintf(stderr
, "WARNING: ignoring illegal PE char \'%c\'...\n", *s
);
510 * 'PR_plot_relative()' - Plot a line using relative coordinates.
514 PR_plot_relative(int num_params
, /* I - Number of parameters */
515 param_t
*params
) /* I - Parameters */
520 plot_points(num_params
, params
);
525 * 'PU_pen_up()' - Stop drawing.
529 PU_pen_up(int num_params
, /* I - Number of parameters */
530 param_t
*params
) /* I - Parameters */
535 plot_points(num_params
, params
);
540 * 'RT_arc_relative3()' - Draw an arc through 3 points relative to the
541 * current pen position.
545 * This currently only draws two line segments through the specified
550 RT_arc_relative3(int num_params
, /* I - Number of parameters */
551 param_t
*params
) /* I - Parameters */
563 Outputf("%.3f %.3f MO\n", PenPosition
[0], PenPosition
[1]);
565 PenPosition
[0] = Transform
[0][0] * params
[0].value
.number
+
566 Transform
[0][1] * params
[1].value
.number
+
568 PenPosition
[1] = Transform
[1][0] * params
[0].value
.number
+
569 Transform
[1][1] * params
[1].value
.number
+
572 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
575 PenPosition
[0] = Transform
[0][0] * params
[2].value
.number
+
576 Transform
[0][1] * params
[3].value
.number
+
578 PenPosition
[1] = Transform
[1][0] * params
[2].value
.number
+
579 Transform
[1][1] * params
[3].value
.number
+
584 Outputf("%.3f %.3f LI\n", PenPosition
[0], PenPosition
[1]);
593 * 'decode_number()' - Decode an encoded number.
596 static double /* O - Value */
597 decode_number(unsigned char **s
, /* IO - String to decode */
598 int base_bits
, /* I - Number of data bits per byte */
599 double frac_bits
) /* I - Multiplier for fractional data */
601 double temp
, /* Current value */
602 shift
; /* Multiplier */
603 int sign
; /* Sign of result */
610 for (temp
= 0.0, shift
= frac_bits
* 0.5; **s
!= '\0'; (*s
) ++)
611 if (**s
>= 95 && **s
< 127)
620 temp
+= ((**s
- 95) & ~1) * shift
;
623 temp
+= (**s
- 95) * shift
;
628 if (**s
!= '\r' && **s
!= '\n')
629 fprintf(stderr
, "DEBUG: Bad PE character 0x%02X!\n", **s
);
642 temp
+= ((**s
- 63) & ~1) * shift
;
645 temp
+= (**s
- 63) * shift
;
652 for (temp
= 0.0, shift
= frac_bits
* 0.5; **s
!= '\0'; (*s
) ++)
653 if (**s
>= 191 && **s
< 255)
662 temp
+= ((**s
- 191) & ~1) * shift
;
665 temp
+= (**s
- 191) * shift
;
670 if (**s
!= '\r' && **s
!= '\n')
671 fprintf(stderr
, "DEBUG: Bad PE character 0x%02X!\n", **s
);
684 temp
+= ((**s
- 63) & ~1) * shift
;
687 temp
+= (**s
- 63) * shift
;
695 return (temp
* sign
);
700 * 'plot_points()' - Plot the specified points.
704 plot_points(int num_params
, /* I - Number of parameters */
705 param_t
*params
) /* I - Parameters */
707 int i
; /* Looping var */
708 float x
, y
; /* Transformed coordinates */
716 Outputf("%.3f %.3f MO\n", PenPosition
[0], PenPosition
[1]);
722 for (i
= 0; i
< num_params
; i
+= 2)
726 x
= Transform
[0][0] * params
[i
+ 0].value
.number
+
727 Transform
[0][1] * params
[i
+ 1].value
.number
+
729 y
= Transform
[1][0] * params
[i
+ 0].value
.number
+
730 Transform
[1][1] * params
[i
+ 1].value
.number
+
735 x
= Transform
[0][0] * params
[i
+ 0].value
.number
+
736 Transform
[0][1] * params
[i
+ 1].value
.number
+
738 y
= Transform
[1][0] * params
[i
+ 0].value
.number
+
739 Transform
[1][1] * params
[i
+ 1].value
.number
+
745 if (PolygonMode
&& i
== 0)
746 Outputf("%.3f %.3f MO\n", x
, y
);
747 else if (fabs(PenPosition
[0] - x
) > 0.001 ||
748 fabs(PenPosition
[1] - y
) > 0.001)
749 Outputf("%.3f %.3f LI\n", x
, y
);
765 * End of "$Id: hpgl-vector.c 6649 2007-07-11 21:46:42Z mike $".