⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lin07.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -