#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 );
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" );
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
{
angle1 = ( Arc.angle1 / 64.0 ) * 3.141592654 / 180.0;
b = (Arc.height / 2.0);
X = b * cos( angle1 );
Y = -b * sin( angle1 );
}
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 );
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 );
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 );
pbox = REGION_RECTS( region );
nbox = REGION_NUM_RECTS( region );
PclSendData(outFile, pConPriv, pbox, nbox, ratio);
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 );
REGION_DESTROY( pGC->pScreen, drawRegion );
REGION_DESTROY( pGC->pScreen, region );
REGION_DESTROY( pGC->pScreen, transClip );
}
}
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 );
}
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;
}
}