📄 lin07.c
字号:
don't support that, we won't do it here */
lclCapStyle = capRound;
if(dashFlags & pnDashStyle) /* on-off or double-dash? */
{/* Double-dash style square pen wide line */
/* cap non-end points flat so they fit together */
dashCap = capFlat;
/* Main square pen double-dash line drawing loop */
/* BobB 4/23/99 - corrected dashed line rect count
while(rectCnt-- > 0) */
while(lRectCnt-- > 0)
{
/* Set up the line state for this line */
/* Skipping is ignored for square pen wide lines */
lineState.lsSkipStat = NoSkip;
rlistPtr = (rect *) ((long) vListPtr++);
if(_mwLLSetup(rlistPtr)) continue;
dashPoly1.numPoints = 0;
dashPoly2.numPoints = 0;
/* mark the first burst for this line */
firstTime = 1;
do{
_mwLL();
saveBlitCnt = lclblitRec->blitCnt;
saveDashIndex = dashIndex;
saveDashCount = dashCount;
saveDashFlags = dashFlags;
rlistPtr = (rect *) lclblitRec->blitList;
ProcessDashesSq(rlistPtr, &dashPoly1);
lclblitRec->blitCnt = saveBlitCnt;
dashIndex = saveDashIndex;
dashCount = saveDashCount;
dashFlags = saveDashFlags ^ pnDashState;
lclblitRec->blitPat = workingBkPat;
rlistPtr = (rect *) lclblitRec->blitList;
ProcessDashesSq(rlistPtr, &dashPoly2);
dashFlags ^= pnDashState;
lclblitRec->blitPat = workingPnPat;
firstTime = 0;
}while(lineState.lsMajorAxisLengthM1 >= 0);
}
}
else
{/* On-off style line. */
/* Dashes are capped with the same style as the line */
dashCap = lclCapStyle;
/* Main on-off line-drawing loop. */
while(rectCnt-- > 0)
{
/* Set up line state for this line */
lineState.lsSkipStat = NoSkip;
rlistPtr = (rect *) ((long) vListPtr++);
if(_mwLLSetup(rlistPtr)) continue;
firstTime = 1;
dashPoly1.numPoints = 0;
do{
_mwLL();
rlistPtr = (rect *) lclblitRec->blitList;
ProcessDashesSq(rlistPtr, &dashPoly1);
firstTime = 0;
}while(lineState.lsMajorAxisLengthM1 >= 0);
}
}
return;
}
/*======================================================================
Processes rects according to the current dash state and the dash list,
keeping only "on" rects and approximating a correction for angle.
***Note*** in order to process properly the last point, there must be
an extra point after that. At the least, there must be *something*
legally addressable for 8 bytes after the last rect in the source list,
so that this routine has something to read to determine the final move
type. Dash count *must* be greater than zero on entry, and is always
greater than zero on exit. */
void ProcessDashes(rect *rlistPtr)
{
rect *temp1Rec,*temp2Rec;
long count;
short tempBlitCount,temcount,temdashIndex;
byte *temstart;
count = dashCount;
tempBlitCount = lclblitRec->blitCnt;
temcount = tempBlitCount;
if(tempBlitCount == 0) return;
temp1Rec = (rect *) lclblitRec->blitList; /* load the destination rects */
do{
if(dashFlags & pnDashState)
{/* Dash is on; keep rects until either come to end or out of rects */
do{
temp2Rec = (rect *) (rlistPtr);
*temp1Rec++ = *rlistPtr++;
if((temp2Rec->Xmin == rlistPtr->Xmin) ||
(temp2Rec->Ymin == rlistPtr->Ymin))
{
count -= 128;
}
else
{
count -= 181;
}
temcount--;
if(temcount == 0)
{
if(count > 0)
{
goto PDCheckMoreBurst;
}
else
{
break;
}
}
} while (count > 0);
}
else
{/* Dash is off; skip rects until either come to end or out of rects */
do{
tempBlitCount--;
temp2Rec = (rect *) (rlistPtr);
rlistPtr++;
if((temp2Rec->Xmin == rlistPtr->Xmin) ||
(temp2Rec->Ymin == rlistPtr->Ymin))
{
count -= 128;
}
else
{
count -= 181;
}
temcount--;
if(temcount == 0)
{
if(count > 0)
{
goto PDCheckMoreBurst;
}
else
{
break;
}
}
} while (count > 0);
}
/* flip the state and advance the dash pointer */
do{
dashFlags ^= pnDashState;
dashIndex++;
if(dashIndex >= dashElements) dashIndex = 0;
temstart = (dashListStart + dashIndex);
temdashIndex = *temstart;
count += temdashIndex << 7;
} while (count <= 0);
PDCheckMoreBurst:
;
} while (temcount > 0);
dashCount = count;
/* tempBlitCnt = 0 there is no line; = 127 no dash */
lclblitRec->blitCnt = tempBlitCount;
return;
}
/*======================================================================
Processes rects into square pen wide line dashes according to the current
dash state and the dash list, keeping only "on" rects and approximating a
correction for angle.
***Note*** in order to process properly the last point, there must be
an extra point after that. At the least, there must be *something*
legally addressable for 8 bytes after the last rect in the source list,
so that this routine has something to read to determine the final move
type. Dash count *must* be greater than zero on entry, and is always
greater than zero on exit. */
void ProcessDashesSq(rect *rlistPtr, dashPoly *dashPolyPtr)
{
short temBlitCnt,tem,temdashIndex;
long temDashCnt;
rect *temp2Rec;
byte *temstart;
long saveBlitList;
temBlitCnt = lclblitRec->blitCnt;
temDashCnt = dashCount;
if(temBlitCnt == 0) return; /* No pixel to do */
if((firstTime) && (dashFlags & pnDashState))
{/* capping the start of the dash; add the cap points to the dash */
DoCapPoints(rlistPtr, dashPolyPtr, lclCapStyle, CAP_DASH_START);
}
do{
if((dashFlags & pnDashState) == 0)
goto PDSqOff;
do{
temp2Rec = (rect *) (rlistPtr);
rlistPtr++;
if((temp2Rec->Xmin == rlistPtr->Xmin) ||
(temp2Rec->Ymin == rlistPtr->Ymin))
{
temDashCnt -= 128;
}
else
{
temDashCnt -= 181;
}
if(--temBlitCnt == 0) goto PDSqHandleLast;
} while (temDashCnt > 0);
goto PDSqDrawDashAndAdvance;
PDSqHandleLast:
if(lineState.lsMajorAxisLengthM1 >= 0)
goto PDSqCheckAdvance;
/* end of the line so use capping and capping the end of the
dash; add the cap points to the dash's */
DoCapPoints(rlistPtr, dashPolyPtr, lclCapStyle, CAP_DASH_END);
saveBlitList = lclblitRec->blitList;
tem = (MAX_RECTS/2) *(sizeof(rect)) + sizeof(blitRcd);
mwFC((unsigned char *)lclblitRec, tem, dashPolyPtr->FirstVert,
dashPolyPtr->numPoints, coordModeOrigin, 0, 0);
lclblitRec->blitList = saveBlitList;
goto PDSqCheckDashAdvance;
PDSqCheckAdvance:
/* set the end points for this dash */
if(temDashCnt > 0)
{
dashCount = temDashCnt;
return;
}
PDSqDrawDashAndAdvance:
/* Set the end points for this dash, not either end of line, so
use dash capping */
DoCapPoints(rlistPtr, dashPolyPtr, dashCap, CAP_DASH_END);
saveBlitList = lclblitRec->blitList;
tem = (MAX_RECTS/2) *(sizeof(rect)) + sizeof(blitRcd);
mwFC((unsigned char*)lclblitRec, tem, dashPolyPtr->FirstVert,
dashPolyPtr->numPoints, coordModeOrigin, 0, 0);
lclblitRec->blitList = saveBlitList;
dashPolyPtr->numPoints = 0;
goto PDSqDashAdvance;
PDSqOff:
/* Dash is off; skip rects until either come to end of dash or out or rects */
do{
temp2Rec = (rect *) (rlistPtr);
rlistPtr++;
if((temp2Rec->Xmin == rlistPtr->Xmin) ||
(temp2Rec->Ymin == rlistPtr->Ymin))
{
temDashCnt -= 128;
}
else
{
temDashCnt -= 181;
}
if(--temBlitCnt == 0) goto PDSqCheckDashAdvance;
} while (temDashCnt > 0);
goto PDSqDashAdvance;
PDSqCheckDashAdvance:
if(temDashCnt > 0)
{
dashCount = temDashCnt;
return;
}
PDSqDashAdvance:
/* flip the state and advance the dash pointer */
do{
dashFlags ^= pnDashState;
dashIndex++;
if(dashIndex >= dashElements) dashIndex = 0;
temstart = (dashListStart + dashIndex);
temdashIndex = *temstart;
temDashCnt += temdashIndex << 7;
}while (temDashCnt <= 0);
if((dashFlags & pnDashState) != 0)
{
DoCapPoints(rlistPtr, dashPolyPtr, dashCap, CAP_DASH_START);
}
}while (temBlitCnt != 0);
dashCount = temDashCnt;
return;
}
/* ==================================================================
Adds the two or three points for the specified cap to the polygon for
the dash. */
void DoCapPoints(rect *rlistPtr, dashPoly *dashPolyPtr, int capStl, int capNd)
{
short temlineDir;
short lineFlipTable[8] = {5, 4, 7, 6, 1, 0, 3, 2};
int halfSize, pointNum;
pointNum = dashPolyPtr->numPoints;
temlineDir = lineState.lsLineDir;
if(capNd != CAP_DASH_END) temlineDir = lineFlipTable[temlineDir];
if(lineState.lsErrTermAdjUp == 0)
{
switch(temlineDir)
{
case 0:
case 1: /* CapDown */
if (capStl)
{
halfSize = halfHeightDown;
}
else
{
halfSize = 0;
}
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin + halfWidthRight;
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin + halfSize;
dashPolyPtr->FirstVert[pointNum+1].Y = dashPolyPtr->FirstVert[pointNum].Y;
dashPolyPtr->FirstVert[pointNum+1].X = rlistPtr->Xmin - halfWidthLeft;
dashPolyPtr->numPoints += 2;
return;
case 2:
case 6: /* CapRight */
if (capStl)
{
halfSize = halfWidthRight;
}
else
{
halfSize = 0;
}
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin - halfHeightUp;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin + halfSize;
dashPolyPtr->FirstVert[pointNum+1].X = dashPolyPtr->FirstVert[pointNum].X;
dashPolyPtr->FirstVert[pointNum+1].Y = rlistPtr->Ymin + halfHeightDown;
dashPolyPtr->numPoints += 2;
return;
case 3:
case 7: /* CapLeft */
if (capStl)
{
halfSize = halfWidthLeft;
}
else
{
halfSize = 0;
}
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin + halfHeightDown;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin - halfSize;
dashPolyPtr->FirstVert[pointNum+1].X = dashPolyPtr->FirstVert[pointNum].X;
dashPolyPtr->FirstVert[pointNum+1].Y = rlistPtr->Ymin - halfHeightUp;
dashPolyPtr->numPoints += 2;
return;
case 4:
case 5: /* CapUp */
if (capStl)
{
halfSize = halfHeightUp;
}
else
{
halfSize = 0;
}
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin - halfWidthLeft;
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin - halfSize;
dashPolyPtr->FirstVert[pointNum+1].Y = dashPolyPtr->FirstVert[pointNum].Y;
dashPolyPtr->FirstVert[pointNum+1].X = rlistPtr->Xmin + halfWidthRight;
dashPolyPtr->numPoints += 2;
return;
}
}
else
{
switch(temlineDir)
{
case 0:
case 3: /* CapDownAndLeft */
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin + halfWidthRight;
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin + halfHeightDown;
if (capStl)
{
dashPolyPtr->FirstVert[pointNum+1].Y = dashPolyPtr->FirstVert[pointNum].Y;
pointNum++;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin - halfWidthLeft;
dashPolyPtr->numPoints++;
}
pointNum++;
/* There are two more points in the polygon, the first and the
last point; the point middle was already counted if necessary */
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin - halfHeightUp;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin - halfWidthLeft;
dashPolyPtr->numPoints +=2;
return;
case 1:
case 2: /* CapDownAndRight */
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin - halfHeightUp;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin + halfWidthRight;
if (capStl)
{
dashPolyPtr->FirstVert[pointNum+1].X = dashPolyPtr->FirstVert[pointNum].X;
pointNum++;
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin + halfHeightDown;
dashPolyPtr->numPoints++;
}
pointNum++;
/* There are two more points in the polygon, the first and the
last point; the point middle was already counted if necessary */
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin + halfHeightDown;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin - halfWidthLeft;
dashPolyPtr->numPoints +=2;
return;
case 4:
case 7: /* CapUpAndLeft */
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin + halfHeightDown;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin - halfWidthLeft;
if (capStl)
{
dashPolyPtr->FirstVert[pointNum+1].X = dashPolyPtr->FirstVert[pointNum].X;
pointNum++;
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin - halfHeightUp;
dashPolyPtr->numPoints++;
}
pointNum++;
/* There are two more points in the polygon, the first and the
last point; the point middle was already counted if necessary */
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin - halfHeightUp;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin + halfWidthRight;
dashPolyPtr->numPoints +=2;
return;
case 5:
case 6: /* CapUpAndRight */
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin - halfWidthLeft;
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin - halfHeightUp;
if (capStl)
{
dashPolyPtr->FirstVert[pointNum+1].Y = dashPolyPtr->FirstVert[pointNum].Y;
pointNum++;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin + halfWidthRight;
dashPolyPtr->numPoints++;
}
pointNum++;
/* There are two more points in the polygon, the first and the
last point; the point middle was already counted if necessary */
dashPolyPtr->FirstVert[pointNum].Y = rlistPtr->Ymin + halfHeightDown;
dashPolyPtr->FirstVert[pointNum].X = rlistPtr->Xmin + halfWidthRight;
dashPolyPtr->numPoints += 2;
return;
}
}
}
/* Sets up a local copy of the passed-in blitRcd are related value */
void SetUpCommon(blitRcd *LINEREC)
{
/* Reset the rectangle counter */
rectCnt = LINEREC->blitCnt;
/* Copy the pointer to the line list */
vListPtr = (blitVect *) LINEREC->blitList;
/* Copy blitRcd to working space */
lclblitRec = (blitRcd *) mpWorkSpace;
*lclblitRec = *LINEREC;
/* point to the start of the blitList, we'll fill out with the rects that
make up the line, which is in the stack segment along with the blitRcd */
lclblitRec->blitList = (long ) (mpWorkSpace + sizeof(blitRcd));
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -