Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1462 lines
96 KiB

/*
** Macros and externs used by genline.c
*/
extern ULONG FASTCALL __fastLineComputeColorRGB4(__GLcontext *gc, __GLcolor *color);
extern ULONG FASTCALL __fastLineComputeColorRGB8(__GLcontext *gc, __GLcolor *color);
extern ULONG FASTCALL __fastLineComputeColorRGB(__GLcontext *gc, __GLcolor *color);
extern ULONG FASTCALL __fastLineComputeColorCI4and8(__GLcontext *gc, __GLcolor *color);
extern ULONG FASTCALL __fastLineComputeColorCI(__GLcontext *gc, __GLcolor *color);
extern void FASTCALL __fastGenLineBegin(__GLcontext *gc);
extern void FASTCALL __fastGenLineEnd(__GLcontext *gc);
extern void FASTCALL __fastGenLine(__GLcontext *gc, __GLvertex *v0,
__GLvertex *v1, GLuint flags);
extern void FASTCALL __fastGenLineWide(__GLcontext *gc, __GLvertex *v0,
__GLvertex *v1, GLuint flags);
BOOL FASTCALL __fastGenLineSetupDisplay(__GLcontext *gc);
void FASTCALL __glQueryLineAcceleration(__GLcontext *gc);
BOOL FASTCALL __glGenSetupEitherLines(__GLcontext *gc);
/*
** float-to-fix macro converts floats to 28.4
*/
#define __FAST_LINE_FLTTOFIX(x) ((long)((x) * 16.0f))
// Converts a floating-point coordinate to an appropriate device coordinate
#ifdef _CLIENTSIDE_
#define __FAST_LINE_FLTTODEV(x) ((long)(x))
#define __FAST_LINE_UNIT_VALUE 1
#else
#define __FAST_LINE_FLTTODEV(x) __FAST_LINE_FLTTOFIX(x)
#define __FAST_LINE_UNIT_VALUE 16
#endif
/*
** line-stroking macros for DIB surfaces
*/
#ifdef NT_NO_BUFFER_INVARIANCE
BOOL FASTCALL __fastGenLineSetupDIB(__GLcontext *gc);
/*
** __FAST_LINE_STROKE_DIB
**
** Strokes a thin solid line into a DIB surface. Performs scissoring.
** Works for 8, 16, and 32 BPP
**
*/
#define __FAST_LINE_STROKE_DIB \
{ \
len = gc->line.options.numPixels; \
fraction = gc->line.options.fraction; \
dfraction = gc->line.options.dfraction; \
\
if (!gc->transform.reasonableViewport) { \
GLint clipX0, clipX1, clipY0, clipY1; \
GLint xStart, yStart, xEnd, yEnd; \
GLint xLittle, yLittle, xBig, yBig; \
GLint highWord, lowWord, bigs, littles; \
\
clipX0 = gc->transform.clipX0; \
clipX1 = gc->transform.clipX1; \
clipY0 = gc->transform.clipY0; \
clipY1 = gc->transform.clipY1; \
\
xBig = gc->line.options.xBig; \
yBig = gc->line.options.yBig; \
\
xStart = gc->line.options.xStart; \
yStart = gc->line.options.yStart; \
\
/* If the start point is in the scissor region, we attempt to \
** trivially accept the line. \
*/ \
if (xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
\
len--; /* Makes our math simpler */ \
/* Trivial accept attempt */ \
xEnd = xStart + xBig * len; \
yEnd = yStart + yBig * len; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
len++; \
goto no_scissor; \
} \
\
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
/* \
** Invert negative minor slopes so we can assume \
** dfraction > 0 \
*/ \
if (dfraction < 0) { \
dfraction = -dfraction; \
fraction = 0x7fffffff - fraction; \
} \
\
/* Now we compute number of littles and bigs in this line */\
\
/* We perform a 16 by 32 bit multiply. Ugh. */ \
highWord = (((GLuint) dfraction) >> 16) * len + \
(((GLuint) fraction) >> 16); \
lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
highWord += (((GLuint) lowWord) >> 16); \
bigs = ((GLuint) highWord) >> 15; \
littles = len - bigs; \
\
/* Second trivial accept attempt */ \
xEnd = xStart + xBig*bigs + xLittle*littles; \
yEnd = yStart + yBig*bigs + yLittle*littles; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
len++; \
goto no_scissor; \
} \
len++; /* Restore len */ \
} else { \
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
} \
\
/* \
** The line needs to be scissored. \
** Well, it should only happen rarely, so we can afford \
** to make it slow. We achieve this by tediously stippling the \
** line. (rather than clipping it, of course, which would be \
** faster but harder). \
*/ \
\
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto scissor_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (wglPixelVisible(x, y) && \
xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
*addr = pixel; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
scissor_no_complex: \
while (--len >= 0) { \
if (xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
*addr = pixel; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} \
} else { \
no_scissor: \
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
GLint xEnd, yEnd, xBig, yBig, xLittle, yLittle; \
\
xBig = gc->line.options.xBig; \
yBig = gc->line.options.yBig; \
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (wglPixelVisible(x, y)) \
*addr = pixel; \
\
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
no_complex: \
while (--len >= 0) { \
*addr = pixel; \
\
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
addr += addrBig; \
} else { \
addr += addrLittle; \
} \
} \
} \
} \
no_draw:; \
}
/*
** __FAST_LINE_STROKE_DIB24
**
** Strokes a thin solid line into a DIB surface. Performs scissoring.
** Works for 24 BPP
**
*/
#define __FAST_LINE_STROKE_DIB24 \
{ \
len = gc->line.options.numPixels; \
fraction = gc->line.options.fraction; \
dfraction = gc->line.options.dfraction; \
\
if (!gc->transform.reasonableViewport) { \
GLint clipX0, clipX1, clipY0, clipY1; \
GLint xStart, yStart, xEnd, yEnd; \
GLint xLittle, yLittle, xBig, yBig; \
GLint highWord, lowWord, bigs, littles; \
\
clipX0 = gc->transform.clipX0; \
clipX1 = gc->transform.clipX1; \
clipY0 = gc->transform.clipY0; \
clipY1 = gc->transform.clipY1; \
\
xBig = gc->line.options.xBig; \
yBig = gc->line.options.yBig; \
\
xStart = gc->line.options.xStart; \
yStart = gc->line.options.yStart; \
\
/* If the start point is in the scissor region, we attempt to \
** trivially accept the line. \
*/ \
if (xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
\
len--; /* Makes our math simpler */ \
/* Trivial accept attempt */ \
xEnd = xStart + xBig * len; \
yEnd = yStart + yBig * len; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
len++; \
goto no_scissor; \
} \
\
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
/* \
** Invert negative minor slopes so we can assume \
** dfraction > 0 \
*/ \
if (dfraction < 0) { \
dfraction = -dfraction; \
fraction = 0x7fffffff - fraction; \
} \
\
/* Now we compute number of littles and bigs in this line */\
\
/* We perform a 16 by 32 bit multiply. Ugh. */ \
highWord = (((GLuint) dfraction) >> 16) * len + \
(((GLuint) fraction) >> 16); \
lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
highWord += (((GLuint) lowWord) >> 16); \
bigs = ((GLuint) highWord) >> 15; \
littles = len - bigs; \
\
/* Second trivial accept attempt */ \
xEnd = xStart + xBig*bigs + xLittle*littles; \
yEnd = yStart + yBig*bigs + yLittle*littles; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
len++; \
goto no_scissor; \
} \
len++; /* Restore len */ \
} else { \
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
} \
\
/* \
** The line needs to be scissored. \
** Well, it should only happen rarely, so we can afford \
** to make it slow. We achieve this by tediously stippling the \
** line. (rather than clipping it, of course, which would be \
** faster but harder). \
*/ \
\
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto scissor_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (wglPixelVisible(x, y) && \
xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
scissor_no_complex: \
while (--len >= 0) { \
if (xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} \
} else { \
no_scissor: \
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
GLint xEnd, yEnd, xBig, yBig, xLittle, yLittle; \
\
xBig = gc->line.options.xBig; \
yBig = gc->line.options.yBig; \
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (wglPixelVisible(x, y)) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
addr += addrBig; \
} else { \
addr += addrLittle; \
} \
} \
} else { \
no_complex: \
while (--len >= 0) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
addr += addrBig; \
} else { \
addr += addrLittle; \
} \
} \
} \
} \
no_draw:; \
}
/*
** __FAST_LINE_STROKE_DIB_WIDE
**
** Strokes a wide solid line into a DIB surface. Performs scissoring.
** Works for 8, 16, and 32 BPP
**
*/
#define __FAST_LINE_STROKE_DIB_WIDE \
{ \
len = gc->line.options.numPixels; \
fraction = gc->line.options.fraction; \
dfraction = gc->line.options.dfraction; \
\
/* \
** Since one or more of the strokes of a wide line may lie outside \
** the viewport, wide lines always go through the scissoring checks \
*/ \
{ \
GLint clipX0, clipX1, clipY0, clipY1; \
GLint xStart, yStart, xEnd, yEnd; \
GLint xLittle, yLittle, xBig, yBig; \
GLint highWord, lowWord, bigs, littles; \
\
clipX0 = gc->transform.clipX0; \
clipX1 = gc->transform.clipX1; \
clipY0 = gc->transform.clipY0; \
clipY1 = gc->transform.clipY1; \
\
xBig = gc->line.options.xBig; \
yBig = gc->line.options.yBig; \
\
xStart = gc->line.options.xStart; \
yStart = gc->line.options.yStart; \
\
/* If the start point is in the scissor region, we attempt to \
** trivially accept the line. \
*/ \
if (xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
\
len--; /* Makes our math simpler */ \
width--; \
/* Trivial accept attempt */ \
xEnd = xStart + xBig * len; \
yEnd = yStart + yBig * len; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
if (((yStart + width) >= clipY0) && \
((yStart + width) < clipY1) && \
((yEnd + width) >= clipY0) && \
((yEnd + width) < clipY1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} else { \
if (((xStart + width) >= clipX0) && \
((xStart + width) < clipX1) && \
((xEnd + width) >= clipX0) && \
((xEnd + width) < clipX1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} \
} \
\
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
/* \
** Invert negative minor slopes so we can assume \
** dfraction > 0 \
*/ \
if (dfraction < 0) { \
dfraction = -dfraction; \
fraction = 0x7fffffff - fraction; \
} \
\
/* Now we compute number of littles and bigs in this line */\
\
/* We perform a 16 by 32 bit multiply. Ugh. */ \
highWord = (((GLuint) dfraction) >> 16) * len + \
(((GLuint) fraction) >> 16); \
lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
highWord += (((GLuint) lowWord) >> 16); \
bigs = ((GLuint) highWord) >> 15; \
littles = len - bigs; \
\
/* Second trivial accept attempt */ \
xEnd = xStart + xBig*bigs + xLittle*littles; \
yEnd = yStart + yBig*bigs + yLittle*littles; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
if (((yStart + width) >= clipY0) && \
((yStart + width) < clipY1) && \
((yEnd + width) >= clipY0) && \
((yEnd + width) < clipY1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} else { \
if (((xStart + width) >= clipX0) && \
((xStart + width) < clipX1) && \
((xEnd + width) >= clipX0) && \
((xEnd + width) < clipX1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} \
} \
len++; /* Restore len and width */ \
width++; \
} else { \
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
} \
\
/* \
** The line needs to be scissored. \
** Well, it should only happen rarely, so we can afford \
** to make it slow. We achieve this by tediously stippling the \
** line. (rather than clipping it, of course, which would be \
** faster but harder). \
*/ \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
GLint yTmp0; \
\
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
GLint yTmp1; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + width; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + width; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto scissor_x_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (xStart >= clipX0 && xStart < clipX1) { \
yTmp0 = yStart; \
yTmp1 = y; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(x, yTmp1) && \
yTmp0 >= clipY0 && yTmp0 < clipY1) { \
*addr = pixel; \
} \
addr += addrMinor; \
yTmp0++; \
yTmp1++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
scissor_x_no_complex: \
while (--len >= 0) { \
if (xStart >= clipX0 && xStart < clipX1) { \
yTmp0 = yStart; \
w = width; \
while (--w >= 0) { \
if (yTmp0 >= clipY0 && yTmp0 < clipY1) { \
*addr = pixel; \
} \
addr += addrMinor; \
yTmp0++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} \
} else { \
GLint xTmp0; \
\
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
GLint xTmp1; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + width; \
} else { \
rcl.left = xEnd; \
rcl.right = x + width; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto scissor_y_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (yStart >= clipY0 && yStart < clipY1) { \
xTmp0 = xStart; \
xTmp1 = x; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(xTmp1, y) && \
xTmp0 >= clipX0 && xTmp0 < clipX1) { \
*addr = pixel; \
} \
addr += addrMinor; \
xTmp0++; \
xTmp1++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
scissor_y_no_complex: \
while (--len >= 0) { \
if (yStart >= clipY0 && yStart < clipY1) { \
xTmp0 = xStart; \
w = width; \
while (--w >= 0) { \
if (xTmp0 >= clipX0 && xTmp0 < clipX1) { \
*addr = pixel; \
} \
addr += addrMinor; \
xTmp0++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} \
} \
goto no_draw; \
no_scissor: \
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
GLint yTmp; \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + width; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + width; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto no_scissor_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
yTmp = y; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(x, yTmp)) { \
*addr = pixel; \
} \
addr += addrMinor; \
yTmp++; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
GLint xTmp; \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + width; \
} else { \
rcl.left = xEnd; \
rcl.right = x + width; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto no_scissor_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
xTmp = x; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(xTmp, y)) { \
*addr = pixel; \
} \
addr += addrMinor; \
xTmp++; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
addr += addrLittle; \
} \
} \
} \
} else { \
no_scissor_no_complex: \
while (--len >= 0) { \
w = width; \
while (--w >= 0) { \
*addr = pixel; \
addr += addrMinor; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
addr += addrBig; \
} else { \
addr += addrLittle; \
} \
} \
} \
} \
no_draw:; \
}
/*
** __FAST_LINE_STROKE_DIB24_WIDE
**
** Strokes a wide solid line into a DIB surface. Performs scissoring.
** Works for 24 BPP
**
*/
#define __FAST_LINE_STROKE_DIB24_WIDE \
{ \
len = gc->line.options.numPixels; \
fraction = gc->line.options.fraction; \
dfraction = gc->line.options.dfraction; \
\
/* \
** Since one or more of the strokes of a wide line may lie outside \
** the viewport, wide lines always go through the scissoring checks \
*/ \
{ \
GLint clipX0, clipX1, clipY0, clipY1; \
GLint xStart, yStart, xEnd, yEnd; \
GLint xLittle, yLittle, xBig, yBig; \
GLint highWord, lowWord, bigs, littles; \
\
clipX0 = gc->transform.clipX0; \
clipX1 = gc->transform.clipX1; \
clipY0 = gc->transform.clipY0; \
clipY1 = gc->transform.clipY1; \
\
xBig = gc->line.options.xBig; \
yBig = gc->line.options.yBig; \
\
xStart = gc->line.options.xStart; \
yStart = gc->line.options.yStart; \
\
/* If the start point is in the scissor region, we attempt to \
** trivially accept the line. \
*/ \
if (xStart >= clipX0 && xStart < clipX1 && \
yStart >= clipY0 && yStart < clipY1) { \
\
len--; /* Makes our math simpler */ \
width--; \
/* Trivial accept attempt */ \
xEnd = xStart + xBig * len; \
yEnd = yStart + yBig * len; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
if (((yStart + width) >= clipY0) && \
((yStart + width) < clipY1) && \
((yEnd + width) >= clipY0) && \
((yEnd + width) < clipY1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} else { \
if (((xStart + width) >= clipX0) && \
((xStart + width) < clipX1) && \
((xEnd + width) >= clipX0) && \
((xEnd + width) < clipX1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} \
} \
\
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
/* \
** Invert negative minor slopes so we can assume \
** dfraction > 0 \
*/ \
if (dfraction < 0) { \
dfraction = -dfraction; \
fraction = 0x7fffffff - fraction; \
} \
\
/* Now we compute number of littles and bigs in this line */\
\
/* We perform a 16 by 32 bit multiply. Ugh. */ \
highWord = (((GLuint) dfraction) >> 16) * len + \
(((GLuint) fraction) >> 16); \
lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
highWord += (((GLuint) lowWord) >> 16); \
bigs = ((GLuint) highWord) >> 15; \
littles = len - bigs; \
\
/* Second trivial accept attempt */ \
xEnd = xStart + xBig*bigs + xLittle*littles; \
yEnd = yStart + yBig*bigs + yLittle*littles; \
if (xEnd >= clipX0 && xEnd < clipX1 && \
yEnd >= clipY0 && yEnd < clipY1) { \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
if (((yStart + width) >= clipY0) && \
((yStart + width) < clipY1) && \
((yEnd + width) >= clipY0) && \
((yEnd + width) < clipY1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} else { \
if (((xStart + width) >= clipX0) && \
((xStart + width) < clipX1) && \
((xEnd + width) >= clipX0) && \
((xEnd + width) < clipX1)) { \
\
len++; \
width++; \
goto no_scissor; \
} \
} \
} \
len++; /* Restore len and width */ \
width++; \
} else { \
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
} \
\
/* \
** The line needs to be scissored. \
** Well, it should only happen rarely, so we can afford \
** to make it slow. We achieve this by tediously stippling the \
** line. (rather than clipping it, of course, which would be \
** faster but harder). \
*/ \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
GLint yTmp0; \
\
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
GLint yTmp1; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + width; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + width; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto scissor_x_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (xStart >= clipX0 && xStart < clipX1) { \
yTmp0 = yStart; \
yTmp1 = y; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(x, yTmp1) && \
yTmp0 >= clipY0 && yTmp0 < clipY1) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
addr += addrMinor; \
yTmp0++; \
yTmp1++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
scissor_x_no_complex: \
while (--len >= 0) { \
if (xStart >= clipX0 && xStart < clipX1) { \
yTmp0 = yStart; \
w = width; \
while (--w >= 0) { \
if (yTmp0 >= clipY0 && yTmp0 < clipY1) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
addr += addrMinor; \
yTmp0++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} \
} else { \
GLint xTmp0; \
\
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
GLint xTmp1; \
\
xEnd = x + xBig * (len - 1); \
yEnd = y + yBig * (len - 1); \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + width; \
} else { \
rcl.left = xEnd; \
rcl.right = x + width; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto scissor_y_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
if (yStart >= clipY0 && yStart < clipY1) { \
xTmp0 = xStart; \
xTmp1 = x; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(xTmp1, y) && \
xTmp0 >= clipX0 && xTmp0 < clipX1) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
addr += addrMinor; \
xTmp0++; \
xTmp1++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
scissor_y_no_complex: \
while (--len >= 0) { \
if (yStart >= clipY0 && yStart < clipY1) { \
xTmp0 = xStart; \
w = width; \
while (--w >= 0) { \
if (xTmp0 >= clipX0 && xTmp0 < clipX1) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
addr += addrMinor; \
xTmp0++; \
} \
} else { \
addr += addrMinor * width; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
xStart += xBig; \
yStart += yBig; \
addr += addrBig; \
} else { \
xStart += xLittle; \
yStart += yLittle; \
addr += addrLittle; \
} \
} \
} \
} \
goto no_draw; \
no_scissor: \
if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
RECTL rcl; \
\
xLittle = gc->line.options.xLittle; \
yLittle = gc->line.options.yLittle; \
\
if (gc->line.options.axis == __GL_X_MAJOR) { \
GLint yTmp; \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + 1; \
} else { \
rcl.left = xEnd; \
rcl.right = x + 1; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + width; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + width; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto no_scissor_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
yTmp = y; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(x, yTmp)) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
addr += addrMinor; \
yTmp++; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
addr += addrLittle; \
} \
} \
} else { \
GLint xTmp; \
\
if (x < xEnd) { \
rcl.left = x; \
rcl.right = xEnd + width; \
} else { \
rcl.left = xEnd; \
rcl.right = x + width; \
} \
if (y < yEnd) { \
rcl.top = y; \
rcl.bottom = yEnd + 1; \
} else { \
rcl.top = yEnd; \
rcl.bottom = y + 1; \
} \
switch (wglRectVisible(&rcl)) { \
case WGL_RECT_ALL: \
goto no_scissor_no_complex; \
break; \
case WGL_RECT_NONE: \
goto no_draw; \
break; \
} \
\
/* Line is partially visible, check each pixel */ \
\
while (--len >= 0) { \
xTmp = x; \
w = width; \
while (--w >= 0) { \
if (wglPixelVisible(xTmp, y)) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
} \
addr += addrMinor; \
xTmp++; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
x += xBig; \
y += yBig; \
addr += addrBig; \
} else { \
x += xLittle; \
y += yLittle; \
addr += addrLittle; \
} \
} \
} \
} else { \
no_scissor_no_complex: \
while (--len >= 0) { \
w = width; \
while (--w >= 0) { \
addr[0] = ir; \
addr[1] = ig; \
addr[2] = ib; \
addr += addrMinor; \
} \
fraction += dfraction; \
if (fraction < 0) { \
fraction &= ~0x80000000; \
addr += addrBig; \
} else { \
addr += addrLittle; \
} \
} \
} \
} \
no_draw:; \
}
#endif // NT_NO_BUFFER_INVARIANCE