📄 lin07.c
字号:
/* l->r, t->b Xmajor */
case 2:
check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
if(check > 0x7FFF)
{
lineState.lsDYmin++;
check -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) check;
lineState.lsDXmin++;
lineState.lsMajorAxisLengthM1--;
break;
/* r->l, t->b Xmajor */
case 3:
check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
if(check > 0x7FFF)
{
lineState.lsDYmin++;
check -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) check;
lineState.lsDXmin--;
lineState.lsMajorAxisLengthM1--;
break;
/* r->l, b->t Ymojor */
case 4:
check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
if(check > 0x7FFF)
{
lineState.lsDXmin--;
check -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) check;
lineState.lsDYmin--;
lineState.lsMajorAxisLengthM1--;
break;
/* l->r, b->t Ymajor */
case 5:
lineState.lsDYmin--;
check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
if(check > 0x7FFF)
{
lineState.lsDXmin++;
check -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) check;
lineState.lsMajorAxisLengthM1--;
break;
/* l->r, b->t Xmajor */
case 6:
check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
if(check > 0x7FFF)
{
lineState.lsDYmin--;
check -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) check;
lineState.lsDXmin++;
lineState.lsMajorAxisLengthM1--;
break;
/* r->l, b->t Xmajor */
case 7:
check = lineState.lsErrTerm + lineState.lsErrTermAdjUp;
if(check > 0x7FFF)
{
lineState.lsDYmin--;
check -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) check;
lineState.lsDXmin--;
lineState.lsMajorAxisLengthM1--;
break;
}
}
if(lineState.lsSkipStat > 0)
/* BobB 3/10/99 - corrected the following line
lineState.lsMajorAxisLengthM1 = (short) deltaX; */
lineState.lsMajorAxisLengthM1--;
return(0);
}
/*======================================================================
Routine to scan out as much as possible of a line into a rect list in a
blitRcd. Performs all clipping, and saves the state in a lineState
structure for restarting, if necessary. Line is fully scanned if the
lsMajorAxisLengthM1 field is < 0.
Only generates lsMaxRects-1 as the maximum blitCnt; an additional rect is
placed at the end of every burst (so there are blitCnt+1 rects in the
blitList), but isn't counted in blitCnt; this is to allow for proper angle
correction on the last pixel in dash handling. */
void _mwLL(void)
{
rect *rlistPtr;
short temX,temY,tem;
long error;
tem = lineState.lsMajorAxisLengthM1 + 1;
if(tem >= lineState.lsMaxRects) tem = lineState.lsMaxRects - 1;
/* Set the # of rects for the filler to drawer after we generate them */
lclblitRec->blitCnt = tem;
/* # of points - 1 for next time */
lineState.lsMajorAxisLengthM1 -= tem;
rlistPtr = (rect *) lclblitRec->blitList;
/* point to the location at which to store the first pixels rect */
switch(lineState.lsLineDir)
{
/**/case 0:
temX = lineState.lsDXmin + 1;
temY = lineState.lsDYmin;
error = lineState.lsErrTerm;
while(tem-- > 0)
{
rlistPtr->Xmax = temX--;
rlistPtr->Ymin = temY++;
rlistPtr->Xmin = temX;
rlistPtr->Ymax = temY;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temX++;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
lineState.lsDYmin = temY;
rlistPtr->Xmax = temX--;
rlistPtr->Ymin = temY++;
rlistPtr->Xmin = temX;
rlistPtr->Ymax = temY;
lineState.lsDXmin = temX;
return;
/**/case 1:
temX = lineState.lsDXmin;
temY = lineState.lsDYmin;
error = lineState.lsErrTerm;
while(tem-- >0)
{
rlistPtr->Xmin = temX++;
rlistPtr->Ymin = temY++;
rlistPtr->Xmax = temX;
rlistPtr->Ymax = temY;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temX--;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
lineState.lsDXmin = temX;
lineState.lsDYmin = temY;
rlistPtr->Xmin = temX++;
rlistPtr->Ymin = temY++;
rlistPtr->Xmax = temX;
rlistPtr->Ymax = temY;
return;
/**/case 2:
temX = lineState.lsDXmin;
temY = lineState.lsDYmin;
error = lineState.lsErrTerm;
while(tem-- > 0)
{
rlistPtr->Xmin = temX++;
rlistPtr->Ymin = temY++;
rlistPtr->Xmax = temX;
rlistPtr->Ymax = temY;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temY--;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
lineState.lsDXmin = temX;
lineState.lsDYmin = temY;
rlistPtr->Xmin = temX++;
rlistPtr->Ymin = temY++;
rlistPtr->Xmax = temX;
rlistPtr->Ymax = temY;
return;
/**/case 3:
temX = lineState.lsDXmin + 1;
temY = lineState.lsDYmin;
error = lineState.lsErrTerm;
while(tem-- >0)
{
rlistPtr->Xmax = temX--;
rlistPtr->Ymin = temY++;
rlistPtr->Xmin = temX;
rlistPtr->Ymax = temY;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temY--;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
lineState.lsDYmin = temY;
rlistPtr->Xmax = temX--;
rlistPtr->Ymin = temY++;
rlistPtr->Xmin = temX;
rlistPtr->Ymax = temY;
lineState.lsDXmin = temX;
return;
/**/case 4:
temX = lineState.lsDXmin + 1;
temY = lineState.lsDYmin + 1;
error = lineState.lsErrTerm;
while(tem-- > 0)
{
rlistPtr->Xmax = temX--;
rlistPtr->Ymax = temY--;
rlistPtr->Ymin = temY;
rlistPtr->Xmin = temX;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temX++;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
rlistPtr->Ymax = temY--;
rlistPtr->Xmax = temX--;
rlistPtr->Xmin = temX;
rlistPtr->Ymin = temY;
lineState.lsDXmin = temX;
lineState.lsDYmin = temY;
return;
/**/case 5:
temX = lineState.lsDXmin;
temY = lineState.lsDYmin + 1;
error = lineState.lsErrTerm;
while(tem-- > 0)
{
rlistPtr->Xmin = temX++;
rlistPtr->Ymax = temY--;
rlistPtr->Xmax = temX;
rlistPtr->Ymin = temY;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temX--;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
lineState.lsDXmin = temX;
rlistPtr->Xmin = temX++;
rlistPtr->Ymax = temY--;
rlistPtr->Xmax = temX;
rlistPtr->Ymin = temY;
lineState.lsDYmin = temY;
return;
/**/case 6:
temX = lineState.lsDXmin;
temY = lineState.lsDYmin + 1;
error = lineState.lsErrTerm;
while(tem-- > 0)
{
rlistPtr->Xmin = temX++;
rlistPtr->Ymax = temY--;
rlistPtr->Ymin = temY;
rlistPtr->Xmax = temX;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temY++;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
lineState.lsDXmin = temX;
rlistPtr->Xmin = temX++;
rlistPtr->Ymax = temY--;
rlistPtr->Ymin = temY;
rlistPtr->Xmax = temX;
lineState.lsDYmin = temY;
return;
/**/case 7:
temX = lineState.lsDXmin + 1;
temY = lineState.lsDYmin + 1;
error = lineState.lsErrTerm;
while(tem-- >0)
{
rlistPtr->Xmax = temX--;
rlistPtr->Ymax = temY--;
rlistPtr->Xmin = temX;
rlistPtr->Ymin = temY;
rlistPtr++;
error += lineState.lsErrTermAdjUp;
if(error < 0)
temY++;
else
error -= lineState.lsErrTermAdjDown;
}
lineState.lsErrTerm = (short) error;
rlistPtr->Xmax = temY--;
rlistPtr->Ymax = temX--;
rlistPtr->Xmin = temX;
rlistPtr->Ymin = temY;
lineState.lsDYmin = temY;
lineState.lsDXmin = temX;
return;
}
return;
}
/*=================================================================*/
/*** mwLID subroutine for dash thin line drawing ***/
void mwLID(blitRcd *LINEREC)
{
void SetUpCommon(blitRcd *LINEREC);
long temcount;
short temindex;
byte *temlist;
rect *rlistPtr;
/* BobB 3/10/99 - added the following variable */
int lclRectCnt;
workingPnPat = grafPort.pnPat; /* Foreground pattern */
workingBkPat = grafPort.bkPat; /* Background pattern */
dashFlags = grafPort.pnFlags; /* dash style and current state */
temcount = grafPort.pnDashCnt << 7;
temindex = grafPort.pnDashNdx;
dashElements = grafPort.pnDashRcd[grafPort.pnDash].dashSize;
dashListStart = (byte *) grafPort.pnDashRcd[grafPort.pnDash].dashList;
temlist = dashListStart; /* use to move along the dash list */
/* If dashCount is 0, then dashCount is initialized to the first entry
in the dash list, dashIndex is forced to the index of the first non-
zero-length dash, and the dash state is set to the first non-zero-
length dash's state; that is, the dash sequence is restarted. An
infinite loop will result if all dash lengths are 0! */
if(grafPort.pnDashCnt <= 0)
{/* Is it a zero count, so reinitialize the dash sequence */
temcount = 1;
temindex = -1;
dashFlags &= ~pnDashState;
do{
dashFlags ^= pnDashState;
temindex++;
temcount = (*temlist++) << 7;
}while(temcount == 0);
}
dashCount = temcount;
dashIndex = temindex;
SetUpCommon(LINEREC);
/* Check for square pen wide line */
if(dashFlags & pnSizeFlg)
{
HandleWideSq();
return;
}
/* Check for double dash line */
if(dashFlags & pnDashStyle)
{
DoubleDash();
return;
}
/* on-off line */
lineState.lsMaxRects = MAX_RECTS;
/* Main on-off line-drawing loop */
/* BobB 3/10/99 - corrected the following line for count
while(rectCnt-- > 0) */
lclRectCnt = rectCnt;
while(lclRectCnt-- > 0)
{
/* Set up the line state for this line. */
/* BobB 2/18/99 - corrected lsSkipStat type
lineState.lsSkipStat = (byte) vListPtr->skipStat; */
lineState.lsSkipStat = (signed char) vListPtr->skipStat;
rlistPtr = (rect *) ((long) vListPtr++);
if(_mwLLSetup(rlistPtr)) continue;
do{
_mwLL();
rlistPtr = (rect *) lclblitRec->blitList;
ProcessDashes(rlistPtr);
/* Call the filler to draw this chunk of the line */
lclblitRec->blitDmap->prFill(lclblitRec);
}while(lineState.lsMajorAxisLengthM1 >= 0);
}
grafPort.pnDashNdx = dashIndex;
thePort->pnDashNdx = dashIndex;
grafPort.pnDashCnt = (short) dashCount >> 7;
thePort->pnDashCnt = grafPort.pnDashCnt;
grafPort.pnFlags = dashFlags;
thePort->pnFlags = dashFlags;
return;
}
void DoubleDash(void)
{
rect *rlistPtr;
int saveBlitCnt;
int saveDashIndex;
long saveDashCount;
int saveDashFlags;
/* BobB 4/23/99 - corrected dashed line rect count */
int lRectCnt;
lRectCnt = rectCnt;
/* Remember where the blitList area */
blitListPtr = lclblitRec->blitList;
/* store dash-filtered rects */
secondListPtr = blitListPtr + (MAX_RECTS/2)*sizeof(rect);
/* can only use half area for the blit list, the other
half is for pre-filtered rects */
lineState.lsMaxRects = MAX_RECTS/2;
/* Main 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 */
/* BobB 2/18/99 - corrected lsSkipStat type
lineState.lsSkipStat = (byte) vListPtr->skipStat; */
lineState.lsSkipStat = (signed char) vListPtr->skipStat;
rlistPtr = (rect *) ((long) vListPtr++);
if(_mwLLSetup(rlistPtr)) continue;
do{
lclblitRec->blitList = blitListPtr;
_mwLL();
/* go back to where we put dash-filtered rects */
lclblitRec->blitList = secondListPtr;
saveBlitCnt = lclblitRec->blitCnt;
saveDashIndex = dashIndex;
saveDashCount = dashCount;
saveDashFlags = dashFlags;
rlistPtr = (rect *) blitListPtr;
ProcessDashes(rlistPtr);
/* Call the filler to draw the foreground dashes in this
chunk of the line */
lclblitRec->blitDmap->prFill(lclblitRec);
lclblitRec->blitCnt = saveBlitCnt;
dashIndex = saveDashIndex;
dashCount = saveDashCount;
dashFlags = saveDashFlags;
lclblitRec->blitPat = workingBkPat;
dashFlags ^= pnDashState;
rlistPtr = (rect *) blitListPtr;
ProcessDashes(rlistPtr);
/* Call the filler to draw the background dashes in this
chunk of the line */
lclblitRec->blitDmap->prFill(lclblitRec);
/* Flip the pen back to normal */
dashFlags ^= pnDashState;
lclblitRec->blitPat = workingPnPat; /* Restore foreground */
}while(lineState.lsMajorAxisLengthM1 >= 0);
}
return;
}
/* Wide dashed line handler. Assumes square pen */
void HandleWideSq(void)
{
int saveBlitCnt;
int saveDashIndex;
long saveDashCount;
int saveDashFlags;
rect *rlistPtr;
/* BobB 4/23/99 - corrected dashed line rect count */
int lRectCnt;
lRectCnt = rectCnt;
lclblitRec->blitList = lclblitRec->blitList + (MAX_RECTS/2)*sizeof(rect);
/* use half of buffer size since using other half for mwFC */
lineState.lsMaxRects = MAX_RECTS /2;
/* Setup pen half width */
halfHeightUp = grafPort.pnSize.Y >> 1; /* Round odd up and down */
halfHeightDown = (grafPort.pnSize.Y + 1) >> 1;
halfWidthLeft = grafPort.pnSize.X >> 1; /* Round odd left and right */
halfWidthRight = (grafPort.pnSize.X + 1) >> 1;
/* It is possible to support capFlat as well by copying from
grafPort.pnCap, but since LineTo and especially mwPolyLine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -