1 /*******************************************************************
3 ** *********************************************************
5 ** * File: PclPolygon.c
8 ** * Draws Polygons and Rectangles for the PCL DDX
10 ** * Created: 10/23/95
12 ** *********************************************************
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
48 #ifdef HAVE_DIX_CONFIG_H
49 #include <dix-config.h>
54 #include "windowstr.h"
58 DrawablePtr pDrawable
,
67 xRectangle
*drawRects
, *r
;
68 RegionPtr drawRegion
, region
;
72 PclContextPrivPtr pConPriv
;
74 if( PclUpdateDrawableGC( pGC
, pDrawable
, &outFile
) == FALSE
)
77 pCon
= PclGetContextFromWindow( (WindowPtr
) pDrawable
);
78 pConPriv
= (PclContextPrivPtr
)
79 pCon
->devPrivates
[PclContextPrivateIndex
].ptr
;
82 * Allocate the storage required to deal with the clipping
85 region
= REGION_CREATE( pGC
->pScreen
, NULL
, 0 );
86 drawRects
= (xRectangle
*)xalloc( nRects
* sizeof( xRectangle
) );
88 fudge
= 3 * pGC
->lineWidth
+ 1;
91 * Generate the PCL code to draw the rectangles, by defining them
92 * as a macro which uses the HP-GL/2 rectangle drawing function.
94 MACRO_START( outFile
, pConPriv
);
95 SAVE_PCL( outFile
, pConPriv
, "\033%0B" );
97 xoffset
= pDrawable
->x
;
98 yoffset
= pDrawable
->y
;
100 for( i
= 0, r
= drawRects
; i
< nRects
; i
++, r
++ )
102 xRectangle rect
= pRects
[i
];
104 /* Draw the rectangle */
105 sprintf( t
, "PU%d,%d;ER%d,%d;", rect
.x
+ xoffset
,
106 rect
.y
+ yoffset
, rect
.width
, rect
.height
);
107 SAVE_PCL( outFile
, pConPriv
, t
);
109 /* Build the bounding box */
110 r
->x
= MIN( rect
.x
, rect
.x
+ rect
.width
) + xoffset
-
112 r
->y
= MIN( rect
.y
, rect
.y
+ rect
.height
) + yoffset
-
114 r
->width
= rect
.width
+ 2 * fudge
;
115 r
->height
= rect
.height
+ 2 * fudge
;
117 SAVE_PCL( outFile
, pConPriv
, ";\033%0A" ); /* End the macro */
118 MACRO_END( outFile
);
121 * Convert the collection of rectangles to a proper region, then
122 * intersect it with the clip region.
124 drawRegion
= RECTS_TO_REGION( pGC
->pScreen
, nRects
,
125 drawRects
, CT_UNSORTED
);
127 REGION_INTERSECT( pGC
->pScreen
, region
, drawRegion
, pGC
->pCompositeClip
);
130 * For each rectangle in the clip region, set the HP-GL/2 "input
131 * window" and render the set of rectangles to it.
133 pbox
= REGION_RECTS( region
);
134 nbox
= REGION_NUM_RECTS( region
);
136 PclSendData(outFile
, pConPriv
, pbox
, nbox
, 1.0);
139 * Clean up the temporary regions
141 REGION_DESTROY( pGC
->pScreen
, drawRegion
);
142 REGION_DESTROY( pGC
->pScreen
, region
);
148 DrawablePtr pDrawable
,
160 RegionPtr drawRegion
, region
;
161 int xoffset
, yoffset
;
162 int xtop
, xbottom
, yleft
, yright
;
165 PclContextPrivPtr pConPriv
;
168 if( PclUpdateDrawableGC( pGC
, pDrawable
, &outFile
) == FALSE
)
171 pCon
= PclGetContextFromWindow( (WindowPtr
) pDrawable
);
172 pConPriv
= (PclContextPrivPtr
)
173 pCon
->devPrivates
[PclContextPrivateIndex
].ptr
;
176 * Generate the PCL code to draw the filled polygon, by defining
177 * it as a macro which uses the HP-GL/2 polygon drawing function.
179 MACRO_START( outFile
, pConPriv
);
180 SAVE_PCL( outFile
, pConPriv
, "\033%0B" );
182 if( mode
== CoordModeOrigin
)
184 xoffset
= pDrawable
->x
;
185 yoffset
= pDrawable
->y
;
190 xoffset
= yoffset
= 0;
194 /* Begin the polygon */
195 sprintf( t
, "PU%d,%d;PM0;%s", pPoints
[0].x
+ xoffset
, pPoints
[0].y
196 + yoffset
, command
);
197 SAVE_PCL( outFile
, pConPriv
, t
);
199 /* Seed the bounding box */
200 xtop
= xbottom
= pPoints
[0].x
+ xoffset
;
201 yleft
= yright
= pPoints
[0].y
+ yoffset
;
203 /* Add the rest of the points to the polygon */
204 for( i
= 1; i
< nPoints
; i
++ )
207 SAVE_PCL( outFile
, pConPriv
, "," );
209 sprintf( t
, "%d,%d", pPoints
[i
].x
+ xoffset
, pPoints
[i
].y
+
211 SAVE_PCL( outFile
, pConPriv
, t
);
213 /* Update the bounding box */
214 xtop
= MIN( xtop
, pPoints
[i
].x
+ xoffset
);
215 xbottom
= MAX( xbottom
, pPoints
[i
].x
+ xoffset
);
216 yleft
= MIN( yleft
, pPoints
[i
].y
+ yoffset
);
217 yright
= MAX( yright
, pPoints
[i
].y
+ yoffset
);
220 /* Close the polygon and the macro */
222 if( pGC
->fillRule
== EvenOddRule
)
227 sprintf( t
, ";PM2;FP%d;\033%%0A", fillRule
);
228 SAVE_PCL( outFile
, pConPriv
, t
);
229 MACRO_END ( outFile
);
232 * Build the bounding region from the bounding box of the polygon
238 drawRegion
= REGION_CREATE( pGC
->pScreen
, &box
, 0 );
240 if( mode
== CoordModePrevious
)
241 REGION_TRANSLATE( pGC
->pScreen
, drawRegion
, pPoints
[0].x
, pPoints
[0].y
);
243 region
= REGION_CREATE( pGC
->pScreen
, NULL
, 0 );
245 REGION_INTERSECT( pGC
->pScreen
, region
, drawRegion
, pGC
->pCompositeClip
);
248 * For each rectangle in the clip region, set the HP-GL/2 "input
249 * window" and render the polygon to it.
251 pbox
= REGION_RECTS( region
);
252 nbox
= REGION_NUM_RECTS( region
);
254 PclSendData(outFile
, pConPriv
, pbox
, nbox
, 1.0);
257 * Clean up the temporary regions
259 REGION_DESTROY( pGC
->pScreen
, drawRegion
);
260 REGION_DESTROY( pGC
->pScreen
, region
);
265 DrawablePtr pDrawable
,
274 xRectangle
*drawRects
, *r
;
275 RegionPtr drawRegion
, region
;
276 int xoffset
, yoffset
;
279 PclContextPrivPtr pConPriv
;
281 if( PclUpdateDrawableGC( pGC
, pDrawable
, &outFile
) == FALSE
)
284 pCon
= PclGetContextFromWindow( (WindowPtr
) pDrawable
);
285 pConPriv
= (PclContextPrivPtr
)
286 pCon
->devPrivates
[PclContextPrivateIndex
].ptr
;
289 * Allocate the storage required to deal with the clipping
292 region
= REGION_CREATE( pGC
->pScreen
, NULL
, 0 );
293 drawRects
= (xRectangle
*)xalloc( nRects
* sizeof( xRectangle
) );
296 fudge
= 3 * pGC
->lineWidth
+ 1;
299 * Generate the PCL code to draw the filled rectangles, by
300 * defining them as a macro which uses the HP-GL/2 rectangle
303 MACRO_START( outFile
, pConPriv
);
304 SAVE_PCL( outFile
, pConPriv
, "\033%0B" );
306 xoffset
= pDrawable
->x
;
307 yoffset
= pDrawable
->y
;
309 for( i
= 0, r
= drawRects
; i
< nRects
; i
++, r
++ )
311 xRectangle rect
= pRects
[i
];
313 /* Draw the rectangle */
314 sprintf( t
, "PU%d,%d;RR%d,%d;", rect
.x
+ xoffset
, rect
.y
+
315 yoffset
, rect
.width
, rect
.height
);
316 SAVE_PCL( outFile
, pConPriv
, t
);
318 /* Build the bounding box */
319 r
->x
= MIN( rect
.x
, rect
.x
+ rect
.width
) + xoffset
- fudge
;
320 r
->y
= MIN( rect
.y
, rect
.y
+ rect
.height
) + yoffset
-
322 r
->width
= rect
.width
+ 2 * fudge
;
323 r
->height
= rect
.height
+ 2 * fudge
;
325 SAVE_PCL( outFile
, pConPriv
, ";\033%0A" ); /* End the macro */
326 MACRO_END( outFile
);
329 * Convert the collection of rectangles to a proper region, then
330 * intersect it with the clip region.
332 drawRegion
= RECTS_TO_REGION( pGC
->pScreen
, nRects
,
333 drawRects
, CT_UNSORTED
);
334 REGION_INTERSECT( pGC
->pScreen
, region
, drawRegion
, pGC
->pCompositeClip
);
337 * For each rectangle in the clip region, set the HP-GL/2 "input
338 * window" and render the set of rectangles to it.
340 pbox
= REGION_RECTS( region
);
341 nbox
= REGION_NUM_RECTS( region
);
343 PclSendData(outFile
, pConPriv
, pbox
, nbox
, 1.0);
346 * Clean up the temporary regions
348 REGION_DESTROY( pGC
->pScreen
, drawRegion
);
349 REGION_DESTROY( pGC
->pScreen
, region
);