cmc3@BELLCORE.BELLCORE.COM (c.m.chase) (01/06/89)
Here is the CPP output from miarc.c on the X server.
$ gcc -O bug.c
will result in cc1 dying with "fatal signal 6"
vital stats
hardware: Sun4/110 (sparc)
OS: Sun OS 4.0
Gcc version: 1.32
If there's any other information I can provide that would be useful,
please let me know.
Craig Chase
cmc3@nvuxr.bellcore.bcr.com
P.S. please respond to let me know that this message arrived intact. It
is somewhat longish (~75Kbytes)
---------------------------------------------------------------------------
# 1 "miarc.c"
# 1 "/usr/local/pkg/X11/src/X11/X.h"
typedef unsigned long XID;
typedef XID Window;
typedef XID Drawable;
typedef XID Font;
typedef XID Pixmap;
typedef XID Cursor;
typedef XID Colormap;
typedef XID GContext;
typedef XID KeySym;
typedef unsigned long Mask;
typedef unsigned long Atom;
typedef unsigned long VisualID;
typedef unsigned long Time;
typedef unsigned char KeyCode;
# 311 "/usr/local/pkg/X11/src/X11/X.h"
# 27 "miarc.c"
# 1 "/usr/local/pkg/X11/src/X11/Xprotostr.h"
# 1 "/usr/local/pkg/X11/src/X11/Xmd.h"
typedef long INT32;
typedef short INT16;
typedef char INT8;
typedef unsigned long CARD32;
typedef unsigned short CARD16;
typedef unsigned char CARD8;
typedef unsigned long BITS32;
typedef unsigned short BITS16;
typedef unsigned char BYTE;
typedef unsigned char BOOL;
# 28 "/usr/local/pkg/X11/src/X11/Xprotostr.h"
typedef struct _xSegment {
INT16 x1 , y1 , x2 , y2 ;
} xSegment;
typedef struct _xPoint {
INT16 x , y ;
} xPoint;
typedef struct _xRectangle {
INT16 x , y ;
CARD16 width , height ;
} xRectangle;
typedef struct _xArc {
INT16 x , y ;
CARD16 width , height ;
INT16 angle1 , angle2 ;
} xArc;
# 28 "miarc.c"
# 1 "../../include/misc.h"
extern unsigned long globalSerialNumber;
typedef unsigned char *pointer;
typedef int Bool;
typedef unsigned long PIXEL;
typedef unsigned long ATOM;
# 1 "../../include/os.h"
# 1 "../../include/misc.h"
# 117 "../../include/misc.h"
# 29 "../../include/os.h"
# 1 "/usr/include/alloca.h"
# 32 "../../include/os.h"
typedef pointer FID;
typedef struct _FontPathRec *FontPathPtr;
typedef struct _NewClientRec *NewClientPtr;
# 69 "../../include/os.h"
char *__builtin_alloca();
# 92 "../../include/os.h"
char *ReadRequestFromClient();
char *strcat();
char *strncat();
char *strcpy();
char *strncpy();
Bool CloseDownConnection();
FontPathPtr GetFontPath();
FontPathPtr ExpandFontNamePattern();
FID FiOpenForRead();
void CreateWellKnownSockets();
void SetDefaultFontPath();
void FreeFontRecord();
void SetFontPath();
void ErrorF();
void Error();
void FatalError();
void ProcessCommandLine();
void Xfree();
void FlushAllOutput();
void FlushIfCriticalOutputPending();
unsigned long *Xalloc();
unsigned long *Xrealloc();
long GetTimeInMillis();
# 58 "../../include/misc.h"
typedef struct _DDXPoint *DDXPointPtr;
typedef struct _Box *BoxPtr;
# 29 "miarc.c"
# 1 "../../include/gcstruct.h"
# 1 "../../include/gc.h"
typedef struct _GCInterest *GCInterestPtr;
typedef struct _GC *GCPtr;
extern void ValidateGC();
extern int ChangeGC();
extern GCPtr CreateGC();
extern int CopyGC();
extern int FreeGC();
extern void SetGCMask();
extern GCPtr GetScratchGC();
extern void FreeScratchGC();
# 29 "../../include/gcstruct.h"
# 1 "../../include/miscstruct.h"
# 1 "../../include/misc.h"
# 117 "../../include/misc.h"
# 28 "../../include/miscstruct.h"
extern unsigned long globalSerialNumber;
typedef struct _DDXPoint {
short x, y;
} DDXPointRec;
typedef struct _Box {
short x1, y1, x2, y2;
} BoxRec;
# 31 "../../include/gcstruct.h"
# 1 "../../include/region.h"
typedef struct _Region *RegionPtr;
extern int SingleRectRegionEqual();
# 32 "../../include/gcstruct.h"
# 1 "../../include/pixmap.h"
typedef struct _DrawInfo *DrawablePtr;
typedef struct _Pixmap *PixmapPtr;
# 33 "../../include/gcstruct.h"
# 1 "../../include/screenint.h"
typedef struct _PixmapFormat *PixmapFormatPtr;
typedef struct _Visual *VisualPtr;
typedef struct _Depth *DepthPtr;
typedef struct _Screen *ScreenPtr;
# 34 "../../include/gcstruct.h"
# 1 "../../include/dixfont.h"
typedef struct _DIXFontProp *DIXFontPropPtr;
typedef struct _Font *FontPtr;
typedef enum {Linear8Bit, TwoD8Bit, Linear16Bit, TwoD16Bit} FontEncoding;
typedef struct _FontData *FontDataPtr;
extern FontPtr OpenFont();
# 35 "../../include/gcstruct.h"
typedef struct _GCInterest {
struct _GCInterest *pNextGCInterest;
struct _GCInterest *pLastGCInterest;
int length;
ATOM owner;
unsigned long ValInterestMask;
void (* ValidateGC) ();
unsigned long ChangeInterestMask;
int (* ChangeGC) ();
void (* CopyGCSource) ();
void (* CopyGCDest) ();
void (* DestroyGC) ();
pointer extPriv;
} GCInterestRec;
typedef struct _GC{
ScreenPtr pScreen;
pointer devPriv;
pointer devBackingStore;
int depth;
unsigned long serialNumber;
GCInterestPtr pNextGCInterest;
GCInterestPtr pLastGCInterest;
int alu;
unsigned long planemask;
unsigned long fgPixel, bgPixel;
int lineWidth;
int lineStyle;
int capStyle;
int joinStyle;
int fillStyle;
int fillRule;
int arcMode;
PixmapPtr tile;
PixmapPtr stipple;
DDXPointRec patOrg;
FontPtr font;
int subWindowMode;
Bool graphicsExposures;
DDXPointRec clipOrg;
pointer clientClip;
int clientClipType;
int dashOffset;
int numInDashList;
unsigned char *dash;
unsigned long stateChanges;
DDXPointRec lastWinOrg;
int miTranslate:1;
void (* FillSpans)();
void (* SetSpans)();
void (* PutImage)();
RegionPtr (* CopyArea)();
RegionPtr (* CopyPlane)();
void (* PolyPoint)();
void (* Polylines)();
void (* PolySegment)();
void (* PolyRectangle)();
void (* PolyArc)();
void (* FillPolygon)();
void (* PolyFillRect)();
void (* PolyFillArc)();
int (* PolyText8)();
int (* PolyText16)();
void (* ImageText8)();
void (* ImageText16)();
void (* ImageGlyphBlt)();
void (* PolyGlyphBlt)();
void (* PushPixels)();
void (* LineHelper)();
void (* ChangeClip) ();
void (* DestroyClip) ();
void (* CopyClip)();
} GC;
# 30 "miarc.c"
# 1 "../../include/scrnintstr.h"
# 1 "../../include/screenint.h"
# 33 "../../include/screenint.h"
# 28 "../../include/scrnintstr.h"
# 1 "../../include/misc.h"
# 117 "../../include/misc.h"
# 29 "../../include/scrnintstr.h"
# 1 "../../include/region.h"
# 41 "../../include/region.h"
# 30 "../../include/scrnintstr.h"
# 1 "../../include/pixmap.h"
# 45 "../../include/pixmap.h"
# 31 "../../include/scrnintstr.h"
# 1 "../../include/gc.h"
# 65 "../../include/gc.h"
# 32 "../../include/scrnintstr.h"
# 1 "../../include/colormap.h"
# 55 "../../include/colormap.h"
typedef unsigned long Pixel;
typedef struct _CMEntry *EntryPtr;
typedef struct _ColormapRec *ColormapPtr;
extern int CreateColormap();
extern Pixel FindColor();
extern int FreeColormap();
extern int TellNoMap();
extern int TellLostMap();
extern int TellGainedMap();
extern int IsMapInstalled();
extern void UninstallColormap();
# 33 "../../include/scrnintstr.h"
typedef struct _PixmapFormat {
unsigned char depth;
unsigned char bitsPerPixel;
unsigned char scanlinePad;
} PixmapFormatRec;
typedef struct _Visual {
unsigned long vid;
short screen;
short class;
unsigned long redMask, greenMask, blueMask;
int offsetRed, offsetGreen, offsetBlue;
short bitsPerRGBValue;
short ColormapEntries;
short nplanes;
} VisualRec;
typedef struct _Depth {
int depth;
int numVids;
unsigned long *vids;
} DepthRec;
typedef struct _Screen {
int myNum;
ATOM id;
short width, height;
short mmWidth, mmHeight;
short numDepths;
DepthPtr allowedDepths;
short rootDepth;
unsigned long rootVisual;
unsigned long defColormap;
short minInstalledCmaps, maxInstalledCmaps;
char backingStoreSupport, saveUnderSupport;
unsigned long whitePixel, blackPixel;
unsigned long rgf;
GCPtr GCperDepth[8+1];
PixmapPtr PixmapPerDepth[1];
pointer devPrivate;
short numVisuals;
VisualPtr visuals;
Bool (* CloseScreen)();
void (* QueryBestSize)();
Bool (* SaveScreen)();
void (* GetImage)();
unsigned int *(* GetSpans)();
void (* PointerNonInterestBox)();
Bool (* CreateWindow)();
Bool (* DestroyWindow)();
Bool (* PositionWindow)();
Bool (* ChangeWindowAttributes)();
Bool (* RealizeWindow)();
Bool (* UnrealizeWindow)();
int (* ValidateTree)();
void (* WindowExposures)();
PixmapPtr (* CreatePixmap)();
Bool (* DestroyPixmap)();
Bool (* RealizeFont)();
Bool (* UnrealizeFont)();
void (* ConstrainCursor)();
void (* CursorLimits)();
Bool (* DisplayCursor)();
Bool (* RealizeCursor)();
Bool (* UnrealizeCursor)();
void (* RecolorCursor)();
Bool (* SetCursorPosition)();
Bool (* CreateGC)();
void (* CreateColormap)();
void (* DestroyColormap)();
void (* InstallColormap)();
void (* UninstallColormap)();
int (* ListInstalledColormaps) ();
void (* StoreColors)();
void (* ResolveColor)();
RegionPtr (* RegionCreate)();
void (* RegionCopy)();
void (* RegionDestroy)();
int (* Intersect)();
int (* Union)();
int (* Subtract)();
int (* Inverse)();
void (* RegionReset)();
void (* TranslateRegion)();
int (* RectIn)();
Bool (* PointInRegion)();
Bool (* RegionNotEmpty)();
void (* RegionEmpty)();
BoxPtr (*RegionExtents)();
void (* SendGraphicsExpose)();
void (* BlockHandler)();
void (* WakeupHandler)();
pointer blockData;
pointer wakeupData;
} ScreenRec;
typedef struct _ScreenInfo {
int imageByteOrder;
int bitmapScanlineUnit;
int bitmapScanlinePad;
int bitmapBitOrder;
int numPixmapFormats;
PixmapFormatRec
formats[8];
int arraySize;
int numScreens;
ScreenPtr screen;
} ScreenInfo;
extern ScreenInfo screenInfo;
# 31 "miarc.c"
# 1 "../../include/pixmapstr.h"
# 1 "../../include/pixmap.h"
# 45 "../../include/pixmap.h"
# 28 "../../include/pixmapstr.h"
# 1 "../../include/screenint.h"
# 33 "../../include/screenint.h"
# 29 "../../include/pixmapstr.h"
# 1 "../../include/misc.h"
# 117 "../../include/misc.h"
# 30 "../../include/pixmapstr.h"
typedef struct _DrawInfo {
short type;
ScreenPtr pScreen;
int depth;
unsigned long serialNumber;
} DrawableRec;
typedef struct _Pixmap {
DrawableRec drawable;
int width, height;
int refcnt;
int devKind;
pointer devPrivate;
} PixmapRec;
# 32 "miarc.c"
# 1 "../../include/windowstr.h"
# 1 "../../include/window.h"
typedef struct _BackingStore *BackingStorePtr;
typedef struct _Window *WindowPtr;
# 29 "../../include/windowstr.h"
# 1 "../../include/pixmapstr.h"
# 50 "../../include/pixmapstr.h"
# 30 "../../include/windowstr.h"
# 1 "../../include/region.h"
# 41 "../../include/region.h"
# 31 "../../include/windowstr.h"
# 1 "../../include/cursor.h"
typedef struct _Cursor *CursorPtr;
typedef struct _CursorMetric *CursorMetricPtr;
extern CursorPtr rootCursor;
# 32 "../../include/windowstr.h"
# 1 "../../include/property.h"
typedef struct _Property *PropertyPtr;
# 33 "../../include/windowstr.h"
# 1 "../../include/resource.h"
# 1 "../../include/misc.h"
# 117 "../../include/misc.h"
# 27 "../../include/resource.h"
unsigned short CreateNewResourceType();
short CreateNewResourceClass();
unsigned long FakeClientID();
void AddResource();
void FreeResource();
void FreeClientResources();
pointer LookupID();
# 34 "../../include/windowstr.h"
# 1 "../../include/dix.h"
# 1 "../../include/gc.h"
# 65 "../../include/gc.h"
# 29 "../../include/dix.h"
# 1 "../../include/window.h"
# 53 "../../include/window.h"
# 30 "../../include/dix.h"
typedef struct _TimeStamp *TimeStampPtr;
typedef struct _Client *ClientPtr;
extern ClientPtr requestingClient;
extern ClientPtr *clients;
extern ClientPtr serverClient;
extern int currentMaxClients;
extern int ProcAllowEvents();
extern int ProcBell();
extern int ProcChangeActivePointerGrab();
extern int ProcChangeKeyboardControl();
extern int ProcChangePointerControl();
extern int ProcGetKeyboardMapping();
extern int ProcGetPointerMapping();
extern int ProcGetInputFocus();
extern int ProcGetKeyboardControl();
extern int ProcGetMotionEvents();
extern int ProcGetPointerControl();
extern int ProcGrabButton();
extern int ProcGrabKey();
extern int ProcGrabKeyboard();
extern int ProcGrabPointer();
extern int ProcQueryKeymap();
extern int ProcQueryPointer();
extern int ProcSetInputFocus();
extern int ProcSetKeyboardMapping();
extern int ProcSetPointerMapping();
extern int ProcSendEvent();
extern int ProcUngrabButton();
extern int ProcUngrabKey();
extern int ProcUngrabKeyboard();
extern int ProcUngrabPointer();
extern int ProcWarpPointer();
extern int ProcRecolorCursor();
extern WindowPtr LookupWindow();
extern pointer LookupDrawable();
extern void NoopDDA();
# 35 "../../include/windowstr.h"
# 1 "../../include/miscstruct.h"
# 38 "../../include/miscstruct.h"
# 36 "../../include/windowstr.h"
# 1 "/usr/local/pkg/X11/src/X11/Xprotostr.h"
# 55 "/usr/local/pkg/X11/src/X11/Xprotostr.h"
# 37 "../../include/windowstr.h"
typedef struct _BackingStore {
RegionPtr obscured;
DDXPointRec oldAbsCorner;
void (* SaveDoomedAreas)();
RegionPtr (* RestoreAreas)();
void (* ExposeCopy)();
void (* TranslateBackingStore)();
void (* ClearToBackground)();
void (* DrawGuarantee)();
} BackingStoreRec;
typedef struct _Window {
DrawableRec drawable;
VisualID visual;
struct _Window *parent;
struct _Window *nextSib;
struct _Window *prevSib;
struct _Window *firstChild;
struct _Window *lastChild;
CursorPtr cursor;
ClientPtr client;
Window wid;
RegionPtr clipList;
RegionPtr winSize;
RegionPtr borderClip;
RegionPtr borderSize;
RegionPtr exposed;
RegionPtr borderExposed;
xRectangle clientWinSize;
DDXPointRec absCorner;
DDXPointRec oldAbsCorner;
int class;
Mask eventMask;
Mask dontPropagateMask;
Mask allEventMasks;
Mask deliverableEvents;
pointer otherClients;
pointer passiveGrabs;
PropertyPtr userProps;
XID nolongerused;
PixmapPtr backgroundTile;
unsigned long backgroundPixel;
PixmapPtr borderTile;
unsigned long borderPixel;
int borderWidth;
void (* PaintWindowBackground)();
void (* PaintWindowBorder)();
void (* CopyWindow)();
void (* ClearToBackground)();
unsigned long backingBitPlanes;
unsigned long backingPixel;
int backingStore;
BackingStorePtr backStorage;
char bitGravity;
char winGravity;
Colormap colormap;
Bool saveUnder:1;
unsigned visibility:2;
unsigned mapped:1;
unsigned realized:1;
unsigned viewable:1;
unsigned overrideRedirect:1;
unsigned marked:1;
pointer devBackingStore;
pointer devPrivate;
} WindowRec;
extern int DeleteWindow();
extern int ChangeWindowAttributes();
extern int WalkTree();
extern CreateRootWindow();
extern WindowPtr CreateWindow();
extern int DeleteWindow();
extern int DestroySubwindows();
extern int ChangeWindowAttributes();
extern int GetWindowAttributes();
extern int ConfigureWindow();
extern int ReparentWindow();
extern int MapWindow();
extern int MapSubwindow();
extern int UnmapWindow();
extern int UnmapSubwindow();
extern RegionPtr NotClippedByChildren();
# 33 "miarc.c"
# 1 "mifpoly.h"
typedef struct _SppPoint {
double x, y;
} SppPointRec, *SppPointPtr;
typedef struct _SppArc {
double x, y, width, height;
double angle1, angle2;
} SppArcRec, *SppArcPtr;
extern SppPointRec miExtendSegment();
# 34 "miarc.c"
# 1 "../../include/mi.h"
# 1 "../../include/region.h"
# 41 "../../include/region.h"
# 27 "../../include/mi.h"
typedef struct _miDash *miDashPtr;
extern void miPutImage();
extern void miGetImage();
extern RegionPtr miCopyArea();
extern RegionPtr miCopyPlane();
extern void miClearToBackground();
extern int miValidateTree();
extern void miPolySegment();
extern void miPolyRectangle();
extern void miFillPolygon();
extern int miPolyText8();
extern int miPolyText16();
extern void miImageText8();
extern void miImageText16();
extern int miFillConvexPoly();
extern int miFillGeneralPoly();
extern void miNotMiter();
extern void miMiter();
extern void miWideLine();
extern void miWideDash();
extern void miPolyArc();
extern void miPolyFillRect();
extern void miPolyFillArc();
extern void miPolyGlyphBlt();
extern void miImageGlyphBlt();
extern void miZeroLine();
extern void miPaintWindow();
extern miDashPtr miDashLine();
extern void miPushPixels();
extern void miGetPts(), miRoundCap(), miOneSegWide();
extern int miPtToAngle();
extern RegionPtr miRegionCreate();
extern void miRegionCopy();
extern void miRegionDestroy();
extern int miIntersect();
extern int miInverse();
extern int miUnion();
extern int miSubtract();
extern void miRegionReset();
extern void miTranslateRegion();
extern int miRectIn();
extern RegionPtr miRectsToRegion();
extern Bool miPointInRegion();
extern Bool miRegionNotEmpty();
extern void miRegionEmpty();
extern int miNumberRectsInRegion();
extern void miWindowExposures();
extern BoxPtr miRegionExtents();
extern void miSendGraphicsExpose();
extern RegionPtr miHandleExposures();
# 35 "miarc.c"
extern double sqrt(), cos(), sin(), atan();
typedef struct _miArcJoin {
int arcIndex0, arcIndex1;
int phase0, phase1;
int end0, end1;
} miArcJoinRec, *miArcJoinPtr;
typedef struct _miArcCap {
int arcIndex;
int end;
} miArcCapRec, *miArcCapPtr;
typedef struct _miArcFace {
SppPointRec clock;
SppPointRec center;
SppPointRec counterClock;
} miArcFaceRec, *miArcFacePtr;
typedef struct _miArcData {
xArc arc;
int render;
int join;
int cap;
int selfJoin;
miArcFaceRec bounds[2];
double x0, y0, x1, y1;
} miArcDataRec, *miArcDataPtr;
typedef struct _miPolyArc {
int narcs;
miArcDataPtr arcs;
int ncaps;
miArcCapPtr caps;
int njoins;
miArcJoinPtr joins;
} miPolyArcRec, *miPolyArcPtr;
static miPolyArcPtr miComputeArcs ();
static CARD32 gcvals[6];
static void
miArcSegment(pDraw, pGC, tarc, right, left)
DrawablePtr pDraw;
GCPtr pGC;
xArc tarc;
miArcFacePtr right, left;
{
int l = pGC->lineWidth;
int w, h;
int a0, a1, startAngle, endAngle;
int st, ct;
miArcFacePtr temp;
if (tarc.width == 0 || tarc.height == 0) {
drawZeroArc (pDraw, pGC, tarc, left, right);
return;
}
if (pGC->miTranslate && (pDraw->type == 0)) {
tarc.x += ((WindowPtr) pDraw)->absCorner.x;
tarc.y += ((WindowPtr) pDraw)->absCorner.y;
}
if (l < 1)
l = 1;
a0 = tarc.angle1;
a1 = tarc.angle2;
if (a1 > (64 * 360))
a1 = (64 * 360);
else if (a1 < -(64 * 360))
a1 = -(64 * 360);
if (a1 < 0) {
startAngle = a0 + a1;
endAngle = a0;
temp = right;
right = left;
left = temp;
} else {
startAngle = a0;
endAngle = a0 + a1;
}
if (startAngle < 0)
startAngle = (64 * 360) - (-startAngle) % (64 * 360);
if (startAngle >= (64 * 360))
startAngle = startAngle % (64 * 360);
if (endAngle < 0)
endAngle = (64 * 360) - (-endAngle) % (64 * 360);
if (endAngle > (64 * 360))
endAngle = (endAngle-1) % (64 * 360) + 1;
if (startAngle == endAngle) {
startAngle = 0;
endAngle = (64 * 360);
}
drawArc ((int) tarc.x, (int) tarc.y,
(int) tarc.width, (int) tarc.height, l, startAngle, endAngle,
right, left);
}
void
miPolyArc(pDraw, pGC, narcs, parcs)
DrawablePtr pDraw;
GCPtr pGC;
int narcs;
xArc *parcs;
{
register int i;
int xMin, xMax, yMin, yMax;
int dx, dy;
int xOrg, yOrg;
double helperDx, helperDy;
int ifirst, count, width;
Bool fTricky;
DrawablePtr pDrawTo;
unsigned long fg, bg;
GCPtr pGCTo;
miPolyArcPtr polyArcs;
int cap[2], join[2];
int iphase;
width = pGC->lineWidth;
if(width == 0 && pGC->lineStyle == 0)
{
for(i = 0; i < narcs; i++)
miArcSegment( pDraw, pGC, parcs[i],
(miArcFacePtr) 0, (miArcFacePtr) 0 );
fillSpans (pDraw, pGC);
}
else
{
switch(pGC->alu)
{
case 0x0 :
case 0x3 :
case 0xc :
case 0xf :
fTricky = 0;
pDrawTo = pDraw;
pGCTo = pGC;
break;
default:
fTricky = 1;
xMin = yMin = 32767;
xMax = yMax = -32767 ;
for(i = 0; i < narcs; i++)
{
xMin = (((xMin) < ( parcs[i].x)) ? (xMin) : ( parcs[i].x));
yMin = (((yMin) < ( parcs[i].y)) ? (yMin) : ( parcs[i].y));
xMax = (((xMax) > ( (parcs[i].x + (int) parcs[i].width))) ? (xMax) : ( (parcs[i].x + (int) parcs[i].width)));
yMax = (((yMax) > ( (parcs[i].y + (int) parcs[i].height))) ? (yMax) : ( (parcs[i].y + (int) parcs[i].height)));
}
pGCTo = GetScratchGC(1, pDraw->pScreen);
gcvals[ 0] = 0x3 ;
gcvals[ 1] = 1;
gcvals[ 2] = 0;
gcvals[ 3] = pGC->lineWidth;
gcvals[ 4] = pGC->capStyle;
gcvals[ 5] = pGC->joinStyle;
DoChangeGC(pGCTo, ( (1L<<0) | (1L<<2) | (1L<<3) | (1L<<4) | (1L<<6) | (1L<<7)), gcvals, 0);
xOrg = xMin - (width + 1)/2;
yOrg = yMin - (width + 1)/2;
dx = (xMax - xMin) + width + 1;
dy = (yMax - yMin) + width + 1;
for(i = 0; i < narcs; i++)
{
parcs[i].x -= xOrg;
parcs[i].y -= yOrg;
}
if (pGC->miTranslate && (pDraw->type == 0))
{
xOrg += (double) ((WindowPtr)pDraw)->absCorner.x;
yOrg += (double) ((WindowPtr)pDraw)->absCorner.y;
}
pDrawTo = (DrawablePtr)(*pDraw->pScreen->CreatePixmap)
(pDraw->pScreen, dx, dy, 1, 0 );
ValidateGC(pDrawTo, pGCTo);
miClearDrawable(pDrawTo, pGCTo);
}
fg = pGCTo->fgPixel;
bg = pGCTo->bgPixel;
polyArcs = miComputeArcs (parcs, narcs,
!(pGC->lineStyle == 0),
pGC->lineStyle == 2,
pGC->dash, pGC->numInDashList, pGC->dashOffset);
if (!polyArcs)
{
if (fTricky) {
(*pDraw->pScreen->DestroyPixmap) (pDrawTo);
FreeScratchGC (pGCTo);
}
return;
}
cap[0] = cap[1] = 0;
join[0] = join[1] = 0;
for (iphase = ((pGC->lineStyle == 2) ? 1 : 0);
iphase >= 0;
iphase--)
{
if (iphase == 1) {
gcvals[0] = bg;
gcvals[1] = fg;
DoChangeGC (pGC, (1L<<2)| (1L<<3), gcvals, 0);
ValidateGC (pDraw, pGC);
} else if (pGC->lineStyle == 2) {
gcvals[0] = fg;
gcvals[1] = bg;
DoChangeGC (pGC, (1L<<2)| (1L<<3), gcvals, 0);
ValidateGC (pDraw, pGC);
}
for (i = 0; i < polyArcs[iphase].narcs; i++) {
miArcDataPtr arcData;
int j;
arcData = &polyArcs[iphase].arcs[i];
miArcSegment(pDrawTo, pGCTo, arcData->arc,
&arcData->bounds[0],
&arcData->bounds[1]);
if (polyArcs[iphase].arcs[i].render) {
fillSpans (pDrawTo, pGCTo);
if (polyArcs[iphase].arcs[i].selfJoin &&
cap[iphase] < polyArcs[iphase].arcs[i].cap)
cap[iphase]++;
while (cap[iphase] < polyArcs[iphase].arcs[i].cap) {
int arcIndex, end;
miArcDataPtr arcData0;
arcIndex = polyArcs[iphase].caps[cap[iphase]].arcIndex;
end = polyArcs[iphase].caps[cap[iphase]].end;
arcData0 = &polyArcs[iphase].arcs[arcIndex];
miArcCap (pDrawTo, pGCTo,
&arcData0->bounds[end], end,
arcData0->arc.x, arcData0->arc.y,
(double) arcData0->arc.width / 2.0,
(double) arcData0->arc.height / 2.0);
++cap[iphase];
}
while (join[iphase] < polyArcs[iphase].arcs[i].join) {
int arcIndex0, arcIndex1, end0, end1;
int phase0, phase1;
miArcDataPtr arcData0, arcData1;
miArcJoinPtr joinp;
joinp = &polyArcs[iphase].joins[join[iphase]];
arcIndex0 = joinp->arcIndex0;
end0 = joinp->end0;
arcIndex1 = joinp->arcIndex1;
end1 = joinp->end1;
phase0 = joinp->phase0;
phase1 = joinp->phase1;
arcData0 = &polyArcs[phase0].arcs[arcIndex0];
arcData1 = &polyArcs[phase1].arcs[arcIndex1];
miArcJoin (pDrawTo, pGCTo,
&arcData0->bounds[end0],
&arcData1->bounds[end1],
arcData0->arc.x, arcData0->arc.y,
(double) arcData0->arc.width / 2.0,
(double) arcData0->arc.height / 2.0,
arcData1->arc.x, arcData1->arc.y,
(double) arcData1->arc.width / 2.0,
(double) arcData1->arc.height / 2.0);
++join[iphase];
}
if (fTricky) {
(*pGC->PushPixels) (pGC, pDrawTo, pDraw, dx,
dy, xOrg, yOrg);
miClearDrawable ((DrawablePtr) pDrawTo, pGCTo);
}
}
}
}
for (iphase = ((pGC->lineStyle == 2) ? 1 : 0);
iphase >= 0;
iphase--)
{
if (polyArcs[iphase].narcs > 0)
Xfree((pointer) polyArcs[iphase].arcs);
if (polyArcs[iphase].njoins > 0)
Xfree ((pointer) polyArcs[iphase].joins);
if (polyArcs[iphase].ncaps > 0)
Xfree ((pointer) polyArcs[iphase].caps);
}
Xfree((pointer) polyArcs);
if(fTricky)
{
(*pGCTo->pScreen->DestroyPixmap)((PixmapPtr)pDrawTo);
FreeScratchGC(pGCTo);
}
}
}
static double
angleBetween (center, point1, point2)
SppPointRec center, point1, point2;
{
double atan2 (), a1, a2, a;
a1 = atan2 (- (point1.y - center.y), point1.x - center.x);
a2 = atan2 (- (point2.y - center.y), point2.x - center.x);
a = a2 - a1;
if (a < -3.14159265358979323846)
a += 2 * 3.14159265358979323846;
else if (a > 3.14159265358979323846)
a -= 2 * 3.14159265358979323846;
return a;
}
static
translateBounds (b, x, y, fx, fy)
miArcFacePtr b;
int x, y;
double fx, fy;
{
b->clock.x -= x + fx;
b->clock.y -= y + fy;
b->center.x -= x + fx;
b->center.y -= y + fy;
b->counterClock.x -= x + fx;
b->counterClock.y -= y + fy;
}
miArcJoin (pDraw, pGC, pLeft, pRight,
xOrgLeft, yOrgLeft, xFtransLeft, yFtransLeft,
xOrgRight, yOrgRight, xFtransRight, yFtransRight)
DrawablePtr *pDraw;
GCPtr pGC;
miArcFacePtr pRight, pLeft;
int xOrgRight, yOrgRight;
double xFtransRight, yFtransRight;
int xOrgLeft, yOrgLeft;
double xFtransLeft, yFtransLeft;
{
SppPointRec center, corner, otherCorner, end;
SppPointRec poly[5], e;
SppPointPtr pArcPts;
int cpt;
SppArcRec arc;
miArcFaceRec Right, Left;
int polyLen;
int xOrg, yOrg;
double xFtrans, yFtrans;
double angle[4];
double a;
double ae, ac2, ec2, bc2, de;
double width;
xOrg = (xOrgRight + xOrgLeft) / 2;
yOrg = (yOrgRight + yOrgLeft) / 2;
xFtrans = (xFtransLeft + xFtransRight) / 2;
yFtrans = (yFtransLeft + yFtransRight) / 2;
Right = *pRight;
translateBounds (&Right, xOrg - xOrgRight, yOrg - yOrgRight,
xFtrans - xFtransRight, yFtrans - yFtransRight);
Left = *pLeft;
translateBounds (&Left, xOrg - xOrgLeft, yOrg - yOrgLeft,
xFtrans - xFtransLeft, yFtrans - yFtransLeft);
pRight = &Right;
pLeft = &Left;
if (pRight->clock.x == pLeft->counterClock.x &&
pRight->clock.y == pLeft->counterClock.y)
return;
center = pRight->center;
if (0 <= (a = angleBetween (center, pRight->clock, pLeft->counterClock))
&& a <= 3.14159265358979323846)
{
corner = pRight->clock;
otherCorner = pLeft->counterClock;
} else {
a = angleBetween (center, pLeft->clock, pRight->counterClock);
corner = pLeft->clock;
otherCorner = pRight->counterClock;
}
switch (pGC->joinStyle) {
case 1:
width = (pGC->lineWidth ? pGC->lineWidth : 1);
arc.x = center.x - width/2;
arc.y = center.y - width/2;
arc.width = width;
arc.height = width;
arc.angle1 = -atan2 (corner.y - center.y, corner.x - center.x);
arc.angle2 = a;
pArcPts = (SppPointPtr) Xalloc (sizeof (SppPointRec));
pArcPts->x = center.x;
pArcPts->y = center.y;
if( cpt = miGetArcPts(&arc, 1, &pArcPts))
{
miFillSppPoly(pDraw, pGC, cpt, pArcPts, xOrg, yOrg, xFtrans, yFtrans);
Xfree((pointer)pArcPts);
}
return;
case 0:
if (a < 169 * 3.14159265358979323846 / 180.0) {
poly[0] = corner;
poly[1] = center;
poly[2] = otherCorner;
bc2 = (corner.x - otherCorner.x) * (corner.x - otherCorner.x) +
(corner.y - otherCorner.y) * (corner.y - otherCorner.y);
ec2 = bc2 / 4;
ac2 = (corner.x - center.x) * (corner.x - center.x) +
(corner.y - center.y) * (corner.y - center.y);
ae = sqrt (ac2 - ec2);
de = ec2 / ae;
e.x = (corner.x + otherCorner.x) / 2;
e.y = (corner.y + otherCorner.y) / 2;
poly[3].x = e.x + de * (e.x - center.x) / ae;
poly[3].y = e.y + de * (e.y - center.y) / ae;
poly[4] = corner;
polyLen = 5;
break;
}
case 2:
poly[0] = corner;
poly[1] = center;
poly[2] = otherCorner;
poly[3] = corner;
polyLen = 4;
break;
}
miFillSppPoly (pDraw, pGC, polyLen, poly, xOrg, yOrg, xFtrans, yFtrans);
}
miArcCap (pDraw, pGC, pFace, end, xOrg, yOrg, xFtrans, yFtrans)
DrawablePtr *pDraw;
GCPtr pGC;
miArcFacePtr pFace;
int end;
int xOrg, yOrg;
double xFtrans, yFtrans;
{
SppPointRec corner, otherCorner, center, endPoint, poly[5];
corner = pFace->clock;
otherCorner = pFace->counterClock;
center = pFace->center;
switch (pGC->capStyle) {
case 3:
poly[0].x = otherCorner.x;
poly[0].y = otherCorner.y;
poly[1].x = corner.x;
poly[1].y = corner.y;
poly[2].x = corner.x -
(center.y - corner.y);
poly[2].y = corner.y +
(center.x - corner.x);
poly[3].x = otherCorner.x -
(otherCorner.y - center.y);
poly[3].y = otherCorner.y +
(otherCorner.x - center.x);
poly[4].x = otherCorner.x;
poly[4].y = otherCorner.y;
miFillSppPoly (pDraw, pGC, 5, poly, xOrg, yOrg, xFtrans, yFtrans);
break;
case 2:
endPoint = center;
endPoint.x = endPoint.x + 100;
miRoundCap (pDraw, pGC, center, endPoint, corner, otherCorner, 0,
-xOrg, -yOrg, xFtrans, yFtrans);
break;
}
}
void
miPolyFillArc(pDraw, pGC, narcs, parcs)
DrawablePtr pDraw;
GCPtr pGC;
int narcs;
xArc *parcs;
{
int i, cpt;
SppPointPtr pPts;
SppArcRec sppArc;
int angle1, angle2;
for(i = 0; i < narcs; i++)
{
angle1 = parcs[i].angle1;
if (angle1 >= (64 * 360))
angle1 = angle1 % (64 * 360);
else if (angle1 <= -(64 * 360))
angle1 = - (-angle1 % (64 * 360));
angle2 = parcs[i].angle2;
if (angle2 > (64 * 360))
angle2 = (64 * 360);
else if (angle2 < -(64 * 360))
angle2 = -(64 * 360);
sppArc.x = parcs[i].x;
sppArc.y = parcs[i].y;
sppArc.width = parcs[i].width;
sppArc.height = parcs[i].height;
sppArc.angle1 = (((double) (angle1)) / 64.0 * 3.14159265358979323846/180.0);
sppArc.angle2 = (((double) (angle2)) / 64.0 * 3.14159265358979323846/180.0);
if(pGC->arcMode == 1 && parcs[i].angle2 < (64 * 360))
{
if (!(pPts = (SppPointPtr)Xalloc(sizeof(SppPointRec))))
return;
if(cpt = miGetArcPts(&sppArc, 1, &pPts))
{
pPts[0].x = sppArc.x + sppArc.width/2;
pPts[0].y = sppArc.y + sppArc.height /2;
miFillSppPoly(pDraw, pGC, cpt + 1, pPts, 0, 0, 0.0, 0.0);
Xfree((pointer) pPts);
}
}
else
{
pPts = (SppPointPtr) 0;
if(cpt = miGetArcPts(&sppArc, 0, &pPts))
{
miFillSppPoly(pDraw, pGC, cpt, pPts, 0, 0, 0.0, 0.0);
Xfree((pointer) pPts);
}
}
}
}
int
miGetArcPts(parc, cpt, ppPts)
SppArcPtr parc;
int cpt;
SppPointPtr *ppPts;
{
double st,
et,
dt,
cdt,
x0, y0,
x1, y1,
x2, y2,
xc, yc,
xt, yt;
int count, i, axis, npts = 2;
double asin(), fmax (), sin(), cos ();
SppPointPtr poly;
DDXPointRec last;
st = - parc->angle1;
et = - parc->angle2;
cdt = fmax(parc->width, parc->height)/2.0;
if(cdt < 1.0)
return 0;
dt = asin( 1.0 / cdt );
count = et/dt;
count = ((count) > 0 ? (count) : -(count)) + 1;
dt = et/count;
count++;
cdt = 2 * cos(dt);
if (!(poly = (SppPointPtr) Xrealloc((pointer)*ppPts,
(cpt + 2) * sizeof(SppPointRec))))
return(0);
xc = parc->width/2.0;
yc = parc->height/2.0;
axis = (xc >= yc) ? 0 : 1;
x0 = xc * cos(st);
y0 = yc * sin(st);
x1 = xc * cos(st + dt);
y1 = yc * sin(st + dt);
xc += parc->x;
yc += parc->y;
poly[cpt].x = (xc + x0);
poly[cpt].y = (yc + y0);
last.x = ((int) ((( poly[cpt + 1].x = (xc + x1) ) > 0.0) ? (( poly[cpt + 1].x = (xc + x1) ) + 0.5) : (( poly[cpt + 1].x = (xc + x1) ) - 0.5)));
last.y = ((int) ((( poly[cpt + 1].y = (yc + y1) ) > 0.0) ? (( poly[cpt + 1].y = (yc + y1) ) + 0.5) : (( poly[cpt + 1].y = (yc + y1) ) - 0.5)));
for(i = 2; i < count; i++)
{
x2 = cdt * x1 - x0;
y2 = cdt * y1 - y0;
xt = xc + x2;
yt = yc + y2;
if (((axis == 0) ?
( ((int) (((yt) > 0.0) ? ((yt) + 0.5) : ((yt) - 0.5))) != last.y) :
( ((int) (((xt) > 0.0) ? ((xt) + 0.5) : ((xt) - 0.5))) != last.x)) ||
i > count - 3)
{
if ((npts - 2) % 10 == 0)
{
if (!(poly = (SppPointPtr)
Xrealloc((pointer) poly,
((npts + 10 + cpt) *
sizeof(SppPointRec)))))
return(0);
}
if (((poly[cpt + npts - 2].y - poly[cpt + npts - 1].y > 0.0) ?
(yt - poly[cpt + npts - 1].y > 0.0) :
(poly[cpt + npts - 1].y - yt > 0.0)) ||
((poly[cpt + npts - 2].x - poly[cpt + npts - 1].x > 0.0) ?
(xt - poly[cpt + npts - 1].x > 0.0) :
(poly[cpt + npts - 1].x - xt > 0.0)))
{
poly[cpt + npts].x = xc + x1;
poly[cpt + npts].y = yc + y1;
npts++;
if ((npts - 2) % 10 == 0)
{
if (!(poly = (SppPointPtr)
Xrealloc((pointer) poly,
((npts + 10 + cpt) *
sizeof(SppPointRec)))))
return(0);
}
}
last.x = ((int) ((( poly[cpt + npts].x = xt ) > 0.0) ? (( poly[cpt + npts].x = xt ) + 0.5) : (( poly[cpt + npts].x = xt ) - 0.5)));
last.y = ((int) ((( poly[cpt + npts].y = yt ) > 0.0) ? (( poly[cpt + npts].y = yt ) + 0.5) : (( poly[cpt + npts].y = yt ) - 0.5)));
npts++;
}
x0 = x1; y0 = y1;
x1 = x2; y1 = y2;
}
count = i = npts;
if (((parc->angle2) > 0 ? (parc->angle2) : -(parc->angle2)) >= (64 * 360))
poly[cpt +i -1] = poly[0];
else {
poly[cpt +i -1].x = (cos(st + et) * parc->width/2.0 + xc);
poly[cpt +i -1].y = (sin(st + et) * parc->height/2.0 + yc);
}
*ppPts = poly;
return(count);
}
struct arcData {
double x0, y0, x1, y1;
int selfJoin;
};
addCap (capsp, ncapsp, sizep, end, arcIndex)
miArcCapPtr *capsp;
int *ncapsp, *sizep;
int end, arcIndex;
{
miArcCapPtr cap;
if (*ncapsp == *sizep)
*capsp = (miArcCapPtr) Xrealloc (*capsp,
(*sizep += 20) * sizeof (**capsp));
cap = &(*capsp)[*ncapsp];
cap->end = end;
cap->arcIndex = arcIndex;
++*ncapsp;
}
addJoin (joinsp, njoinsp, sizep, end0, index0, phase0, end1, index1, phase1)
miArcJoinPtr *joinsp;
int *njoinsp, *sizep;
int end0, index0, end1, index1;
{
miArcJoinPtr join;
if (*njoinsp == *sizep)
*joinsp = (miArcJoinPtr) Xrealloc (*joinsp,
(*sizep += 20) * sizeof (**joinsp));
join = &(*joinsp)[*njoinsp];
join->end0 = end0;
join->arcIndex0 = index0;
join->phase0 = phase0;
join->end1 = end1;
join->arcIndex1 = index1;
join->phase1 = phase1;
++*njoinsp;
}
miArcDataPtr
addArc (arcsp, narcsp, sizep, xarc)
miArcDataPtr *arcsp;
int *narcsp, *sizep;
xArc xarc;
{
miArcDataPtr arc;
if (*narcsp == *sizep)
*arcsp = (miArcDataPtr) Xrealloc (*arcsp,
(*sizep += 20) * sizeof (**arcsp));
arc = &(*arcsp)[*narcsp];
arc->arc = xarc;
++*narcsp;
return arc;
}
static miPolyArcPtr
miComputeArcs (parcs, narcs, isDashed, isDoubleDash, pDash, nDashes, dashOffset)
xArc *parcs;
int narcs;
int isDashed, isDoubleDash;
unsigned char *pDash;
int nDashes, dashOffset;
{
miPolyArcPtr arcs;
int start, i, j, k, nexti, nextk;
int joinSize[2];
int capSize[2];
int arcSize[2];
int angle2;
double x0, y0, x1, y1, a0, a1, xc, yc;
struct arcData *data;
miArcDataPtr arc;
xArc xarc;
int iphase, prevphase, joinphase;
int arcsJoin;
int selfJoin;
int iDash, dashRemaining;
int iDashStart, dashRemainingStart, iphaseStart;
int startAngle, spanAngle, endAngle, backwards;
int prevDashAngle, dashAngle;
static int computeAngleFromPath ();
arcs = (miPolyArcPtr) Xalloc (sizeof (*arcs) * (isDoubleDash ? 2 : 1));
data = (struct arcData *) __builtin_alloca((int)(narcs * sizeof (struct arcData)));
for (i = 0; i < narcs; i++) {
a0 = (((double) (parcs[i].angle1)) / 64.0 * 3.14159265358979323846/180.0);
angle2 = parcs[i].angle2;
if (angle2 > (64 * 360))
angle2 = (64 * 360);
else if (angle2 < -(64 * 360))
angle2 = -(64 * 360);
data[i].selfJoin = angle2 == (64 * 360) || angle2 == -(64 * 360);
a1 = (((double) (parcs[i].angle1 + angle2)) / 64.0 * 3.14159265358979323846/180.0);
data[i].x0 = parcs[i].x + (double) parcs[i].width / 2 * (1 + cos (a0));
data[i].y0 = parcs[i].y + (double) parcs[i].height / 2 * (1 - sin (a0));
data[i].x1 = parcs[i].x + (double) parcs[i].width / 2 * (1 + cos (a1));
data[i].y1 = parcs[i].y + (double) parcs[i].height / 2 * (1 - sin (a1));
}
for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) {
arcs[iphase].njoins = 0;
arcs[iphase].joins = 0;
joinSize[iphase] = 0;
arcs[iphase].ncaps = 0;
arcs[iphase].caps = 0;
capSize[iphase] = 0;
arcs[iphase].narcs = 0;
arcs[iphase].arcs = 0;
arcSize[iphase] = 0;
}
iphase = 0;
if (isDashed) {
iDash = 0;
dashRemaining = pDash[0];
while (dashOffset > 0) {
if (dashOffset >= dashRemaining) {
dashOffset -= dashRemaining;
iphase = iphase ? 0 : 1;
iDash++;
dashRemaining = pDash[iDash];
} else {
dashRemaining -= dashOffset;
dashOffset = 0;
}
}
iDashStart = iDash;
dashRemainingStart = dashRemaining;
}
iphaseStart = iphase;
for (i = narcs - 1; i >= 0; i--) {
j = i + 1;
if (j == narcs)
j = 0;
if (data[i].selfJoin ||
(((((data[i].x1) - ( data[j].x0)) > 0.0 ? ((data[i].x1) - ( data[j].x0)) : -((data[i].x1) - ( data[j].x0))) > 0.000001) ||
((((data[i].y1) - ( data[j].y0)) > 0.0 ? ((data[i].y1) - ( data[j].y0)) : -((data[i].y1) - ( data[j].y0))) > 0.000001)))
{
if (iphase == 0 || isDoubleDash)
addCap (&arcs[iphase].caps, &arcs[iphase].ncaps,
&capSize[iphase], 0, 0);
break;
}
}
start = i + 1;
if (start == narcs)
start = 0;
i = start;
for (;;) {
j = i + 1;
if (j == narcs)
j = 0;
nexti = i+1;
if (nexti == narcs)
nexti = 0;
if (isDashed) {
startAngle = parcs[i].angle1;
spanAngle = parcs[i].angle2;
if (spanAngle > (64 * 360))
spanAngle = (64 * 360);
else if (spanAngle < -(64 * 360))
spanAngle = -(64 * 360);
if (startAngle < 0)
startAngle = (64 * 360) - (-startAngle) % (64 * 360);
if (startAngle >= (64 * 360))
startAngle = startAngle % (64 * 360);
endAngle = startAngle + spanAngle;
backwards = spanAngle < 0;
prevDashAngle = startAngle;
selfJoin = data[i].selfJoin &&
(iphase == 0 || isDoubleDash);
while (prevDashAngle != endAngle) {
dashAngle = computeAngleFromPath
(prevDashAngle, endAngle,
parcs[i].width, parcs[i].height,
&dashRemaining, backwards);
if (iphase == 0 || isDoubleDash) {
xarc = parcs[i];
xarc.angle1 = prevDashAngle;
if (backwards) {
spanAngle = dashAngle - prevDashAngle;
if (dashAngle > prevDashAngle)
spanAngle = - 360 * 64 + spanAngle;
} else {
spanAngle = dashAngle - prevDashAngle;
if (dashAngle < prevDashAngle)
spanAngle = 360 * 64 + spanAngle;
}
xarc.angle2 = spanAngle;
arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs,
&arcSize[iphase], xarc);
if (!isDoubleDash) {
if (prevDashAngle != startAngle) {
addCap (&arcs[iphase].caps,
&arcs[iphase].ncaps,
&capSize[iphase], 0,
arc - arcs[iphase].arcs);
}
if (dashAngle != endAngle) {
addCap (&arcs[iphase].caps,
&arcs[iphase].ncaps,
&capSize[iphase], 1,
arc - arcs[iphase].arcs);
}
}
arc->cap = arcs[iphase].ncaps;
arc->join = arcs[iphase].njoins;
arc->render = 0;
arc->selfJoin = 0;
if (dashAngle == endAngle)
arc->selfJoin = selfJoin;
}
prevphase = iphase;
if (dashRemaining <= 0) {
++iDash;
if (iDash == nDashes)
iDash = 0;
iphase = iphase ? 0:1;
dashRemaining = pDash[iDash];
}
prevDashAngle = dashAngle;
}
} else {
arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs,
&arcSize[iphase], parcs[i]);
arc->join = arcs[iphase].njoins;
arc->cap = arcs[iphase].ncaps;
arc->selfJoin = data[i].selfJoin;
prevphase = iphase;
}
if (prevphase == 0 || isDoubleDash)
k = arcs[prevphase].narcs - 1;
if (iphase == 0 || isDoubleDash)
nextk = arcs[iphase].narcs;
if (nexti == start) {
nextk = 0;
if (isDashed) {
iDash = iDashStart;
iphase = iphaseStart;
dashRemaining = dashRemainingStart;
}
}
arcsJoin = narcs > 1 &&
((((data[i].x1) - ( data[j].x0)) > 0.0 ? ((data[i].x1) - ( data[j].x0)) : -((data[i].x1) - ( data[j].x0))) <= 0.000001) &&
((((data[i].y1) - ( data[j].y0)) > 0.0 ? ((data[i].y1) - ( data[j].y0)) : -((data[i].y1) - ( data[j].y0))) <= 0.000001) &&
!data[i].selfJoin && !data[j].selfJoin;
if (arcsJoin)
arc->render = 0;
else
arc->render = 1;
if (arcsJoin &&
(prevphase == 0 || isDoubleDash) &&
(iphase == 0 || isDoubleDash))
{
joinphase = iphase;
if (isDoubleDash) {
if (nexti == start)
joinphase = iphaseStart;
if (joinphase != prevphase)
joinphase = 0;
}
if (joinphase == 0 || isDoubleDash) {
addJoin (&arcs[joinphase].joins,
&arcs[joinphase].njoins,
&joinSize[joinphase],
1, k, prevphase,
0, nextk, iphase);
arc->join = arcs[prevphase].njoins;
}
} else {
if ((prevphase == 0 || isDoubleDash) &&
!arc->selfJoin)
{
addCap (&arcs[prevphase].caps, &arcs[prevphase].ncaps,
&capSize[prevphase], 1, k);
arc->cap = arcs[prevphase].ncaps;
}
if (isDashed && !arcsJoin) {
iDash = iDashStart;
iphase = iphaseStart;
dashRemaining = dashRemainingStart;
}
nextk = arcs[iphase].narcs;
if (nexti == start) {
nextk = 0;
iDash = iDashStart;
iphase = iphaseStart;
dashRemaining = dashRemainingStart;
}
if ((iphase == 0 || isDoubleDash) &&
(nexti != start || arcsJoin && isDashed))
addCap (&arcs[iphase].caps, &arcs[iphase].ncaps,
&capSize[iphase], 0, nextk);
}
i = nexti;
if (i == start)
break;
}
for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++)
if (arcs[iphase].narcs > 0) {
arcs[iphase].arcs[arcs[iphase].narcs-1].render = 1;
arcs[iphase].arcs[arcs[iphase].narcs-1].join =
arcs[iphase].njoins;
arcs[iphase].arcs[arcs[iphase].narcs-1].cap =
arcs[iphase].ncaps;
}
return arcs;
}
static int
computeAngleFromPath (startAngle, endAngle, w, h, lenp, backwards)
int startAngle, endAngle;
int *lenp;
int backwards;
{
double len;
double t0, t1, t, l, x0, y0, x1, y1, sidelen;
int a, startq, endq, q;
int a0, a1;
double atan2 (), floor (), acos (), asin ();
a0 = startAngle;
a1 = endAngle;
len = *lenp;
if (backwards) {
a0 = (64 * 360) - a0;
a1 = (64 * 360) - a1;
}
if (a1 < a0)
a1 += (64 * 360);
startq = floor ((double) a0 / (90.0 * 64.0));
endq = floor ((double) a1 / (90.0 * 64.0));
a = a0;
a0 = a0 - startq * 90 *64;
a1 = a1 - endq * 90 * 64;
for (q = startq; q <= endq && len > 0; ++q) {
if (q == startq && a0 != 0) {
t0 = (((double) (a0 + startq * 90 * 64)) / 64.0 * 3.14159265358979323846/180.0);
x0 = (double) w / 2 * cos (t0);
y0 = (double) h / 2* sin (t0);
} else {
x0 = 0;
y0 = 0;
switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4))) {
case 0: x0 = (double) w/2; break;
case 2: x0 = - (double) w/2; break;
case 1: y0 = (double) h/2; break;
case 3: y0 = -(double) h/2; break;
}
}
if (q == endq) {
if (a1 == 0) {
x1 = 0;
y1 = 0;
switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4))) {
case 0: x1 = (double) w/2; break;
case 2: x1 = - (double) w/2; break;
case 1: y1 = (double) h/2; break;
case 3: y1 = -(double) h/2; break;
}
} else {
t1 = (((double) (a1 + endq * 90 * 64)) / 64.0 * 3.14159265358979323846/180.0);
x1 = (double) w / 2 * cos(t1);
y1 = (double) h / 2 * sin(t1);
}
} else {
x1 = 0;
y1 = 0;
switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4))) {
case 0: y1 = (double) h/2; break;
case 2: y1 = - (double) h/2; break;
case 1: x1 = -(double) w/2; break;
case 3: x1 = (double) w/2; break;
}
}
sidelen = sqrt ((x1-x0)*(x1-x0) + (y1-y0) * (y1-y0));
if (sidelen >= len) {
x1 = 0;
y1 = 0;
switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4))) {
case 0: y1 = (double) h/2; break;
case 2: y1 = -(double) h/2; break;
case 1: x1 = -(double) w/2; break;
case 3: x1 = (double) w/2; break;
}
sidelen = sqrt ((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0));
y1 = y0 + (y1 - y0) * len / sidelen;
x1 = x0 + (x1 - x0) * len / sidelen;
if (x1 == (double) w/2 && y1 == 0)
a1 = 0;
else if (x1 == -(double) w/2 && y1 == 0)
a1 = 180 * 64;
else if (y1 == (double) h/2 && x1 == 0)
a1 = 90 * 64;
else if (y1 == -(double) h/2 && x1 == 0)
a1 = 270 * 64;
else {
if (w == 0) {
t1 = asin (y1 / ((double) h/2));
switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4))) {
case 1:
case 2:
t1 = 3.14159265358979323846 - t1;
}
} else if (h == 0) {
t1 = acos (x1 / ((double) w/2));
switch (((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4))) {
case 2:
case 3:
t1 = 2 * 3.14159265358979323846 - t1;
}
} else {
t1 = atan2 (y1 * w, x1 * h);
}
a1 = (t1 * 180/3.14159265358979323846) * 64.0;
if (a1 < 0)
a1 += (64 * 360);
}
a1 -= ((q) >= 0 ? (q) % ( 4) : ( 4) - (-q) % ( 4)) * 90 * 64;
len = 0;
} else
len -= sidelen;
}
*lenp = len;
a1 = a1 + (q-1) * (90*64);
if (backwards)
a1 = (64 * 360) - a1;
return a1;
}
double
FullDcos (a)
double a;
{
double cos ();
int i;
if (floor (a/90) == a/90) {
i = (int) (a/90.0);
switch (((i) >= 0 ? (i) % ( 4) : ( 4) - (-i) % ( 4))) {
case 0: return 1;
case 1: return 0;
case 2: return -1;
case 3: return 0;
}
}
return cos (a * 3.14159265358979323846 / 180.0);
}
double
FullDsin (a)
double a;
{
double sin ();
int i;
if (floor (a/90) == a/90) {
i = (int) (a/90.0);
switch (((i) >= 0 ? (i) % ( 4) : ( 4) - (-i) % ( 4))) {
case 0: return 0;
case 1: return 1;
case 2: return 0;
case 3: return -1;
}
}
return sin (a * 3.14159265358979323846 / 180.0);
}
extern double ceil (), floor (), fabs (), sin (), cos (), sqrt (), pow ();
drawZeroArc (pDraw, pGC, tarc, left, right)
DrawablePtr pDraw;
GCPtr pGC;
xArc tarc;
miArcFacePtr right, left;
{
double x0, y0, x1, y1, w, h;
int a0, a1;
double startAngle, endAngle;
double l;
l = pGC->lineWidth;
if (l == 0)
l = 1;
l /= 2;
a0 = tarc.angle1;
a1 = tarc.angle2;
if (a1 > (64 * 360))
a1 = (64 * 360);
else if (a1 < -(64 * 360))
a1 = -(64 * 360);
w = tarc.width / 2.0;
h = tarc.height / 2.0;
startAngle = - ((double) a0 / 64.0);
endAngle = - ((double) (a0 + a1) / 64.0);
x0 = w * FullDcos(startAngle);
y0 = h * FullDsin(startAngle);
x1 = w * FullDcos(endAngle);
y1 = h * FullDsin(endAngle);
if (y0 != y1) {
if (y0 < y1) {
x0 = -l;
x1 = l;
} else {
x0 = l;
x1 = -l;
}
} else {
if (x0 < x1) {
y0 = -l;
y1 = l;
} else {
y0 = l;
y1 = -l;
}
}
if (x1 != x0 && y1 != y0) {
int minx, maxx, miny, maxy, y, t;
xRectangle rect;
minx = ceil (x0 + w) + tarc.x;
maxx = ceil (x1 + w) + tarc.x;
if (minx > maxx) {
t = minx;
minx = maxx;
maxx = t;
}
miny = ceil (y0 + h) + tarc.y;
maxy = ceil (y1 + h) + tarc.y;
if (miny > maxy) {
t = miny;
miny = maxy;
maxy = t;
}
rect.x = minx;
rect.y = miny;
rect.width = maxx - minx;
rect.height = maxy - miny;
(*pGC->PolyFillRect) (pDraw, pGC, 1, &rect);
}
if (right) {
if (h != 0) {
right->clock.x = x1;
right->clock.y = y0;
right->center.x = 0;
right->center.y = y0;
right->counterClock.x = x0;
right->counterClock.y = y0;
} else {
right->clock.x = x0;
right->clock.y = y0;
right->center.x = x0;
right->center.y = 0;
right->counterClock.x = x0;
right->counterClock.y = y1;
}
}
if (left) {
if (h != 0) {
left->clock.x = x0;
left->clock.y = y1;
left->center.x = 0;
left->center.y = y1;
left->counterClock.x = x1;
left->counterClock.y = y1;
} else {
left->clock.x = x1;
left->clock.y = y1;
left->center.x = x1;
left->center.y = 0;
left->counterClock.x = x1;
left->counterClock.y = y0;
}
}
}
struct bound {
double min, max;
};
struct line {
double m, b;
int valid;
};
struct arc_bound {
struct bound elipse;
struct bound inner;
struct bound outer;
struct bound right;
struct bound left;
};
struct accelerators {
double tail_y;
double h2;
double w2;
double h4;
double w4;
double h2mw2;
double wh2mw2;
double wh4;
struct line left, right;
};
struct arc_def {
double w, h, l;
double a0, a1;
};
double
Sqrt (x)
double x;
{
if (x < 0) {
if (x > -(0.0000001))
return 0;
else
abort ();
}
return sqrt (x);
}
double
fmax (a, b)
double a,b;
{
return a > b? a : b;
}
double
fmin (a, b)
double a, b;
{
return a < b ? a : b;
}
double
tailElipseY (w, h, l)
double w, h, l;
{
extern double Sqrt (), pow ();
double t;
if (w != h) {
t = (pow (h * l * w, 2.0/3.0) - 1.5874010519681993173435330390930175781250 * h*h) /
(w*w - h*h);
if (t < 0)
return 0;
return h / 1.2599210498948732038115849718451499938964 * Sqrt (t);
} else
return 0;
}
double
outerXfromXY (x, y, def, acc)
double x, y;
struct arc_def *def;
struct accelerators *acc;
{
return x + (x * acc->h2 * def->l) /
(2 * Sqrt (x*x *acc->h4 + y*y * acc->w4));
}
double
outerXfromY (y, def, acc)
double y;
struct arc_def *def;
struct accelerators *acc;
{
double x;
x = def->w * Sqrt ((acc->h2 - (y*y)) / acc->h2);
return x + (x * acc->h2 * def->l) /
(2 * Sqrt (x*x *acc->h4 + y*y * acc->w4));
}
double
outerYfromXY (x, y, def, acc)
double x, y;
struct arc_def *def;
struct accelerators *acc;
{
return y + (y * acc->w2 * def->l) /
(2 * Sqrt (x*x * acc->h4 + y*y * acc->w4));
}
double
outerYfromY (y, def, acc)
double y;
struct arc_def *def;
struct accelerators *acc;
{
double x;
x = def->w * Sqrt ((acc->h2 - (y*y)) / acc->h2);
return y + (y * acc->w2 * def->l) /
(2 * Sqrt (x*x * acc->h4 + y*y * acc->w4));
}
double
innerXfromXY (x, y, def, acc)
double x, y;
struct arc_def *def;
struct accelerators *acc;
{
return x - (x * acc->h2 * def->l) /
(2 * Sqrt (x*x * acc->h4 + y*y * acc->w4));
}
double
innerXfromY (y, def, acc)
double y;
struct arc_def *def;
struct accelerators *acc;
{
double x;
x = def->w * Sqrt ((acc->h2 - (y*y)) / acc->h2);
return x - (x * acc->h2 * def->l) /
(2 * Sqrt (x*x * acc->h4 + y*y * acc->w4));
}
double
innerYfromXY (x, y, def, acc)
double x, y;
struct arc_def *def;
struct accelerators *acc;
{
return y - (y * acc->w2 * def->l) /
(2 * Sqrt (x*x * acc->h4 + y*y * acc->w4));
}
double
innerYfromY (y, def, acc)
double y;
struct arc_def *def;
struct accelerators *acc;
{
double x;
x = def->w * Sqrt ((acc->h2 - (y*y)) / acc->h2);
return y - (y * acc->w2 * def->l) /
(2 * Sqrt (x*x * acc->h4 + y*y * acc->w4));
}
computeLine (x1, y1, x2, y2, line)
double x1, y1, x2, y2;
struct line *line;
{
if (y1 == y2)
line->valid = 0;
else {
line->m = (x1 - x2) / (y1 - y2);
line->b = x1 - y1 * line->m;
line->valid = 1;
}
}
double
intersectLine (y, line)
double y;
struct line *line;
{
return line->m * y + line->b;
}
computeAcc (def, acc)
struct arc_def *def;
struct accelerators *acc;
{
acc->h2 = def->h * def->h;
acc->w2 = def->w * def->w;
acc->h4 = acc->h2 * acc->h2;
acc->w4 = acc->w2 * acc->w2;
acc->h2mw2 = acc->h2 - acc->w2;
acc->wh2mw2 = def->w * acc->h2mw2;
acc->wh4 = def->w * acc->h4;
acc->tail_y = tailElipseY (def->w, def->h, def->l);
}
computeBound (def, bound, acc, right, left)
struct arc_def *def;
struct arc_bound *bound;
struct accelerators *acc;
miArcFacePtr right, left;
{
double t, elipseX ();
double innerTaily;
double tail_y;
struct bound innerx, outerx;
struct bound elipsex;
bound->elipse.min = ((def->a0) == 0.0 ? 0.0 : ((def->a0) == 90.0 ? 1.0 : sin(def->a0*3.14159265358979323846/180.0))) * def->h;
bound->elipse.max = ((def->a1) == 0.0 ? 0.0 : ((def->a1) == 90.0 ? 1.0 : sin(def->a1*3.14159265358979323846/180.0))) * def->h;
if (def->a0 == 45 && def->w == def->h)
elipsex.min = bound->elipse.min;
else
elipsex.min = ((def->a0) == 0.0 ? 1.0 : ((def->a0) == 90.0 ? 0.0 : cos(def->a0*3.14159265358979323846/180.0))) * def->w;
if (def->a1 == 45 && def->w == def->h)
elipsex.max = bound->elipse.max;
else
elipsex.max = ((def->a1) == 0.0 ? 1.0 : ((def->a1) == 90.0 ? 0.0 : cos(def->a1*3.14159265358979323846/180.0))) * def->w;
bound->outer.min = outerYfromXY (elipsex.min, bound->elipse.min, def, acc);
bound->outer.max = outerYfromXY (elipsex.max, bound->elipse.max, def, acc);
bound->inner.min = innerYfromXY (elipsex.min, bound->elipse.min, def, acc);
bound->inner.max = innerYfromXY (elipsex.max, bound->elipse.max, def, acc);
outerx.min = outerXfromXY (elipsex.min, bound->elipse.min, def, acc);
outerx.max = outerXfromXY (elipsex.max, bound->elipse.max, def, acc);
innerx.min = innerXfromXY (elipsex.min, bound->elipse.min, def, acc);
innerx.max = innerXfromXY (elipsex.max, bound->elipse.max, def, acc);
if (right) {
right->counterClock.y = bound->outer.min;
right->counterClock.x = outerx.min;
right->center.y = bound->elipse.min;
right->center.x = elipsex.min;
right->clock.y = bound->inner.min;
right->clock.x = innerx.min;
}
if (left) {
left->clock.y = bound->outer.max;
left->clock.x = outerx.max;
left->center.y = bound->elipse.max;
left->center.x = elipsex.max;
left->counterClock.y = bound->inner.max;
left->counterClock.x = innerx.max;
}
bound->left.min = bound->inner.max;
bound->left.max = bound->outer.max;
bound->right.min = bound->inner.min;
bound->right.max = bound->outer.min;
computeLine (innerx.min, bound->inner.min, outerx.min, bound->outer.min,
&acc->right);
computeLine (innerx.max, bound->inner.max, outerx.max, bound->outer.max,
&acc->left);
if (bound->inner.min > bound->inner.max) {
t = bound->inner.min;
bound->inner.min = bound->inner.max;
bound->inner.max = t;
}
tail_y = acc->tail_y;
if (tail_y > bound->elipse.max)
tail_y = bound->elipse.max;
else if (tail_y < bound->elipse.min)
tail_y = bound->elipse.min;
innerTaily = innerYfromY (tail_y, def, acc);
if (bound->inner.min > innerTaily)
bound->inner.min = innerTaily;
if (bound->inner.max < innerTaily)
bound->inner.max = innerTaily;
}
double
elipseY (edge_y, def, bound, acc, outer, y0, y1)
double edge_y;
struct arc_def *def;
struct arc_bound *bound;
struct accelerators *acc;
register double y0, y1;
{
register double w, h, l, h2, h4, w2, w4, x, y2;
double newtony, binaryy;
double value0, value1, valuealt;
double newtonvalue, binaryvalue;
double minY, maxY;
double binarylimit;
double (*f)();
w = def->w;
h = def->h;
f = outer ? outerYfromY : innerYfromY;
l = outer ? def->l : -def->l;
h2 = acc->h2;
h4 = acc->h4;
w2 = acc->w2;
w4 = acc->w4;
value0 = f (y0, def, acc) - edge_y;
if (value0 == 0)
return y0;
value1 = f (y1, def, acc) - edge_y;
maxY = y1;
minY = y0;
if (y0 > y1) {
maxY = y0;
minY = y1;
}
if (value1 == 0)
return y1;
if (value1 > 0 == value0 > 0)
return -1.0;
binarylimit = fabs ((value1 - value0) / 25.0);
if (binarylimit < (0.1))
binarylimit = (0.1);
do {
if (y0 == y1 || value0 == value1)
return maxY+1;
binaryy = (y0 + y1) / 2;
y2 = binaryy*binaryy;
x = w * Sqrt ((h2 - (y2)) / h2);
binaryvalue = ( binaryy + (binaryy * w2 * l) /
(2 * Sqrt (x*x * h4 + y2 * w4))) - edge_y;
if (binaryvalue > 0 == value0 > 0) {
y0 = binaryy;
value0 = binaryvalue;
} else {
y1 = binaryy;
value1 = binaryvalue;
}
} while (fabs (value1) > binarylimit);
if (binaryvalue == 0)
return binaryy;
while (fabs (value1) > (0.0000001)) {
newtony = y1 - value1 * (y1 - y0) / (value1 - value0);
if (newtony > maxY)
newtony = maxY;
if (newtony < minY)
newtony = minY;
y2 = newtony*newtony;
x = w * Sqrt ((h2 - (y2)) / h2);
newtonvalue = ( newtony + (newtony * w2 * l) /
(2 * Sqrt (x*x * h4 + y2 * w4))) - edge_y;
if (newtonvalue == 0)
return newtony;
if (fabs (value0) > fabs (value1)) {
y0 = newtony;
value0 = newtonvalue;
} else {
y1 = newtony;
value1 = newtonvalue;
}
}
return y1;
}
double
elipseX (elipse_y, def, acc)
double elipse_y;
struct arc_def *def;
struct accelerators *acc;
{
return def->w / def->h * Sqrt (acc->h2 - elipse_y * elipse_y);
}
double
outerX (outer_y, def, bound, acc)
register double outer_y;
register struct arc_def *def;
struct arc_bound *bound;
struct accelerators *acc;
{
double y;
if (def->w == def->h) {
register double x;
x = def->w + def->l/2.0;
x = Sqrt (x * x - outer_y * outer_y);
return x;
}
if (outer_y == bound->outer.min)
y = bound->elipse.min;
if (outer_y == bound->outer.max)
y = bound->elipse.max;
else
y = elipseY (outer_y, def, bound, acc, 1,
bound->elipse.min, bound->elipse.max);
return outerXfromY (y, def, acc);
}
innerXs (inner_y, def, bound, acc, innerX1p, innerX2p)
register double inner_y;
struct arc_def *def;
struct arc_bound *bound;
struct accelerators *acc;
double *innerX1p, *innerX2p;
{
register double x1, x2;
double xalt, y0, y1, altY, elipse_y1, elipse_y2;
if (def->w == def->h) {
x1 = def->w - def->l/2.0;
x2 = Sqrt (x1 * x1 - inner_y * inner_y);
if (x1 < 0)
x2 = -x2;
*innerX1p = *innerX2p = x2;
return;
}
if ((( bound->elipse).min <= (acc->tail_y) && (acc->tail_y) <= ( bound->elipse).max)) {
if (def->h > def->w) {
y0 = bound->elipse.min;
y1 = acc->tail_y;
altY = bound->elipse.max;
} else {
y0 = bound->elipse.max;
y1 = acc->tail_y;
altY = bound->elipse.min;
}
elipse_y1 = elipseY (inner_y, def, bound, acc, 0, y0, y1);
elipse_y2 = elipseY (inner_y, def, bound, acc, 0, y1, altY);
if (elipse_y1 == -1.0)
elipse_y1 = elipse_y2;
if (elipse_y2 == -1.0)
elipse_y2 = elipse_y1;
} else {
elipse_y1 = elipseY (inner_y, def, bound, acc, 0,
bound->elipse.min, bound->elipse.max);
elipse_y2 = elipse_y1;
}
x2 = x1 = innerXfromY (elipse_y1, def, acc);
if (elipse_y1 != elipse_y2)
x2 = innerXfromY (elipse_y2, def, acc);
if (acc->left.valid && (( bound->left).min <= (inner_y) && (inner_y) <= ( bound->left).max)) {
xalt = intersectLine (inner_y, &acc->left);
if (xalt < x2 && xalt < x1)
x2 = xalt;
if (xalt < x1)
x1 = xalt;
}
if (acc->right.valid && (( bound->right).min <= (inner_y) && (inner_y) <= ( bound->right).max)) {
xalt = intersectLine (inner_y, &acc->right);
if (xalt < x2 && xalt < x1)
x2 = xalt;
if (xalt < x1)
x1 = xalt;
}
*innerX1p = x1;
*innerX2p = x2;
}
double
hookElipseY (scan_y, def, bound, acc, left)
double scan_y;
struct arc_def *def;
struct arc_bound *bound;
struct accelerators *acc;
{
double ret;
if (acc->h2mw2 == 0) {
if (scan_y > 0 && !left || scan_y < 0 && left)
return bound->elipse.min;
return bound->elipse.max;
}
ret = (acc->h4 * scan_y) / (acc->h2mw2);
if (ret >= 0)
return pow (ret, 1.0/3.0);
else
return -pow (-ret, 1.0/3.0);
}
double
hookX (scan_y, def, bound, acc, left)
double scan_y;
struct arc_def *def;
struct arc_bound *bound;
struct accelerators *acc;
int left;
{
double elipse_y, elipse_x, x, xalt;
double maxMin;
if (def->w != def->h) {
elipse_y = hookElipseY (scan_y, def, bound, acc, left);
if ((( bound->elipse).min <= (elipse_y) && (elipse_y) <= ( bound->elipse).max)) {
maxMin = elipse_y*elipse_y*elipse_y * acc->h2mw2 -
acc->h2 * scan_y * (3 * elipse_y*elipse_y - 2*acc->h2);
if ((left && maxMin > 0) || (!left && maxMin < 0)) {
if (elipse_y == 0)
return def->w + left ? -def->l/2 : def->l/2;
x = (acc->h2 * scan_y - elipse_y * acc->h2mw2) *
Sqrt (acc->h2 - elipse_y * elipse_y) /
(def->h * def->w * elipse_y);
return x;
}
}
}
if (left) {
if (acc->left.valid && (( bound->left).min <= (scan_y) && (scan_y) <= ( bound->left).max)) {
x = intersectLine (scan_y, &acc->left);
} else {
if (acc->right.valid)
x = intersectLine (scan_y, &acc->right);
else
x = def->w - def->l/2;
}
} else {
if (acc->right.valid && (( bound->right).min <= (scan_y) && (scan_y) <= ( bound->right).max)) {
x = intersectLine (scan_y, &acc->right);
} else {
if (acc->left.valid)
x = intersectLine (scan_y, &acc->left);
else
x = def->w - def->l/2;
}
}
return x;
}
arcSpan (y, def, bounds, acc)
double y;
struct arc_def *def;
struct arc_bound *bounds;
struct accelerators *acc;
{
double innerx1, innerx2, outerx1, outerx2;
if ((( bounds->inner).min <= (y) && (y) <= ( bounds->inner).max)) {
innerXs (y, def, bounds, acc, &innerx1, &innerx2);
} else {
innerx2 = innerx1 = hookX (y, def, bounds, acc, 1);
if (acc->right.valid && (( bounds->right).min <= (y) && (y) <= ( bounds->right).max))
{
innerx2 = intersectLine (y, &acc->right);
if (innerx2 < innerx1)
innerx1 = innerx2;
}
}
if ((( bounds->outer).min <= (y) && (y) <= ( bounds->outer).max)) {
outerx1 = outerx2 = outerX (y, def, bounds, acc);
} else {
outerx2 = outerx1 = hookX (y, def, bounds, acc, 0);
if (acc->left.valid && (( bounds->left).min <= (y) && (y) <= ( bounds->left).max))
{
outerx2 = intersectLine (y, &acc->left);
if (outerx2 < outerx1)
outerx2 = outerx1;
}
}
if (innerx1 < outerx1 && outerx1 < innerx2 && innerx2 < outerx2) {
span (innerx1, outerx1);
span (innerx2, outerx2);
} else
span (innerx1, outerx2);
}
static double arcXcenter, arcYcenter;
static int arcXoffset, arcYoffset;
static struct finalSpan **finalSpans;
static int finalMiny, finalMaxy;
static int finalSize;
static int nspans;
struct finalSpan {
struct finalSpan *next;
int min, max;
};
static struct finalSpan *freeFinalSpans, *tmpFinalSpan;
struct finalSpanChunk {
struct finalSpan data[ 128];
struct finalSpanChunk *next;
};
static struct finalSpanChunk *chunks;
struct finalSpan *
realAllocSpan ()
{
register struct finalSpanChunk *newChunk;
register struct finalSpan *span;
register int i;
newChunk = (struct finalSpanChunk *) Xalloc (sizeof (struct finalSpanChunk));
if (!newChunk)
return (struct finalSpan *) Xalloc (sizeof (struct finalSpan));
newChunk->next = chunks;
chunks = newChunk;
freeFinalSpans = span = newChunk->data + 1;
for (i = 1; i < 128-1; i++) {
span->next = span+1;
span++;
}
span->next = 0;
span = newChunk->data;
span->next = 0;
return span;
}
disposeFinalSpans ()
{
struct finalSpanChunk *chunk, *next;
for (chunk = chunks; chunk; chunk = next) {
next = chunk->next;
Xfree (chunk);
}
chunks = 0;
freeFinalSpans = 0;
}
fillSpans (pDrawable, pGC)
DrawablePtr pDrawable;
GCPtr pGC;
{
register struct finalSpan *span;
register DDXPointPtr xSpan;
register int *xWidth;
register int i;
register struct finalSpan **f;
register int spany;
DDXPointPtr xSpans;
int *xWidths;
if (nspans == 0)
return;
xSpan = xSpans = (DDXPointPtr) Xalloc (nspans * sizeof (DDXPointRec));
xWidth = xWidths = (int *) Xalloc (nspans * sizeof (int));
i = 0;
f = finalSpans;
for (spany = finalMiny; spany < finalMaxy; spany++, f++) {
for (span = *f; span; span=span->next) {
if (span->max <= span->min) {
printf ("span width: %d\n", span->max-span->min);
continue;
}
xSpan->x = span->min;
xSpan->y = spany;
++xSpan;
*xWidth++ = span->max - span->min;
++i;
}
}
disposeFinalSpans ();
Xfree (finalSpans);
(*pGC->FillSpans) (pDrawable, pGC, i, xSpans, xWidths, 1);
Xfree (xSpans);
Xfree (xWidths);
finalSpans = 0;
finalMiny = 0;
finalMaxy = 0;
finalSize = 0;
nspans = 0;
}
struct finalSpan **
realFindSpan (y)
{
struct finalSpan **newSpans;
int newSize, newMiny, newMaxy;
int change;
int i;
if (y < finalMiny || y >= finalMaxy) {
if (y < finalMiny)
change = finalMiny - y;
else
change = y - finalMaxy;
if (change > 1024)
change += 1024;
else
change = 1024;
newSize = finalSize + change;
newSpans = (struct finalSpan **) Xalloc
(newSize * sizeof (struct finalSpan *));
newMiny = finalMiny;
newMaxy = finalMaxy;
if (y < finalMiny)
newMiny = finalMiny - change;
else
newMaxy = finalMaxy + change;
if (finalSpans) {
bcopy ((char *) finalSpans,
((char *) newSpans) + (finalMiny-newMiny) * sizeof (struct finalSpan *),
finalSize * sizeof (struct finalSpan *));
Xfree (finalSpans);
}
if ((i = finalMiny - newMiny) > 0)
bzero (newSpans, i * sizeof (struct finalSpan *));
if ((i = newMaxy - finalMaxy) > 0)
bzero (newSpans + finalMaxy - newMiny,
i * sizeof (struct finalSpan *));
finalSpans = newSpans;
finalMaxy = newMaxy;
finalMiny = newMiny;
finalSize = newSize;
}
return &finalSpans[y - finalMiny];
}
newFinalSpan (y, xmin, xmax)
int y;
register int xmin, xmax;
{
register struct finalSpan *x;
register struct finalSpan **f;
struct finalSpan *oldx;
struct finalSpan *prev;
f = ((finalMiny <= (y) && (y) < finalMaxy) ? &finalSpans[(y) - finalMiny] : realFindSpan (y));
oldx = 0;
for (;;) {
prev = 0;
for (x = *f; x; x=x->next) {
if (x == oldx) {
prev = x;
continue;
}
if (x->min <= xmax && xmin <= x->max) {
if (oldx) {
oldx->min = min (x->min, xmin);
oldx->max = max (x->max, xmax);
if (prev)
prev->next = x->next;
else
*f = x->next;
--nspans;
} else {
x->min = min (x->min, xmin);
x->max = max (x->max, xmax);
oldx = x;
}
xmin = oldx->min;
xmax = oldx->max;
break;
}
prev = x;
}
if (!x)
break;
}
if (!oldx) {
x = (freeFinalSpans ? ((tmpFinalSpan = freeFinalSpans), (freeFinalSpans = freeFinalSpans->next), (tmpFinalSpan->next = 0), tmpFinalSpan) : realAllocSpan ());
x->min = xmin;
x->max = xmax;
x->next = *f;
*f = x;
++nspans;
}
}
mirrorSppPoint (quadrant, sppPoint)
int quadrant;
SppPointPtr sppPoint;
{
switch (quadrant) {
case 0:
break;
case 1:
sppPoint->x = -sppPoint->x;
break;
case 2:
sppPoint->x = -sppPoint->x;
sppPoint->y = -sppPoint->y;
break;
case 3:
sppPoint->y = -sppPoint->y;
break;
}
sppPoint->y = -sppPoint->y;
}
static double spanY;
static int quadrantMask;
span (left, right)
double left, right;
{
register int mask = quadrantMask, bit;
register double min, max, y;
int xmin, xmax, spany;
while (mask) {
bit = ((mask) & (~(mask) + 1));
mask &= ~bit;
switch (bit) {
case 1:
min = left;
max = right;
y = spanY;
break;
case 2:
min = -right;
max = -left;
y = spanY;
break;
case 4:
min = -right;
max = -left;
y = -spanY;
break;
case 8:
min = left;
max = right;
y = -spanY;
break;
default:
abort ();
}
xmin = (int) ceil (min + arcXcenter) + arcXoffset;
xmax = (int) ceil (max + arcXcenter) + arcXoffset;
spany = (int) (ceil (arcYcenter - y)) + arcYoffset;
if (xmax > xmin)
newFinalSpan (spany, xmin, xmax);
}
}
drawArc (x0, y0, w, h, l, a0, a1, right, left)
int x0, y0, w, h, l, a0, a1;
miArcFacePtr right, left;
{
struct arc_def def;
struct accelerators acc;
struct span *result;
int startq, endq, curq;
int rightq, leftq, righta, lefta;
miArcFacePtr passRight, passLeft;
int q0, q1, mask;
struct band {
int a0, a1;
int mask;
} band[5], sweep[20];
int bandno, sweepno;
int i, j, k;
int flipRight = 0, flipLeft = 0;
def.w = ((double) w) / 2;
def.h = ((double) h) / 2;
arcXoffset = x0;
arcYoffset = y0;
arcXcenter = def.w;
arcYcenter = def.h;
def.l = (double) l;
if (a1 < a0)
a1 += 360 * 64;
startq = a0 / (90 * 64);
endq = (a1-1) / (90 * 64);
bandno = 0;
curq = startq;
for (;;) {
switch (curq) {
case 0:
if (a0 > 90 * 64)
q0 = 0;
else
q0 = a0;
if (a1 < 360 * 64)
q1 = min (a1, 90 * 64);
else
q1 = 90 * 64;
if (curq == startq && a0 == q0) {
righta = q0;
rightq = curq;
}
if (curq == endq && a1 == q1) {
lefta = q1;
leftq = curq;
}
break;
case 1:
if (a1 < 90 * 64)
q0 = 0;
else
q0 = 180 * 64 - min (a1, 180 * 64);
if (a0 > 180 * 64)
q1 = 90 * 64;
else
q1 = 180 * 64 - max (a0, 90 * 64);
if (curq == startq && 180 * 64 - a0 == q1) {
righta = q1;
rightq = curq;
}
if (curq == endq && 180 * 64 - a1 == q0) {
lefta = q0;
leftq = curq;
}
break;
case 2:
if (a0 > 270 * 64)
q0 = 0;
else
q0 = max (a0, 180 * 64) - 180 * 64;
if (a1 < 180 * 64)
q1 = 90 * 64;
else
q1 = min (a1, 270 * 64) - 180 * 64;
if (curq == startq && a0 - 180*64 == q0) {
righta = q0;
rightq = curq;
}
if (curq == endq && a1 - 180 * 64 == q1) {
lefta = q1;
leftq = curq;
}
break;
case 3:
if (a1 < 270 * 64)
q0 = 0;
else
q0 = 360 * 64 - min (a1, 360 * 64);
q1 = 360 * 64 - max (a0, 270 * 64);
if (curq == startq && 360 * 64 - a0 == q1) {
righta = q1;
rightq = curq;
}
if (curq == endq && 360 * 64 - a1 == q0) {
lefta = q0;
leftq = curq;
}
break;
}
band[bandno].a0 = q0;
band[bandno].a1 = q1;
band[bandno].mask = 1 << curq;
bandno++;
if (curq == endq)
break;
curq++;
if (curq == 4) {
a0 = 0;
a1 -= 360 * 64;
curq = 0;
endq -= 4;
}
}
sweepno = 0;
for (;;) {
q0 = 90 * 64;
mask = 0;
for (i = 0; i < bandno; i++)
if (band[i].a0 < q0) {
q0 = band[i].a0;
q1 = band[i].a1;
mask = band[i].mask;
}
if (!mask)
break;
for (i = 0; i < bandno; i++)
if (!(mask & band[i].mask)) {
if (band[i].a0 == q0) {
if (band[i].a1 < q1)
q1 = band[i].a1;
mask |= band[i].mask;
} else if (band[i].a0 < q1)
q1 = band[i].a0;
}
sweep[sweepno].a0 = q0;
sweep[sweepno].a1 = q1;
sweep[sweepno].mask = mask;
sweepno++;
for (i = 0; i < bandno; i++)
if (band[i].a0 == q0) {
band[i].a0 = q1;
if (band[i].a0 == band[i].a1)
band[i].a1 = band[i].a0 = 90 * 64;
}
}
computeAcc (&def, &acc);
for (j = 0; j < sweepno; j++) {
mask = sweep[j].mask;
passRight = passLeft = 0;
if (mask & (1 << rightq)) {
if (sweep[j].a0 == righta)
passRight = right;
if (sweep[j].a1 == righta) {
passLeft = right;
flipRight = 1;
}
}
if (mask & (1 << leftq)) {
if (sweep[j].a0 == lefta) {
passRight = left;
flipLeft = 1;
}
if (sweep[j].a1 == lefta)
passLeft = left;
}
drawQuadrant (&def, &acc, sweep[j].a0, sweep[j].a1, mask,
passRight, passLeft);
}
if (right) {
mirrorSppPoint (rightq, &right->clock);
mirrorSppPoint (rightq, &right->center);
mirrorSppPoint (rightq, &right->counterClock);
if (flipRight) {
SppPointRec temp;
temp = right->clock;
right->clock = right->counterClock;
right->counterClock = temp;
}
}
if (left) {
mirrorSppPoint (leftq, &left->counterClock);
mirrorSppPoint (leftq, &left->center);
mirrorSppPoint (leftq, &left->clock);
if (flipLeft) {
SppPointRec temp;
temp = left->clock;
left->clock = left->counterClock;
left->counterClock = temp;
}
}
}
drawQuadrant (def, acc, a0, a1, mask, right, left)
struct arc_def *def;
struct accelerators *acc;
int a0, a1;
int mask;
miArcFacePtr right, left;
{
struct arc_bound bound;
double miny, maxy, y;
int minIsInteger;
def->a0 = ((double) a0) / 64.0;
def->a1 = ((double) a1) / 64.0;
computeBound (def, &bound, acc, right, left);
y = fmin (bound.inner.min, bound.outer.min);
miny = ceil(y) + def->w - floor (def->w);
minIsInteger = y == miny;
y = fmax (bound.inner.max, bound.outer.max);
maxy = floor (y) + def->w - floor (def->w);
for (y = miny; y <= maxy; y = y + 1.0) {
if (y == miny && minIsInteger)
quadrantMask = mask & 0xc;
else
quadrantMask = mask;
spanY = y;
arcSpan (y, def, &bound, acc);
}
if (a1 == 90 * 64 && (mask & 1) && ((int) (def->w * 2 + def->l)) & 1) {
quadrantMask = 1;
spanY = def->h + def->l/2;
span (0.0, 1.0);
}
}
max (x, y)
{
return x>y? x:y;
}
min (x, y)
{
return x<y? x:y;
}