diff options
Diffstat (limited to 'hw/xprint/pcl/PclArc.c')
-rw-r--r-- | hw/xprint/pcl/PclArc.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/hw/xprint/pcl/PclArc.c b/hw/xprint/pcl/PclArc.c new file mode 100644 index 000000000..d675e1699 --- /dev/null +++ b/hw/xprint/pcl/PclArc.c @@ -0,0 +1,270 @@ +/* $Xorg: PclArc.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclArc.c +** * +** * Contents: +** * Arc-drawing code for the PCL DDX driver +** * +** * Created: 10/23/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +/* $XFree86: xc/programs/Xserver/Xprint/pcl/PclArc.c,v 1.4 1999/12/13 02:12:53 robin Exp $ */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <stdio.h> +#include <math.h> +#include <errno.h> + +#include "Pcl.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "attributes.h" + +static void +PclDoArc( + DrawablePtr pDrawable, + GCPtr pGC, + int nArcs, + xArc *pArcs, + void (*DoIt)(FILE *, PclContextPrivPtr, double, double, xArc)) +{ + char t[80]; + FILE *outFile; + int nbox, i; + BoxPtr pbox; + BoxRec r; + RegionPtr drawRegion, region, transClip; + short fudge; + int xoffset, yoffset; + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + xRectangle repro; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + fudge = 3 * pGC->lineWidth; + + pCon = PclGetContextFromWindow( (WindowPtr) pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + XpGetReproductionArea( pCon, &repro ); + + /* + * Generate the PCL code to draw the collection of arcs, by + * defining it as a macro which uses the HP-GL/2 arc drawing + * function. + */ + + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + for( i = 0; i < nArcs; i++ ) + { + xArc Arc = pArcs[i]; + double b, X, Y, ratio; + double angle1; + + MACRO_START( outFile, pConPriv ); + SAVE_PCL( outFile, pConPriv, "\033%0B" ); + + /* Calculate the start of the arc */ + if( ( Arc.angle1 / 64 ) % 360 == 90 ) + { + X = 0; + Y = -Arc.height / 2.0; + } + else if( ( Arc.angle1 / 64 ) % 360 == 270 ) + { + X = 0; + Y = Arc.height / 2.0; + } + else + { + /* Convert the angle to radians */ + angle1 = ( Arc.angle1 / 64.0 ) * 3.141592654 / 180.0; + + b = (Arc.height / 2.0); + X = b * cos( angle1 ); + Y = -b * sin( angle1 ); + } + + /* Change the coordinate system to scale the ellipse */ + ratio = (double)Arc.height / (double)Arc.width; + + sprintf( t, "SC%.2f,%.2f,%d,%d;", + (repro.x - Arc.width / 2 - xoffset - Arc.x) * ratio, + (repro.x - Arc.width / 2 - xoffset - Arc.x + + repro.width) * ratio, + repro.y - Arc.height / 2 - yoffset - Arc.y + repro.height, + repro.y - Arc.height / 2 - yoffset - Arc.y); + SAVE_PCL( outFile, pConPriv, t ); + + DoIt( outFile, pConPriv, X, Y, Arc ); + + /* Build the bounding box */ + r.x1 = -Arc.width / 2 - fudge; + r.y1 = -Arc.height / 2 - fudge; + r.x2 = Arc.width / 2 + fudge; + r.y2 = Arc.height / 2 + fudge; + drawRegion = REGION_CREATE( pGC->pScreen, &r, 0 ); + + SAVE_PCL( outFile, pConPriv, "\033%0A" ); + MACRO_END( outFile ); + + /* + * Intersect the bounding box with the clip region. + */ + region = REGION_CREATE( pGC->pScreen, NULL, 0 ); + transClip = REGION_CREATE( pGC->pScreen, NULL, 0 ); + REGION_COPY( pGC->pScreen, transClip, pGC->pCompositeClip ); + REGION_TRANSLATE( pGC->pScreen, transClip, + -(xoffset + Arc.x + Arc.width / 2), + -(yoffset + Arc.y + Arc.height / 2) ); + REGION_INTERSECT( pGC->pScreen, region, drawRegion, transClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the collection of arcs to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, ratio); + + /* + * Restore the coordinate system + */ + sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, + repro.x + repro.width, repro.y + repro.height, + repro.y ); + SEND_PCL( outFile, t ); + + /* + * Clean up the temporary regions + */ + REGION_DESTROY( pGC->pScreen, drawRegion ); + REGION_DESTROY( pGC->pScreen, region ); + REGION_DESTROY( pGC->pScreen, transClip ); + } +} + +/* + * Draw a simple non-filled arc, centered on the origin and starting + * at the given point. + */ +static void +DrawArc(FILE *outFile, + PclContextPrivPtr pConPriv, + double X, + double Y, + xArc A) +{ + char t[80]; + + sprintf( t, "PU%d,%d;PD;AA0,0,%.2f;", (int)X, (int)Y, + (float)A.angle2 / -64.0 ); + SAVE_PCL(outFile, pConPriv, t); +} + +void +PclPolyArc( + DrawablePtr pDrawable, + GCPtr pGC, + int nArcs, + xArc *pArcs) +{ + PclDoArc( pDrawable, pGC, nArcs, pArcs, DrawArc ); +} + +/* + * Draw a filled wedge, from the origin, to the given point, through + * the appropriate angle, and back to the origin. + */ +static void +DoWedge(FILE *outFile, + PclContextPrivPtr pConPriv, + double X, + double Y, + xArc A) +{ + char t[80]; + + sprintf( t, "PU0,0;WG%.2f,%.2f,%.2f;", sqrt( X * X + Y * Y ), + (float)A.angle1 / -64.0, + (float)A.angle2 / -64.0 ); + SAVE_PCL(outFile, pConPriv, t); +} + +static void +DoChord(FILE *outFile, + PclContextPrivPtr pConPriv, + double X, + double Y, + xArc A) +{ + char t[80]; + + sprintf( t, "PU%d,%d;PM0;AA0,0,%.2f;PA%d,%d;PM2;FP;", (int)X, (int)Y, + (float)A.angle2 / -64.0 , (int)X, (int)Y ); + SAVE_PCL(outFile, pConPriv, t); +} + + +void +PclPolyFillArc( + DrawablePtr pDrawable, + GCPtr pGC, + int nArcs, + xArc *pArcs) +{ + switch( pGC->arcMode ) + { + case ArcChord: + PclDoArc( pDrawable, pGC, nArcs, pArcs, DoChord ); + break; + case ArcPieSlice: + PclDoArc( pDrawable, pGC, nArcs, pArcs, DoWedge ); + break; + } +} |