?? line.c
字號:
if((lCode1 == 0) && (lCode2 == 0))
{
return(1);
}
//
// If the intersection of the codes is non-zero, then the line lies
// entirely off one edge of the clipping region. In this case,
// trivally reject the line.
//
if((lCode1 & lCode2) != 0)
{
return(0);
}
//
// Determine the end of the line to move. The first end of the line is
// moved until it is within the clipping region, and then the second
// end of the line is moved until it is also within the clipping
// region.
//
if(lCode1)
{
lCode = lCode1;
}
else
{
lCode = lCode2;
}
//
// See if this end of the line lies above the clipping region.
//
if(lCode & 1)
{
//
// Move this end of the line to the intersection of the line and
// the top of the clipping region.
//
lX = (*plX1 + (((*plX2 - *plX1) *
(pContext->sClipRegion.sYMin - *plY1)) /
(*plY2 - *plY1)));
lY = pContext->sClipRegion.sYMin;
}
//
// Otherwise, see if this end of the line lies below the clipping
// region.
//
else if(lCode & 2)
{
//
// Move this end of the line to the intersection of the line and
// the bottom of the clipping region.
//
lX = (*plX1 + (((*plX2 - *plX1) *
(pContext->sClipRegion.sYMax - *plY1)) /
(*plY2 - *plY1)));
lY = pContext->sClipRegion.sYMax;
}
//
// Otherwise, see if this end of the line lies to the left of the
// clipping region.
//
else if(lCode & 4)
{
//
// Move this end of the line to the intersection of the line and
// the left side of the clipping region.
//
lX = pContext->sClipRegion.sXMin;
lY = (*plY1 + (((*plY2 - *plY1) *
(pContext->sClipRegion.sXMin - *plX1)) /
(*plX2 - *plX1)));
}
//
// Otherwise, this end of the line lies to the right of the clipping
// region.
//
else
{
//
// Move this end of the line to the intersection of the line and
// the right side of the clipping region.
//
lX = pContext->sClipRegion.sXMax;
lY = (*plY1 + (((*plY2 - *plY1) *
(pContext->sClipRegion.sXMax - *plX1)) /
(*plX2 - *plX1)));
}
//
// See which end of the line just moved.
//
if(lCode1)
{
//
// Save the new coordinates for the start of the line.
//
*plX1 = lX;
*plY1 = lY;
//
// Recompute the clipping code for the start of the line.
//
lCode1 = GrClipCodeGet(pContext, lX, lY);
}
else
{
//
// Save the new coordinates for the end of the line.
//
*plX2 = lX;
*plY2 = lY;
//
// Recompute the clipping code for the end of the line.
//
lCode2 = GrClipCodeGet(pContext, lX, lY);
}
}
}
//*****************************************************************************
//
//! Draws a line.
//!
//! \param pContext is a pointer to the drawing context to use.
//! \param lX1 is the X coordinate of the start of the line.
//! \param lY1 is the Y coordinate of the start of the line.
//! \param lX2 is the X coordinate of the end of the line.
//! \param lY2 is the Y coordinate of the end of the line.
//!
//! This function draws a line, utilizing GrLineDrawH() and GrLineDrawV() to
//! draw the line as efficiently as possible. The line is clipped to the
//! clippping rectangle using the Cohen-Sutherland clipping algorithm, and then
//! scan converted using Bresenham's line drawing algorithm.
//!
//! \return None.
//
//*****************************************************************************
void
GrLineDraw(const tContext *pContext, long lX1, long lY1, long lX2, long lY2)
{
long lError, lDeltaX, lDeltaY, lYStep, bSteep;
//
// Check the arguments.
//
ASSERT(pContext);
//
// See if this is a vertical line.
//
if(lX1 == lX2)
{
//
// It is more efficient to avoid Bresenham's algorithm when drawing a
// vertical line, so use the vertical line routine to draw this line.
//
GrLineDrawV(pContext, lX1, lY1, lY2);
//
// The line has ben drawn, so return.
//
return;
}
//
// See if this is a horizontal line.
//
if(lY1 == lY2)
{
//
// It is more efficient to avoid Bresenham's algorithm when drawing a
// horizontal line, so use the horizontal line routien to draw this
// line.
//
GrLineDrawH(pContext, lX1, lX2, lY1);
//
// The line has ben drawn, so return.
//
return;
}
//
// Clip this line if necessary, and return without drawing anything if the
// line does not cross the clipping region.
//
if(GrLineClip(pContext, &lX1, &lY1, &lX2, &lY2) == 0)
{
return;
}
//
// Determine if the line is steep. A steep line has more motion in the Y
// direction than the X direction.
//
if(((lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2)) >
((lX2 > lX1) ? (lX2 - lX1) : (lX1 - lX2)))
{
bSteep = 1;
}
else
{
bSteep = 0;
}
//
// If the line is steep, then swap the X and Y coordinates.
//
if(bSteep)
{
lError = lX1;
lX1 = lY1;
lY1 = lError;
lError = lX2;
lX2 = lY2;
lY2 = lError;
}
//
// If the starting X coordinate is larger than the ending X coordinate,
// then swap the start and end coordinates.
//
if(lX1 > lX2)
{
lError = lX1;
lX1 = lX2;
lX2 = lError;
lError = lY1;
lY1 = lY2;
lY2 = lError;
}
//
// Compute the difference between the start and end coordinates in each
// axis.
//
lDeltaX = lX2 - lX1;
lDeltaY = (lY2 > lY1) ? (lY2 - lY1) : (lY1 - lY2);
//
// Initialize the error term to negative half the X delta.
//
lError = -lDeltaX / 2;
//
// Determine the direction to step in the Y axis when required.
//
if(lY1 < lY2)
{
lYStep = 1;
}
else
{
lYStep = -1;
}
//
// Loop through all the points along the X axis of the line.
//
for(; lX1 <= lX2; lX1++)
{
//
// See if this is a steep line.
//
if(bSteep)
{
//
// Plot this point of the line, swapping the X and Y coordinates.
//
DpyPixelDraw(pContext->pDisplay, lY1, lX1, pContext->ulForeground);
}
else
{
//
// Plot this point of the line, using the coordinates as is.
//
DpyPixelDraw(pContext->pDisplay, lX1, lY1, pContext->ulForeground);
}
//
// Increment the error term by the Y delta.
//
lError += lDeltaY;
//
// See if the error term is now greater than zero.
//
if(lError > 0)
{
//
// Take a step in the Y axis.
//
lY1 += lYStep;
//
// Decrement the error term by the X delta.
//
lError -= lDeltaX;
}
}
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -