First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xprint / pcl / PclArc.c
blob0d8289e33e78646d312badc33448fda36ce5913c
1 /*******************************************************************
2 **
3 ** *********************************************************
4 ** *
5 ** * File: PclArc.c
6 ** *
7 ** * Contents:
8 ** * Arc-drawing code for the PCL DDX driver
9 ** *
10 ** * Created: 10/23/95
11 ** *
12 ** *********************************************************
13 **
14 ********************************************************************/
16 (c) Copyright 1996 Hewlett-Packard Company
17 (c) Copyright 1996 International Business Machines Corp.
18 (c) Copyright 1996 Sun Microsystems, Inc.
19 (c) Copyright 1996 Novell, Inc.
20 (c) Copyright 1996 Digital Equipment Corp.
21 (c) Copyright 1996 Fujitsu Limited
22 (c) Copyright 1996 Hitachi, Ltd.
24 Permission is hereby granted, free of charge, to any person obtaining a copy
25 of this software and associated documentation files (the "Software"), to deal
26 in the Software without restriction, including without limitation the rights
27 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28 copies of the Software, and to permit persons to whom the Software is
29 furnished to do so, subject to the following conditions:
31 The above copyright notice and this permission notice shall be included in
32 all copies or substantial portions of the Software.
34 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
38 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 Except as contained in this notice, the names of the copyright holders shall
42 not be used in advertising or otherwise to promote the sale, use or other
43 dealings in this Software without prior written authorization from said
44 copyright holders.
48 #ifdef HAVE_DIX_CONFIG_H
49 #include <dix-config.h>
50 #endif
52 #include <stdio.h>
53 #include <math.h>
54 #include <errno.h>
56 #include "Pcl.h"
57 #include "gcstruct.h"
58 #include "windowstr.h"
59 #include "attributes.h"
61 static void
62 PclDoArc(
63 DrawablePtr pDrawable,
64 GCPtr pGC,
65 int nArcs,
66 xArc *pArcs,
67 void (*DoIt)(FILE *, PclContextPrivPtr, double, double, xArc))
69 char t[80];
70 FILE *outFile;
71 int nbox, i;
72 BoxPtr pbox;
73 BoxRec r;
74 RegionPtr drawRegion, region, transClip;
75 short fudge;
76 int xoffset, yoffset;
77 XpContextPtr pCon;
78 PclContextPrivPtr pConPriv;
79 xRectangle repro;
81 if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE )
82 return;
84 fudge = 3 * pGC->lineWidth;
86 pCon = PclGetContextFromWindow( (WindowPtr) pDrawable );
87 pConPriv = (PclContextPrivPtr)
88 pCon->devPrivates[PclContextPrivateIndex].ptr;
89 XpGetReproductionArea( pCon, &repro );
91 /*
92 * Generate the PCL code to draw the collection of arcs, by
93 * defining it as a macro which uses the HP-GL/2 arc drawing
94 * function.
97 xoffset = pDrawable->x;
98 yoffset = pDrawable->y;
100 for( i = 0; i < nArcs; i++ )
102 xArc Arc = pArcs[i];
103 double b, X, Y, ratio;
104 double angle1;
106 MACRO_START( outFile, pConPriv );
107 SAVE_PCL( outFile, pConPriv, "\033%0B" );
109 /* Calculate the start of the arc */
110 if( ( Arc.angle1 / 64 ) % 360 == 90 )
112 X = 0;
113 Y = -Arc.height / 2.0;
115 else if( ( Arc.angle1 / 64 ) % 360 == 270 )
117 X = 0;
118 Y = Arc.height / 2.0;
120 else
122 /* Convert the angle to radians */
123 angle1 = ( Arc.angle1 / 64.0 ) * 3.141592654 / 180.0;
125 b = (Arc.height / 2.0);
126 X = b * cos( angle1 );
127 Y = -b * sin( angle1 );
130 /* Change the coordinate system to scale the ellipse */
131 ratio = (double)Arc.height / (double)Arc.width;
133 sprintf( t, "SC%.2f,%.2f,%d,%d;",
134 (repro.x - Arc.width / 2 - xoffset - Arc.x) * ratio,
135 (repro.x - Arc.width / 2 - xoffset - Arc.x +
136 repro.width) * ratio,
137 repro.y - Arc.height / 2 - yoffset - Arc.y + repro.height,
138 repro.y - Arc.height / 2 - yoffset - Arc.y);
139 SAVE_PCL( outFile, pConPriv, t );
141 DoIt( outFile, pConPriv, X, Y, Arc );
143 /* Build the bounding box */
144 r.x1 = -Arc.width / 2 - fudge;
145 r.y1 = -Arc.height / 2 - fudge;
146 r.x2 = Arc.width / 2 + fudge;
147 r.y2 = Arc.height / 2 + fudge;
148 drawRegion = REGION_CREATE( pGC->pScreen, &r, 0 );
150 SAVE_PCL( outFile, pConPriv, "\033%0A" );
151 MACRO_END( outFile );
154 * Intersect the bounding box with the clip region.
156 region = REGION_CREATE( pGC->pScreen, NULL, 0 );
157 transClip = REGION_CREATE( pGC->pScreen, NULL, 0 );
158 REGION_COPY( pGC->pScreen, transClip, pGC->pCompositeClip );
159 REGION_TRANSLATE( pGC->pScreen, transClip,
160 -(xoffset + Arc.x + Arc.width / 2),
161 -(yoffset + Arc.y + Arc.height / 2) );
162 REGION_INTERSECT( pGC->pScreen, region, drawRegion, transClip );
165 * For each rectangle in the clip region, set the HP-GL/2 "input
166 * window" and render the collection of arcs to it.
168 pbox = REGION_RECTS( region );
169 nbox = REGION_NUM_RECTS( region );
171 PclSendData(outFile, pConPriv, pbox, nbox, ratio);
174 * Restore the coordinate system
176 sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x,
177 repro.x + repro.width, repro.y + repro.height,
178 repro.y );
179 SEND_PCL( outFile, t );
182 * Clean up the temporary regions
184 REGION_DESTROY( pGC->pScreen, drawRegion );
185 REGION_DESTROY( pGC->pScreen, region );
186 REGION_DESTROY( pGC->pScreen, transClip );
191 * Draw a simple non-filled arc, centered on the origin and starting
192 * at the given point.
194 static void
195 DrawArc(FILE *outFile,
196 PclContextPrivPtr pConPriv,
197 double X,
198 double Y,
199 xArc A)
201 char t[80];
203 sprintf( t, "PU%d,%d;PD;AA0,0,%.2f;", (int)X, (int)Y,
204 (float)A.angle2 / -64.0 );
205 SAVE_PCL(outFile, pConPriv, t);
208 void
209 PclPolyArc(
210 DrawablePtr pDrawable,
211 GCPtr pGC,
212 int nArcs,
213 xArc *pArcs)
215 PclDoArc( pDrawable, pGC, nArcs, pArcs, DrawArc );
219 * Draw a filled wedge, from the origin, to the given point, through
220 * the appropriate angle, and back to the origin.
222 static void
223 DoWedge(FILE *outFile,
224 PclContextPrivPtr pConPriv,
225 double X,
226 double Y,
227 xArc A)
229 char t[80];
231 sprintf( t, "PU0,0;WG%.2f,%.2f,%.2f;", sqrt( X * X + Y * Y ),
232 (float)A.angle1 / -64.0,
233 (float)A.angle2 / -64.0 );
234 SAVE_PCL(outFile, pConPriv, t);
237 static void
238 DoChord(FILE *outFile,
239 PclContextPrivPtr pConPriv,
240 double X,
241 double Y,
242 xArc A)
244 char t[80];
246 sprintf( t, "PU%d,%d;PM0;AA0,0,%.2f;PA%d,%d;PM2;FP;", (int)X, (int)Y,
247 (float)A.angle2 / -64.0 , (int)X, (int)Y );
248 SAVE_PCL(outFile, pConPriv, t);
252 void
253 PclPolyFillArc(
254 DrawablePtr pDrawable,
255 GCPtr pGC,
256 int nArcs,
257 xArc *pArcs)
259 switch( pGC->arcMode )
261 case ArcChord:
262 PclDoArc( pDrawable, pGC, nArcs, pArcs, DoChord );
263 break;
264 case ArcPieSlice:
265 PclDoArc( pDrawable, pGC, nArcs, pArcs, DoWedge );
266 break;