📄 xpol7.c
字号:
return(0); /* fail if return */
}
goto PrepareForNext;
}
/* Not a first segment so connect the ends of the last and current edges. */
directionDifference = direction - lastDirection;
if (directionDifference < 0) directionDifference = -directionDifference;
if (directionDifference == 4) /* are the lines in opposite dirs? */
{ /* when the lines are in opposite dirs the far side of the pen
must be filled out unless the lines are horizontal or vertical */
if (!(lastDirection & 1)) goto NormalConnectEdges;
/* if lastDirection < 4, then add two right pen edges; otherwise,
add two left pen edges */
if (lastDirection < 4)
{ /* direction 1-3 */
addStartX = startX + halfWidthRight;
addStartY = startY + halfHeightUp;
addEndX = addStartX;
addEndY = startY + halfHeightDown;
if (addEdgeVector() != 1)
return(0); /* fail if return */
addStartX = startX + halfWidthRight;
addStartY = startY + halfHeightUp;
addEndX = addStartX;
addEndY = startY + halfHeightDown;
if (addEdgeVector() != 1)
return(0); /* fail if return */
}
else
{ /* direction 5-7 */
addStartX = startX + halfWidthLeft;
addStartY = startY + halfHeightDown;
addEndX = addStartX;
addEndY = startY + halfHeightUp;
if (addEdgeVector() != 1)
return(0); /* fail if return */
addStartX = startX + halfWidthLeft;
addStartY = startY + halfHeightDown;
addEndX = addStartX;
addEndY = startY + halfHeightUp;
if (addEdgeVector() != 1)
return(0); /* fail if return */
}
goto PrepareForNext;
}
/* Lines are not opposite so check to see if this is a right angle
unless lines aren't horizontal or vertical. */
if ((!(lastDirection & 1)) && ((directionDifference & 3) == 2))
{ /* Lines are at a right angle so add a square corner so that
for FrameRect, the edges don't change from one scan line to
the next. If the horizontal edge goes right, add a left edge,
otherwise add a right edge */
if (lastDirection < 4)
{ /* direction 1-3 */
addStartX = startX + halfWidthRight;
addStartY = startY + halfHeightUp;
addEndX = addStartX;
addEndY = startY + halfHeightDown;
if (addEdgeVector() != 1)
return(0); /* fail if return */
}
else
{ /* direction 5-7 */
addStartX = startX + halfWidthLeft;
addStartY = startY + halfHeightDown;
addEndX = addStartX;
addEndY = startY + halfHeightUp;
if (addEdgeVector() != 1)
return(0); /* fail if return */
}
goto PrepareForNext;
}
/* Connect lastIn and startOut (if they differ) and startIn and lastOut
(if they differ). */
NormalConnectEdges:
/* MikeM 09/29/99 corrextex y,x comparison to y,y comparison */
/* if ((lastInX != startOutX) || (lastInY != startOutX)) */
if ((lastInX != startOutX) || (lastInY != startOutY))
{ /* connect lastIn and startOut */
addStartX = lastInX;
addStartY = lastInY;
addEndX = startOutX;
addEndY = startOutY;
if (addEdgeVector() != 1)
return(0); /* fail if return */
}
if ((startInX != lastOutX) || (startInY != lastOutY))
{ /* connect startIn and lastOut */
addStartX = startInX;
addStartY = startInY;
addEndX = lastOutX;
addEndY = lastOutY;
if (addEdgeVector() != 1)
return(0); /* fail if return */
}
/* prepare for the next line segment */
PrepareForNext:
startX = endX;
startY = endY;
lastDirection = direction;
lastInX = endInX;
lastInY = endInY;
lastOutX = endOutX;
lastOutY = endOutY;
} while (--lclNpointsparm > 0); /* count down # of points remaining.
The extra point in the loop count is for optionally connecting
the last & first points */
if (firstSegment == 1) /* are we still on the first line segment? */
{ /* yes, so draw the pen around the one point */
addStartX = startX + halfWidthLeft; /* add an upward edge to the left */
addStartY = startY + halfHeightDown;
addEndX = addStartX;
addEndY = startY + halfHeightUp;
if (addEdgeVector() != 1)
{
return(0); /* fail if return */
}
addStartX = startX; /* add a downward edge to the right */
addStartY = startY;
}
else
{ /* no, just close up the last segment */
if ((!(direction & 3)))
{
return(1); /* nothing to do */
}
if (direction > 4)
{ /* direction 5-7 -- add an upward left */
addStartX = endX + halfWidthLeft;
addStartY = endY + halfHeightDown;
addEndX = addStartX;
addEndY = endY + halfHeightUp;
if (addEdgeVector() != 1)
{
return(0); /* fail if return */
}
return(1); /* done */
}
addStartX = endX; /* add a downward edge to the right */
addStartY = endY;
}
addStartX = addStartX + halfWidthRight;
addStartY = addStartY + halfHeightUp;
addEndX = addStartX;
addEndY = startY + halfHeightDown;
if (addEdgeVector() != 1)
{
return(0); /* fail if return */
}
return(1);
}
/* Function mwPolyLine is the X-Windows superset polyline drawer. If the
memory pool is at least as large as STACK_BUFFER_SIZE, the edge tables
are maintained there; otherwise, the edge tables are maintained in a buffer
on the stack. If there's not enough memory to maintain the edge lists,
then the point list must be rescanned frequently, and that's much slower.
Therefore, it behooves the caller to make as much memory available in the
memory pool as possible.
Wide lines are filled as polygons.
pnLoc is updated to the last point connected to.
pointsparm = pointer to array of points that defines the polyline. If the
first and last points aren't the same, they're only joined if
npointsparm < 0. If the first and last points are the same, they're
drawn properly--just once. For wide lines, points where lines
intersect are drawn just once; for thin lines, only common endpoints
are taken care of, and intersection points are drawn multiple times.
npointsparm = # of elements in the points array. If < 0, then the absolute
value is the # of elements, and the first and last points should be
joined.
modeparm = coordModeOrigin (coordinates are absolute) or coordModePrevious
(coordinates after the first are relative to the preceding one).
Note: Important restriction! Currently assumes the pen is square and that
lines are wide! */
void mwPolyLine(point *pointsparm, int npointsparm, int modeparm)
{
int i;
short AddEdgeToGET(void);
if (npointsparm == 0) return; /* nothing to do if no points */
lclModeparm = modeparm; /* local copy of modeparm */
if (grafPort.pnLevel < 0)
{ /* set the new pen location and done. */
/* point to the first vertex (which is always absolute, even in
previous mode) */
if (npointsparm > 0)
{ /* count is positive, so load the last point */
if (modeparm == coordModePrevious) /* previous mode? */
{ /* yes, must add our way through the list to the last point */
finalRawX = pointsparm->X; /* the first point is absolute, */
finalRawY = pointsparm->Y; /* even in previous mode */
pointsparm++;
i = 1;
while (i < npointsparm)
{
finalRawX += pointsparm->X;
finalRawY = pointsparm->Y;
i++;
pointsparm++;
}
}
else
{ /* no, so the last point is absolute so point to the last */
pointsparm += npointsparm - 1; /* point in the list */
finalRawX = pointsparm->X;
finalRawY = pointsparm->Y;
}
}
else
{ /* get first point */
finalRawX = pointsparm->X;
finalRawY = pointsparm->Y;
}
if (globalLevel > 0) /* already in global? */
{ /* convert to global */
U2GP(finalRawX, finalRawY, &finalGblX, &finalGblY, 1);
}
else
{
finalGblX = finalRawX;
finalGblY = finalRawY;
}
LocX = finalGblX; /* update global pen location */
LocY = finalGblY;
grafPort.pnLoc.X = finalRawX; /* update user pen location */
grafPort.pnLoc.Y = finalRawY;
thePort->pnLoc.X = finalRawX;
thePort->pnLoc.Y = finalRawY;
return;
}
clpR = ViewClip; /* copy clip rectangle over */
/* mark whether to connect first & last */
if (npointsparm < 0)
{
finalWrap = 1; /* do connect first & last */
npointsparm = - npointsparm; /* abs(npointsparm) */
}
else
{
finalWrap = 0; /* don't connect first & last */
}
/* set the pen dimensions */
halfWidth[0] = - (grafPort.pnSize.X >> 1); /* round odd down */
halfWidth[1] = ((grafPort.pnSize.X + 1) >> 1); /* round odd up */
halfWidth[2] = - (grafPort.pnSize.Y >> 1); /* round odd down */
halfWidth[3] = ((grafPort.pnSize.Y + 1) >> 1); /* round odd up */
/* decide which buffer to use, stack or memory pool */
buf1Ptr = mpWorkSpace; /* assume using general memory pool */
bufCntr = (long) (mpWorkEnd - buf1Ptr);
if (bufCntr <= STACK_BUFFER_SIZE) /* is the memory pool smaller than */
{ /* the stack buffer? */
bufCntr = STACK_BUFFER_SIZE; /* set up to use the stack buffer */
buf1Ptr = &buf1[0];
}
/* must leave room for at least one rect and a blitRcd - point to last
byte at which an edge can start without overflowing the buffer */
endAvailForGET = ((long) buf1Ptr) + bufCntr - sizeof(blitRcd) - sizeof(rect) -
sizeof(lineEdge);
/* remember where the GET pointer is */
ptrToGETPtr = (lineEdgeV **) (long) buf1Ptr;
*ptrToGETPtr = 0; /* set the GET to empty to start */
buf1Ptr += SIZEOFF * 2; /* point past the GET and AET pointers */
addEdgeVector = &AddEdgeToGET; /* routine called to add each edge to the GET */
/* scan through the vertex list and put all non-0-height edges into the
global edge table, sorted by increasing Y start coordinate */
lclNpointsparm = npointsparm; /* for counting down */
vertexListPtr = pointsparm; /* remember where the first vertex is */
/* try to build the GET from the point list (success depends on whether
enough memory is available) */
if (BuildSquareWidePenPolyLineGET() == 1)
{ /* scan out the global edge table */
bufCntr -= ((long) buf1Ptr - (long) ptrToGETPtr); /* # of bytes left
for blitRcd */
mwScanGET((void **)ptrToGETPtr, (blitRcd *)buf1Ptr, bufCntr, cmplx, 1, 1);
}
else
{ /* There's not enough memory for the GET, two pointers, a blitRcd,
and at least one rect, so we'll have to scan the whole vertex list
each time to maintain the AET. */
lclNpointsparm = npointsparm; /* reset the counter */
vertexListPtr = pointsparm;
updateAETVector = &BuildSquareWidePenPolyLineGET; /* vector used
to update the AET by scanning vertices */
lclFillRule = 1; /* set winding rule fill for ScanOutAET */
__mwSL(); /* scan out the polygon */
}
LocX = finalGblX; /* update global pen location */
LocY = finalGblY;
grafPort.pnLoc.X = finalRawX; /* update user pen location */
grafPort.pnLoc.Y = finalRawY;
thePort->pnLoc.X = finalRawX;
thePort->pnLoc.Y = finalRawY;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -