📄 arcs0.c
字号:
if (qaEdgeBuffer[0].Count != 1)
{ /* need inner edges too */
qaEdgeBuffer[4] = qaEdgeBuffer[0]; /* copy the outer arcs */
qaEdgeBuffer[5] = qaEdgeBuffer[1]; /* to the inner arcs */
qaEdgeBuffer[6] = qaEdgeBuffer[2];
qaEdgeBuffer[7] = qaEdgeBuffer[3];
/* flip arc top->bottom so this can work with the outer arc */
newEdge = &qaEdgeBuffer[4];
qaEdgeBuffer[4].TopToBottom = -qaEdgeBuffer[4].TopToBottom;
qaEdgeBuffer[4].CurrentX++; /* shift 1 to the right */
qaEdgeBuffer[4].StartY++; /* shift down 1 */
qaEdgeBuffer[4].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[5];
qaEdgeBuffer[5].TopToBottom = -qaEdgeBuffer[5].TopToBottom;
qaEdgeBuffer[5].CurrentX--; /* shift 1 to the left */
qaEdgeBuffer[5].StartY++; /* shift down 1 */
qaEdgeBuffer[5].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[6];
qaEdgeBuffer[6].TopToBottom = -qaEdgeBuffer[6].TopToBottom;
qaEdgeBuffer[6].CurrentX++; /* shift 1 to the right */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
qaEdgeBuffer[6].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[7];
qaEdgeBuffer[7].TopToBottom = -qaEdgeBuffer[7].TopToBottom;
qaEdgeBuffer[7].CurrentX--; /* shift 1 to the left */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
qaEdgeBuffer[7].Count--; /* skip the bottommost point */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[8]; /* point to next table entry */
}
}
else
{ /* wide */
/* Draws a wide-line framed oval. The approach is the same as for thin
framed ovals, except that the outer arcs are moved out by the X and Y
pen radii, and the inner arcs are moved in similarly. */
gBaseR = gR;
/* For odd pen dimensions, we can be symmetric about the thin edge. For
even, we bias the extra pixel to the outside of the frame. */
/* set up the four outer arcs first and rounded up */
halfWidth = (grafPort.pnSize.X >> 1);
gR.Xmin -= halfWidth;
gR.Xmax += halfWidth;
halfHeight = (grafPort.pnSize.Y >> 1);
gR.Ymin -= halfHeight;
gR.Ymax += halfHeight;
xRadius = ((gR.Xmax - gR.Xmin) >> 1);
yRadius = ((gR.Ymax - gR.Ymin) >> 1);
if ((xRadius < 0) || (yRadius < 0))
{
grafErrValue = c_FrameArc + c_NullRect; /* bad rectangle */
nuGrafErr(grafErrValue); /* report error */
globalLevel++;
return;
}
cR.Xmin = gR.Xmin + xRadius; /* compute center point */
cR.Ymin = gR.Ymin + yRadius;
cR.Xmax = gR.Xmax - xRadius;
cR.Ymax = gR.Ymax - yRadius;
gR.Xmax++; /* round up rect for frame */
gR.Ymax++;
OvalPt(&gR, bgnAngle, &bgnPt); /* point of intersection for begin angle */
OvalPt(&gR, endAngle, &endPt); /* point of intersection for end angle */
/* set up the outer edges first */
GETPtr = &qaEdgeBuffer[0];
newEdge = GETPtr;
newEdge->countNumber = 0; /* show as arc entry */
mwSTQA(newEdge, xRadius, yRadius, cR.Xmin, cR.Ymin, -1, -1);
newEdge = &qaEdgeBuffer[1];
mwSTQA(newEdge, xRadius, yRadius, (cR.Xmax +1), cR.Ymin, 1, 1);
newEdge->countNumber = 0; /* show as arc entry */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[2];
mwSBQA(newEdge, xRadius, yRadius, cR.Xmin, cR.Ymax, 1, -1);
newEdge->countNumber = 0; /* show as arc entry */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[3];
mwSBQA(newEdge, xRadius, yRadius, (cR.Xmax +1), cR.Ymax, -1, 1);
newEdge->countNumber = 0; /* show as arc entry */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[4];
/* if the outer arcs are flat, the current GET is all we need */
if (qaEdgeBuffer[0].Count != 1)
{ /* need inner edges too */
/*Inner arcs are pulled in from frame edge by pen radii. For odd
pen dimensions, we can be symmetric between inner and outer edge
displacements. For even pen dimensions, we bias the extra pixel
to the outside. */
halfWidth = ((grafPort.pnSize.X - 1) >> 1);
iR.Xmin = gBaseR.Xmin + halfWidth;
iR.Xmax = gBaseR.Xmax - halfWidth;
halfHeight = ((grafPort.pnSize.Y - 1) >> 1);
iR.Ymin = gBaseR.Ymin + halfHeight;
iR.Ymax = gBaseR.Ymax - halfHeight;
rXWidth = iR.Xmax - iR.Xmin; /* width */
rXHeight = iR.Ymax - iR.Ymin; /* height */
if ((rXWidth > 0) && (rXHeight > 0))
{
thisLeftEdge = iR.Xmin + xRadius; /* left edge + height */
nextTopEdge = iR.Ymin + yRadius; /* top edge + height */
thisRightEdge = iR.Xmax - xRadius + 1; /* shift right by 1 to
compensate for the filler not drawing right edges */
nextBottomEdge = iR.Ymax - yRadius; /* bottom edge - height */
/* set up the upper left arc */
newEdge = &qaEdgeBuffer[4];
mwSTQA(newEdge, xRadius, yRadius, thisLeftEdge, nextTopEdge, -1, 1);
/* set up the upper right arc */
newEdge = &qaEdgeBuffer[5];
mwSTQA(newEdge, xRadius, yRadius, thisRightEdge, nextTopEdge, 1, -1);
/* set up the lower left arc */
newEdge = &qaEdgeBuffer[6];
mwSBQA(newEdge, xRadius, yRadius, thisLeftEdge, nextBottomEdge, 1, 1);
/* set up the upper right arc */
newEdge = &qaEdgeBuffer[7];
mwSBQA(newEdge, xRadius, yRadius, thisRightEdge, nextBottomEdge, -1, -1);
/* Now shift the edges down and right 1, to compensate for filler
characteristics and to make 1 wide be really 1 wide, and add to the GET. */
newEdge = &qaEdgeBuffer[4];
newEdge->CurrentX++; /* shift 1 to the right */
newEdge->StartY++; /* shift down 1 */
newEdge->Count--; /* skip the bottommost point */
newEdge->countNumber = 0; /* show as arc entry */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[5];
newEdge->CurrentX--; /* shift 1 to the left */
newEdge->StartY++; /* shift down 1 */
newEdge->Count--;
newEdge->countNumber = 0; /* show as arc entry */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[6];
newEdge->CurrentX++; /* shift 1 to the right */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
newEdge->Count--;
newEdge->countNumber = 0; /* show as arc entry */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[7];
newEdge->CurrentX--; /* shift 1 to the left */
newEdge->StepVector(newEdge); /* advance Y by 1 (skip first point) */
newEdge->Count--; /* skip the topmost point */
newEdge->countNumber = 0; /* show as arc entry */
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge = &qaEdgeBuffer[8]; /* point to next table entry */
}
}
}
/* Ready to process line insertions */
/* set up point table */
pointTbl[0] = cR.Xmin;
pointTbl[1] = cR.Ymin;
pointTbl[2] = cR.Xmax;
pointTbl[3] = cR.Ymax;
pointTbl[4] = gR.Xmin;
pointTbl[5] = gR.Ymin;
pointTbl[6] = gR.Xmax;
pointTbl[7] = gR.Ymax;
pointTbl[8] = bgnPt.X;
pointTbl[9] = bgnPt.Y;
pointTbl[10] = endPt.X;
pointTbl[11] = endPt.Y;
for (typePtr = 0; typePtr < 5; typePtr++)
{
if (typeTbl[arcType][typePtr][aeType] == vt) /* vertical or line edge entry? */
{ /* Enter vertical edge */
lineHeight = (pointTbl[typeTbl[arcType][typePtr][aeEndY]] -
pointTbl[typeTbl[arcType][typePtr][aeBgnY]]);
if (lineHeight > 0) /* skip if 0 */
{ /* insert end line edge */
mwSV((Vedge *)newEdge, pointTbl[typeTbl[arcType][typePtr][aeBgnX]],
pointTbl[typeTbl[arcType][typePtr][aeBgnY]], lineHeight,
typeTbl[arcType][typePtr][aeDir]);
newEdge->countNumber =1;
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge++;
}
}
else
{ /* Enter line edge */
/* skip if bgnY == endY */
if (pointTbl[typeTbl[arcType][typePtr][aeBgnY]] !=
pointTbl[typeTbl[arcType][typePtr][aeEndY]])
{ /* insert the line edge */
mwSLE((lineEdgeV *)newEdge, pointTbl[typeTbl[arcType][typePtr][aeBgnX]],
pointTbl[typeTbl[arcType][typePtr][aeBgnY]],
pointTbl[typeTbl[arcType][typePtr][aeEndX]],
pointTbl[typeTbl[arcType][typePtr][aeEndY]],
typeTbl[arcType][typePtr][aeDir]);
newEdge->countNumber =1;
AddToGETYXSorted(newEdge); /* insert the new edge in GET, YX sorted */
newEdge++;
}
}
if (typeTbl[arcType][typePtr][aeEnd] == tEnd) break;
}
/* draw the arc and done! */
mwScanGET((void **)&GETPtr,(blitRcd *) &rFillRcd[0], fillRcdSize, cmplx, -1, 0);
globalLevel++;
return;
}
/* Function mwFDA draws a dashed arc. The circumference of the arc oval
is computed and used to calculate dash lengths in degrees. Multiple
FrameArc calls are used to draw the dash sequences. */
void mwFDA(rect *boundR, int BANGLE, int AANGLE)
{
int endAng;
short pixDegree;
int dashListSize; /* elements in dash on/off table */
byte *dashOnOffList; /* pointer to on/off byte list */
int curDashNdx; /* current index into on/off table */
int curDashFlg; /* current state of dashing on/off */
int curDashCnt; /* current position in dash sequence */
int dashSeqCnt; /* dash sequence count */
/* turn off dash flag so we don't call ourselves again */
grafPort.pnFlags &= ~pnDashFlg;
/* # of dash elements in dashList */
dashListSize = grafPort.pnDashRcd[grafPort.pnDash].dashSize;
/* point to the dash list */
dashOnOffList = grafPort.pnDashRcd[grafPort.pnDash].dashList;
curDashNdx = grafPort.pnDashNdx;
curDashFlg = grafPort.pnFlags & pnDashState;
curDashCnt = grafPort.pnDashCnt;
endAng = BANGLE + AANGLE; /* compute endAngle */
/* Calculate how many pixels (times 100) per degree around the circumference.
Average the X and Y radius to simplify the calculations for an oval. */
pixDegree = 314 * (((boundR->Xmax - boundR->Xmin) + (boundR->Ymax -
boundR->Ymin)) >> 1) / 3600;
if (pixDegree == 0) pixDegree = 1; /* protect from later div by 0 */
/* pick up first partial dash sequence */
/* BobB 11/10/99 - corrected the following two lines for dash sequencing
dashOnOffList = dashOnOffList + curDashNdx;
dashSeqCnt = *dashOnOffList; */
dashSeqCnt = *(dashOnOffList + curDashNdx);
if (dashSeqCnt > curDashCnt) dashSeqCnt -= curDashCnt;
do /* until arc complete */
{
/* compute dash length in degrees */
dashSeqCnt *= 100;
dashSeqCnt /= pixDegree; /* divide by pixels per degree (times 100) */
/* if the size of the next segment goes past the end of the arc, draw
to the end of the arc. */
if ((dashSeqCnt + BANGLE) > endAng)
{
/* compute partial dash sequence done */
dashSeqCnt = endAng - BANGLE;
curDashCnt = dashSeqCnt * pixDegree / 100;
}
if (curDashFlg == 0) /* which dash state are we in? */
{ /* draw a foreground dash sequence */
FrameArc(boundR, BANGLE, dashSeqCnt);
}
else
{ /* draw a background dash sequence */
if (grafPort.pnFlags & pnDashStyle) /* test double-dash */
{ /* draw in back pattern */
grafBlit.blitPat = grafPort.bkPat;
FrameArc(boundR, BANGLE, dashSeqCnt);
grafBlit.blitPat = grafPort.pnPat;
}
}
BANGLE += dashSeqCnt; /* continue from where we left off */
curDashFlg ^= pnDashState; /* no, so flip dash state */
curDashNdx++; /* advance to next dash sequence */
/* BobB 11/10/99 - corrected the following line for dash sequencing
if (dashSeqCnt >= dashListSize) */ /* end of list? */
if (curDashNdx >= dashListSize) /* end of list? */
{ /* yes, so start list over */
/* BobB 11/10/99 - corrected the following line for dash sequencing
dashSeqCnt = 0; */
curDashNdx = 0;
}
/* BobB 11/10/99 - corrected the following three lines for dash sequencing
curDashNdx = dashSeqCnt;
dashOnOffList = dashOnOffList + curDashNdx;
dashSeqCnt = *dashOnOffList; */
dashSeqCnt = *(dashOnOffList + curDashNdx);
/* BobB 3/10/99 - corrected the following line for dashed lines
}while (BANGLE >= endAng);*/ /* done? */
}while (BANGLE < endAng); /* done? */
thePort->pnDashNdx = curDashNdx; /* update user port */
thePort->pnFlags = curDashFlg | pnDashFlg;
thePort->pnDashCnt = curDashCnt;
grafPort.pnDashNdx = curDashNdx; /* update the dash record */
grafPort.pnFlags |= thePort->pnFlags;
grafPort.pnDashCnt = curDashCnt;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -