executor/src/qStdArc.c

182 lines
5.1 KiB
C

/* Copyright 1986, 1988, 1989, 1990 by Abacus Research and
* Development, Inc. All rights reserved.
*/
#if !defined (OMIT_RCSID_STRINGS)
char ROMlib_rcsid_qStdArc[] =
"$Id: qStdArc.c 63 2004-12-24 18:19:43Z ctm $";
#endif
/* Forward declarations in QuickDraw.h (DO NOT DELETE THIS LINE) */
#include "rsys/common.h"
#include "QuickDraw.h"
#include "CQuickDraw.h"
#include "MemoryMgr.h"
#include "ToolboxUtil.h"
#include "rsys/cquick.h"
#include "rsys/picture.h"
#define returnhv(hh, vv) { ptp->h = hh; ptp->v = vv; return; }
A3(PRIVATE, void, getpoint, INTEGER, angle, Rect *, r, Point *, ptp)
{
INTEGER left = CW(r->left), top = CW(r->top),
right = CW(r->right), bottom = CW(r->bottom);
INTEGER radh = (right - left) / 2,
radv = (bottom - top) / 2;
INTEGER centh = left + radh,
centv = top + radv;
MoveTo(centh, centv);
if (angle == 0) {
/*-->*/ returnhv(centh, top)
} else if (angle == 90) {
/*-->*/ returnhv(right, centv)
} else if (angle == 180) {
/*-->*/ returnhv(centh, bottom)
} else if (angle == 270) {
/*-->*/ returnhv(left, centv)
} else if (angle >= 45 && angle <= 135) {
/*-->*/ returnhv(right, centv - (INTEGER)(FixMul(SlopeFromAngle(90-angle),
-(LONGINT) radv << 16) >> 16))
} else if (angle >= 225 && angle <= 315) {
/*-->*/ returnhv(left, centv + (INTEGER)(FixMul(SlopeFromAngle(90-angle),
-(LONGINT) radv << 16) >> 16))
} else if (angle < 45 || angle > 315) {
/*-->*/ returnhv(centh + (INTEGER)(FixMul(SlopeFromAngle(angle),
-(LONGINT) radh << 16) >> 16), top)
} else {
/*-->*/ returnhv(centh - (INTEGER)(FixMul(SlopeFromAngle(angle),
-(LONGINT) radh << 16) >> 16), bottom)
}
}
#define RTop 0
#define RRight 1
#define RBottom 2
#define RLeft 3
A3(PRIVATE, INTEGER, findwall, Rect *, r, INTEGER, h, INTEGER, v)
{
if (v == CW(r->top)) /* the order of tests is important */
return(RTop); /* don't change them if you don't see */
else if (h == CW(r->right)) /* why */
return(RRight);
else if (v == CW(r->bottom))
return(RBottom);
else
return(RLeft);
}
P4 (PUBLIC pascal trap, void, StdArc, GrafVerb, verb, Rect *, r,
INTEGER, starta, INTEGER, arca)
{
INTEGER left = CW(r->left), top = CW(r->top),
right = CW(r->right), bottom = CW(r->bottom);
INTEGER ewall;
Point spt, ept;
register INTEGER h, v;
INTEGER enda;
INTEGER done;
RgnHandle saveclip, rh;
Point saveloc;
INTEGER tmpvis;
INTEGER swappedarca, swappedstarta;
PAUSEDECL;
if (EmptyRect(r))
/*-->*/ return;
if (arca <= -360 || arca >= 360)
{
StdOval(verb, r);
/*-->*/ return;
}
PIC_SAVE_EXCURSION
({
ROMlib_drawingverbrectpicupdate( verb, r );
PICOP(OP_frameArc + (int) verb);
PICWRITE(r, sizeof(*r));
swappedstarta = CW(starta);
PICWRITE(&swappedstarta, sizeof(swappedstarta));
swappedarca = CW(arca);
PICWRITE(&swappedarca, sizeof(swappedarca));
});
if (PORT_PEN_VIS (thePort) < 0)
/*-->*/ return;
saveloc = PORT_PEN_LOC (thePort);
PAUSERECORDING;
tmpvis = PORT_PEN_VIS_X (thePort);
PORT_PEN_VIS_X (thePort) = CWC (0);
OpenRgn ();
enda = starta + arca;
if (arca < 0) {
arca = starta; /* use arca as a temp... not needed anymore */
starta = enda;
enda = arca;
}
while (starta < 0)
starta += 360;
while (enda < 0)
enda += 360;
starta %= 360;
enda %= 360;
getpoint(starta, r, &spt);
getpoint(enda, r, &ept);
MoveTo(left + (right - left) / 2, top + (bottom - top) / 2);
ewall = findwall(r, ept.h, ept.v);
LineTo(h = spt.h, v = spt.v);
for (done = FALSE; !done;)
switch (findwall(r, h, v)) {
case RTop:
if (ewall == RTop && h <= ept.h) {
LineTo(ept.h, top);
done = TRUE;
break;
}
LineTo(h = right, v = top);
case RRight:
if (ewall == RRight && v <= ept.v) {
LineTo(right, ept.v);
done = TRUE;
break;
}
LineTo(h = right, v = bottom);
case RBottom:
if (ewall == RBottom && h >= ept.h) {
LineTo(ept.h, bottom);
done = TRUE;
break;
}
LineTo(h = left, v = bottom);
case RLeft:
if (ewall == RLeft && v >= ept.v) {
LineTo(left, ept.v);
done = TRUE;
break;
}
LineTo(h = left, v = top);
}
LineTo (left + (right - left) / 2, top + (bottom - top) / 2);
rh = NewRgn();
CloseRgn (rh);
PORT_PEN_VIS_X (thePort) = tmpvis;
saveclip = PORT_CLIP_REGION_X (thePort);
SectRgn (MR (saveclip), rh, rh);
PORT_CLIP_REGION_X (thePort) = RM (rh);
StdOval (verb, r);
PORT_CLIP_REGION_X (thePort) = saveclip;
DisposeRgn (rh);
RESUMERECORDING;
PORT_PEN_LOC (thePort) = saveloc;
}