Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Source/SR_Rasterizers.c
/****************************************************************************** |
** ** |
** Module: SR_Rasterizers.c ** |
** ** |
** ** |
** Purpose: Sample Renderer rasterizer routines ** |
** ** |
** ** |
** ** |
** Copyright (C) 1996 Apple Computer, Inc. All rights reserved. ** |
** ** |
** ** |
*****************************************************************************/ |
#include "QD3D.h" |
#include "QD3DRenderer.h" |
#include "SR.h" |
#include "SR_Rasterizers.h" |
/****************************************************************************** |
** ** |
** Sample Renderer routines ** |
** ** |
*****************************************************************************/ |
/*===========================================================================*\ |
* |
* Routine: SRLine_Rasterize_32() |
* |
* Comments: 2D line rasterizer for 32-bit color frame buffers. |
* |
\*===========================================================================*/ |
TQ3Status SRLine_Rasterize_32( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3Point3D *pt1, |
const TQ3ColorRGB *lineColorRGB) |
{ |
long rowBytes; |
unsigned long *cBuffer; |
float x0, y0; |
float x1, y1; |
float dx, dy; |
long lx0, ly0; |
long lx1, ly1; |
long dlx, dly; |
long count; |
unsigned long lineColor; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
lineColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
lineColorRGB->r, |
lineColorRGB->g, |
lineColorRGB->b); |
/* Load points in device coordinates */ |
x0 = pt0->x; |
y0 = pt0->y; |
x1 = pt1->x; |
y1 = pt1->y; |
dx = x1 - x0; |
dy = y1 - y0; |
/* Round points to nearest grid location */ |
lx0 = FLOAT_ROUND_TO_LONG_POSITIVE(x0); |
ly0 = FLOAT_ROUND_TO_LONG_POSITIVE(y0); |
lx1 = FLOAT_ROUND_TO_LONG_POSITIVE(x1); |
ly1 = FLOAT_ROUND_TO_LONG_POSITIVE(y1); |
dlx = lx1 - lx0; |
dly = ly1 - ly0; |
/* Separate X-major and Y-major cases */ |
if (ABS(dlx) >= ABS(dly)) { |
long xStep; |
/* X major */ |
if (dx >= 0.0) { |
/* Left to right */ |
xStep = sizeof(long); |
count = lx1 - lx0 + 1; |
} else { |
/* Right to left */ |
xStep = -sizeof(long); |
count = lx0 - lx1 + 1; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned long *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(long))); |
if (ly0 == ly1) { |
/* Special case: horizontal line */ |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
} while (--count); |
} else { |
long fDeltaY; |
long fError; |
long yStep; |
fDeltaY = (long) |
((float)((1 << 24) - 1) * dy / (float) (count - 1)); |
if (fDeltaY >= 0) { |
/* Top to bottom */ |
fError = (long)((y0 - |
(float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = rowBytes; |
} else { |
/* Bottom to top */ |
fDeltaY = -fDeltaY; |
fError = ((1 << 24) - 1) - |
(long)((y0 - (float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = -rowBytes; |
} |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
fError += fDeltaY; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned long *) |
((unsigned char *)cBuffer + yStep); |
} |
} while (--count); |
} |
} else { |
long yStep; |
/* Y major */ |
if (dy >= 0.0) { |
/* Top to bottom */ |
yStep = rowBytes; |
count = ly1 - ly0 + 1; |
} else { |
/* Bottom to top */ |
yStep = -rowBytes; |
count = ly0 - ly1 + 1; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned long *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(long))); |
if (lx0 == lx1) { |
/* Special case: vertical line */ |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + yStep); |
} while (--count); |
} else { |
long fDeltaX; |
long fError; |
long xStep; |
fDeltaX = (long) |
((float)((1 << 24) - 1) * dx / (float) (count - 1)); |
if (fDeltaX >= 0) { |
/* Left to right */ |
fError = (long) |
((x0 - (float)lx0 + 0.5) * (float)((1 << 24) - 1)); |
xStep = sizeof(long); |
} else { |
/* Right to left */ |
fDeltaX = -fDeltaX; |
fError = ((1 << 24) - 1) - |
(long)((x0 - (float)lx0 + 0.5) * (float)((1 << 24) - 1)); |
xStep = -sizeof(long); |
} |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + yStep); |
fError += fDeltaX; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned long *) |
((unsigned char *)cBuffer + xStep); |
} |
} while (--count); |
} |
} |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRLine_Rasterize_32_WClip() |
* |
* Comments: 2D line rasterizer with window clipping for 32-bit color |
* frame buffers. |
* |
\*===========================================================================*/ |
TQ3Status SRLine_Rasterize_32_WClip( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3Point3D *pt1, |
const TQ3ColorRGB *lineColorRGB) |
{ |
unsigned long *cBuffer; |
float x0, y0; |
float x1, y1; |
float dx, dy; |
long lx0, ly0; |
long lx1, ly1; |
long dlx, dly; |
long count; |
unsigned long lineColor; |
long clipX, clipY; |
TQ3Bitmap *clipMask = NULL; |
unsigned long *clipMaskPtr, clipBits, clipXMask; |
unsigned long clipMaskRowBytes; |
float upperLeftX, upperLeftY; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
long rowBytes; |
if (Q3XDrawRegion_GetClipMask(srPrivate->drawRegion, &clipMask) == kQ3Failure) { |
return (kQ3Failure); |
} |
if (clipMask == NULL) { |
return (kQ3Failure); |
} |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
lineColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
lineColorRGB->r, |
lineColorRGB->g, |
lineColorRGB->b); |
/* Load points in device coordinates */ |
x0 = pt0->x; |
y0 = pt0->y; |
x1 = pt1->x; |
y1 = pt1->y; |
dx = x1 - x0; |
dy = y1 - y0; |
/* Set up window clipping values */ |
clipMaskRowBytes = clipMask->rowBytes; |
Q3XDrawRegion_GetDeviceOffsetX(srPrivate->drawRegion, &upperLeftX); |
Q3XDrawRegion_GetDeviceOffsetY(srPrivate->drawRegion, &upperLeftY); |
/* Round points to nearest grid location */ |
lx0 = FLOAT_ROUND_TO_LONG_POSITIVE(x0); |
ly0 = FLOAT_ROUND_TO_LONG_POSITIVE(y0); |
lx1 = FLOAT_ROUND_TO_LONG_POSITIVE(x1); |
ly1 = FLOAT_ROUND_TO_LONG_POSITIVE(y1); |
dlx = lx1 - lx0; |
dly = ly1 - ly0; |
/* Separate X-major and Y-major cases */ |
if (ABS(dlx) >= ABS(dly)) { |
long xStep; |
/* X major */ |
if (dx >= 0.0) { |
/* Left to right */ |
xStep = sizeof(long); |
count = lx1 - lx0 + 1; |
} else { |
/* Right to left */ |
xStep = -sizeof(long); |
count = lx0 - lx1 + 1; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned long *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(long))); |
/* Window clip mask values */ |
clipX = lx0 - upperLeftX; |
clipY = ly0 - upperLeftY; |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMask->image + |
(clipY * clipMaskRowBytes) + ((clipX >> 5) << 2)); |
clipBits = *clipMaskPtr; |
clipXMask = (unsigned long)(1 << (0x1f - (clipX & 0x1f))); |
if (ly0 == ly1) { |
/* Special case: horizonal line */ |
if (xStep > 0 ) { |
/* Left to right */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
clipXMask >>= 1; |
if (clipXMask == 0) { |
clipMaskPtr++; |
clipXMask = (unsigned long)(1 << 0x1f); |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} else { |
/* Right to left */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
clipXMask <<= 1; |
if (clipXMask == 0) { |
clipMaskPtr--; |
clipXMask = 1; |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} |
} else { |
long fDeltaY; |
long fError; |
long yStep; |
long clipYStep; |
fDeltaY = (long)((float)((1 << 24) - 1) * dy / (float) (count - 1)); |
if (fDeltaY >= 0) { |
/* Top to bottom */ |
fError = (long)((y0 - (float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = rowBytes; |
clipYStep = clipMaskRowBytes; |
} else { |
/* Bottom to top */ |
fDeltaY = -fDeltaY; |
fError = ((1 << 24) - 1) - (long)((y0 - (float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = -rowBytes; |
clipYStep = -clipMaskRowBytes; |
} |
if (xStep > 0 ) { |
/* Left to right */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
clipXMask >>= 1; |
if (clipXMask == 0) { |
clipMaskPtr++; |
clipXMask = (unsigned long)(1 << 0x1f); |
clipBits = *clipMaskPtr; |
} |
/* Update color buffer and clip mask pointers by y step */ |
fError += fDeltaY; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} else { |
/* Right to left */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
clipXMask <<= 1; |
if (clipXMask == 0) { |
clipMaskPtr--; |
clipXMask = 1; |
clipBits = *clipMaskPtr; |
} |
/* Update color buffer and clip mask pointers by y step */ |
fError += fDeltaY; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} |
} |
} else { |
long yStep; |
long clipYStep; |
/* Y major */ |
if (dy >= 0.0) { |
/* Top to bottom */ |
yStep = rowBytes; |
count = ly1 - ly0 + 1; |
clipYStep = clipMaskRowBytes; |
} else { |
/* Bottom to top */ |
yStep = -rowBytes; |
count = ly0 - ly1 + 1; |
clipYStep = -clipMaskRowBytes; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned long *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(long))); |
/* Window clip mask values */ |
clipX = lx0 - upperLeftX; |
clipY = ly0 - upperLeftY; |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMask->image + |
(clipY * clipMaskRowBytes) + ((clipX >> 5) << 2)); |
clipXMask = (unsigned long)(1 << (0x1f - (clipX & 0x1f))); |
if (lx0 == lx1) { |
/* Special case: vertical line */ |
do { |
/* Write visible pixels only */ |
if (*clipMaskPtr & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by y step */ |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
} while (--count); |
} else { |
long fDeltaX; |
long fError; |
long xStep; |
fDeltaX = (long)((float)((1 << 24) - 1) * dx / (float) (count - 1)); |
if (fDeltaX >= 0) { |
/* Left to right */ |
fError = (long)((x0 - (float)lx0 + 0.5) * (float)((1 << 24) - 1)); |
xStep = sizeof(long); |
do { |
/* Write visible pixels only */ |
if (*clipMaskPtr & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by y step */ |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
/* Update color buffer and clip mask pointers by x step */ |
fError += fDeltaX; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
clipXMask >>= 1; |
if (clipXMask == 0) { |
clipMaskPtr++; |
clipXMask = (unsigned long)(1 << 0x1f); |
} |
} |
} while (--count); |
} else { |
/* Right to left */ |
fDeltaX = -fDeltaX; |
fError = ((1 << 24) - 1) - (long)((x0 - (float)lx0 + 0.5) * |
(float)((1 << 24) - 1)); |
xStep = -sizeof(long); |
do { |
/* Write visible pixels only */ |
if (*clipMaskPtr & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by y step */ |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
/* Update color buffer and clip mask pointers by x step */ |
fError += fDeltaX; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned long *)((unsigned char *)cBuffer + xStep); |
clipXMask <<= 1; |
if (clipXMask == 0) { |
clipMaskPtr--; |
clipXMask = 1; |
} |
} |
} while (--count); |
} |
} |
} |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRPoint_Rasterize_32() |
* |
* Comments: 2D point rasterizer for 32-bit color frame buffers. |
* |
\*===========================================================================*/ |
TQ3Status SRPoint_Rasterize_32( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3ColorRGB *pointColorRGB) |
{ |
unsigned long *cBuffer; |
unsigned long pointColor; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
long rowBytes; |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
pointColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
pointColorRGB->r, |
pointColorRGB->g, |
pointColorRGB->b); |
cBuffer = (unsigned long *)((unsigned char *)image + |
((FLOAT_ROUND_TO_LONG_POSITIVE(pt0->y) * rowBytes) + |
FLOAT_ROUND_TO_LONG_POSITIVE(pt0->x) * sizeof(long))); |
*cBuffer = pointColor; |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRPoint_Rasterize_32_WClip() |
* |
* Comments: 2D point rasterizer with window clipping for 32-bit color |
* frame buffers. |
* |
\*===========================================================================*/ |
TQ3Status SRPoint_Rasterize_32_WClip( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3ColorRGB *pointColorRGB) |
{ |
long longX, longY; |
float upperLeftX, upperLeftY; |
unsigned long *cBuffer; |
TQ3Bitmap *clipMask = NULL; |
unsigned long *clipMaskPtr, clipBits, clipXMask; |
unsigned long clipMaskRowBytes; |
unsigned long pointColor; |
long rowBytes; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
pointColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
pointColorRGB->r, |
pointColorRGB->g, |
pointColorRGB->b); |
if (Q3XDrawRegion_GetClipMask(srPrivate->drawRegion, &clipMask) == kQ3Failure) { |
return (kQ3Failure); |
} |
if (clipMask == NULL) { |
return (kQ3Failure); |
} |
longX = FLOAT_ROUND_TO_LONG_POSITIVE(pt0->x); |
longY = FLOAT_ROUND_TO_LONG_POSITIVE(pt0->y); |
cBuffer = (unsigned long *)((unsigned char *)image + |
(((long)longY * rowBytes) + (long)longX * sizeof(long))); |
clipMaskRowBytes = clipMask->rowBytes; |
Q3XDrawRegion_GetDeviceOffsetX(srPrivate->drawRegion, &upperLeftX); |
Q3XDrawRegion_GetDeviceOffsetY(srPrivate->drawRegion, &upperLeftY); |
longX -= upperLeftX; |
longY -= upperLeftY; |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMask->image + |
(longY * clipMaskRowBytes) + ((longX >> 5) << 2)); |
clipBits = *clipMaskPtr; |
clipXMask = (unsigned long)(1 << (0x1f - (longX & 0x1f))); |
if (clipBits & clipXMask) { |
*cBuffer = pointColor; |
} |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRLine_Rasterize_8() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRLine_Rasterize_8( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3Point3D *pt1, |
const TQ3ColorRGB *lineColorRGB) |
{ |
unsigned char *cBuffer; |
float x0, y0; |
float x1, y1; |
float dx, dy; |
long lx0, ly0; |
long lx1, ly1; |
long dlx, dly; |
long count; |
unsigned char lineColor; |
long rowBytes; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
lineColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
lineColorRGB->r, |
lineColorRGB->g, |
lineColorRGB->b); |
/* Load points in device coordinates */ |
x0 = pt0->x; |
y0 = pt0->y; |
x1 = pt1->x; |
y1 = pt1->y; |
dx = x1 - x0; |
dy = y1 - y0; |
/* Round points to nearest grid location */ |
lx0 = FLOAT_ROUND_TO_LONG_POSITIVE(x0); |
ly0 = FLOAT_ROUND_TO_LONG_POSITIVE(y0); |
lx1 = FLOAT_ROUND_TO_LONG_POSITIVE(x1); |
ly1 = FLOAT_ROUND_TO_LONG_POSITIVE(y1); |
dlx = lx1 - lx0; |
dly = ly1 - ly0; |
/* Separate X-major and Y-major cases */ |
if (ABS(dlx) >= ABS(dly)) { |
long xStep; |
/* X major */ |
if (dx >= 0.0) { |
/* Left to right */ |
xStep = sizeof(char); |
count = lx1 - lx0 + 1; |
} else { |
/* Right to left */ |
xStep = -sizeof(char); |
count = lx0 - lx1 + 1; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned char *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(char))); |
if (ly0 == ly1) { |
/* Special case: horizonal line */ |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
} while (--count); |
} else { |
long fDeltaY; |
long fError; |
long yStep; |
fDeltaY = (long)((float)((1 << 24) - 1) * dy / (float) (count - 1)); |
if (fDeltaY >= 0) { |
/* Top to bottom */ |
fError = (long)((y0 - (float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = rowBytes; |
} else { |
/* Bottom to top */ |
fDeltaY = -fDeltaY; |
fError = ((1 << 24) - 1) - (long)((y0 - (float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = -rowBytes; |
} |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
fError += fDeltaY; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
} |
} while (--count); |
} |
} else { |
long yStep; |
/* Y major */ |
if (dy >= 0.0) { |
/* Top to bottom */ |
yStep = rowBytes; |
count = ly1 - ly0 + 1; |
} else { |
/* Bottom to top */ |
yStep = -rowBytes; |
count = ly0 - ly1 + 1; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned char *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(char))); |
if (lx0 == lx1) { |
/* Special case: vertical line */ |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
} while (--count); |
} else { |
long fDeltaX; |
long fError; |
long xStep; |
fDeltaX = (long)((float)((1 << 24) - 1) * dx / (float) (count - 1)); |
if (fDeltaX >= 0) { |
/* Left to right */ |
fError = (long)((x0 - (float)lx0 + 0.5) * (float)((1 << 24) - 1)); |
xStep = sizeof(char); |
} else { |
/* Right to left */ |
fDeltaX = -fDeltaX; |
fError = ((1 << 24) - 1) - (long)((x0 - (float)lx0 + 0.5) * (float)((1 << 24) - 1)); |
xStep = -sizeof(char); |
} |
do { |
*cBuffer = lineColor; |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
fError += fDeltaX; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
} |
} while (--count); |
} |
} |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRLine_Rasterize_8_WClip() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRLine_Rasterize_8_WClip( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3Point3D *pt1, |
const TQ3ColorRGB *lineColorRGB) |
{ |
unsigned char *cBuffer; |
float x0, y0; |
float x1, y1; |
float dx, dy; |
long lx0, ly0; |
long lx1, ly1; |
long dlx, dly; |
long count; |
unsigned char lineColor; |
long clipX, clipY; |
TQ3Bitmap *clipMask = NULL; |
unsigned long *clipMaskPtr, clipBits, clipXMask; |
unsigned long clipMaskRowBytes; |
float upperLeftX, upperLeftY; |
long rowBytes; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
if (Q3XDrawRegion_GetClipMask(srPrivate->drawRegion, &clipMask) == kQ3Failure) { |
return (kQ3Failure); |
} |
if (clipMask == NULL) { |
return (kQ3Failure); |
} |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
lineColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
lineColorRGB->r, |
lineColorRGB->g, |
lineColorRGB->b); |
/* Load points in device coordinates */ |
x0 = pt0->x; |
y0 = pt0->y; |
x1 = pt1->x; |
y1 = pt1->y; |
dx = x1 - x0; |
dy = y1 - y0; |
/* Set up window clipping values */ |
clipMaskRowBytes = clipMask->rowBytes; |
Q3XDrawRegion_GetDeviceOffsetX(srPrivate->drawRegion, &upperLeftX); |
Q3XDrawRegion_GetDeviceOffsetY(srPrivate->drawRegion, &upperLeftY); |
/* Round points to nearest grid location */ |
lx0 = FLOAT_ROUND_TO_LONG_POSITIVE(x0); |
ly0 = FLOAT_ROUND_TO_LONG_POSITIVE(y0); |
lx1 = FLOAT_ROUND_TO_LONG_POSITIVE(x1); |
ly1 = FLOAT_ROUND_TO_LONG_POSITIVE(y1); |
dlx = lx1 - lx0; |
dly = ly1 - ly0; |
/* Separate X-major and Y-major cases */ |
if (ABS(dlx) >= ABS(dly)) { |
long xStep; |
/* X major */ |
if (dx >= 0.0) { |
/* Left to right */ |
xStep = sizeof(char); |
count = lx1 - lx0 + 1; |
} else { |
/* Right to left */ |
xStep = -sizeof(char); |
count = lx0 - lx1 + 1; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned char *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(char))); |
/* Window clip mask values */ |
clipX = lx0 - upperLeftX; |
clipY = ly0 - upperLeftY; |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMask->image + |
(clipY * clipMaskRowBytes) + ((clipX >> 5) << 2)); |
clipBits = *clipMaskPtr; |
clipXMask = (unsigned long)(1 << (0x1f - (clipX & 0x1f))); |
if (ly0 == ly1) { |
/* Special case: horizonal line */ |
if (xStep > 0 ) { |
/* Left to right */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
clipXMask >>= 1; |
if (clipXMask == 0) { |
clipMaskPtr++; |
clipXMask = (unsigned long)(1 << 0x1f); |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} else { |
/* Right to left */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
clipXMask <<= 1; |
if (clipXMask == 0) { |
clipMaskPtr--; |
clipXMask = 1; |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} |
} else { |
long fDeltaY; |
long fError; |
long yStep; |
long clipYStep; |
fDeltaY = (long)((float)((1 << 24) - 1) * dy / (float) (count - 1)); |
if (fDeltaY >= 0) { |
/* Top to bottom */ |
fError = (long)((y0 - (float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = rowBytes; |
clipYStep = clipMaskRowBytes; |
} else { |
/* Bottom to top */ |
fDeltaY = -fDeltaY; |
fError = ((1 << 24) - 1) - (long)((y0 - (float)ly0 + 0.5) * (float)((1 << 24) - 1)); |
yStep = -rowBytes; |
clipYStep = -clipMaskRowBytes; |
} |
if (xStep > 0 ) { |
/* Left to right */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
clipXMask >>= 1; |
if (clipXMask == 0) { |
clipMaskPtr++; |
clipXMask = (unsigned long)(1 << 0x1f); |
clipBits = *clipMaskPtr; |
} |
/* Update color buffer and clip mask pointers by y step */ |
fError += fDeltaY; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} else { |
/* Right to left */ |
do { |
/* Write visible pixels only */ |
if (clipBits & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by x step */ |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
clipXMask <<= 1; |
if (clipXMask == 0) { |
clipMaskPtr--; |
clipXMask = 1; |
clipBits = *clipMaskPtr; |
} |
/* Update color buffer and clip mask pointers by y step */ |
fError += fDeltaY; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
clipBits = *clipMaskPtr; |
} |
} while (--count); |
} |
} |
} else { |
long yStep; |
long clipYStep; |
/* Y major */ |
if (dy >= 0.0) { |
/* Top to bottom */ |
yStep = rowBytes; |
count = ly1 - ly0 + 1; |
clipYStep = clipMaskRowBytes; |
} else { |
/* Bottom to top */ |
yStep = -rowBytes; |
count = ly0 - ly1 + 1; |
clipYStep = -clipMaskRowBytes; |
} |
/* Color buffer address of (lx0, ly0) */ |
cBuffer = (unsigned char *)((unsigned char *)image + |
((ly0 * rowBytes) + lx0 * sizeof(char))); |
/* Window clip mask values */ |
clipX = lx0 - upperLeftX; |
clipY = ly0 - upperLeftY; |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMask->image + |
(clipY * clipMaskRowBytes) + ((clipX >> 5) << 2)); |
clipXMask = (unsigned long)(1 << (0x1f - (clipX & 0x1f))); |
if (lx0 == lx1) { |
/* Special case: vertical line */ |
do { |
/* Write visible pixels only */ |
if (*clipMaskPtr & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by y step */ |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
} while (--count); |
} else { |
long fDeltaX; |
long fError; |
long xStep; |
fDeltaX = (long)((float)((1 << 24) - 1) * dx / (float) (count - 1)); |
if (fDeltaX >= 0) { |
/* Left to right */ |
fError = (long)((x0 - (float)lx0 + 0.5) * (float)((1 << 24) - 1)); |
xStep = sizeof(char); |
do { |
/* Write visible pixels only */ |
if (*clipMaskPtr & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by y step */ |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
/* Update color buffer and clip mask pointers by x step */ |
fError += fDeltaX; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
clipXMask >>= 1; |
if (clipXMask == 0) { |
clipMaskPtr++; |
clipXMask = (unsigned long)(1 << 0x1f); |
} |
} |
} while (--count); |
} else { |
/* Right to left */ |
fDeltaX = -fDeltaX; |
fError = ((1 << 24) - 1) - (long)((x0 - (float)lx0 + 0.5) * (float)((1 << 24) - 1)); |
xStep = -sizeof(char); |
do { |
/* Write visible pixels only */ |
if (*clipMaskPtr & clipXMask) { |
*cBuffer = lineColor; |
} |
/* Update color buffer and clip mask pointers by y step */ |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + yStep); |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMaskPtr + clipYStep); |
/* Update color buffer and clip mask pointers by x step */ |
fError += fDeltaX; |
if (fError >= (1 << 24)) { |
fError = fError - (1 << 24); |
cBuffer = (unsigned char *)((unsigned char *)cBuffer + xStep); |
clipXMask <<= 1; |
if (clipXMask == 0) { |
clipMaskPtr--; |
clipXMask = 1; |
} |
} |
} while (--count); |
} |
} |
} |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRPoint_Rasterize_8() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRPoint_Rasterize_8( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3ColorRGB *pointColorRGB) |
{ |
unsigned char *cBuffer; |
unsigned char pointColor; |
long rowBytes; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
pointColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
pointColorRGB->r, |
pointColorRGB->g, |
pointColorRGB->b); |
cBuffer = (unsigned char *)((unsigned char *)image + |
((FLOAT_ROUND_TO_LONG_POSITIVE(pt0->y) * rowBytes) + |
FLOAT_ROUND_TO_LONG_POSITIVE(pt0->x) * sizeof(char))); |
*cBuffer = (unsigned char)pointColor; |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRPoint_Rasterize_8_WClip() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRPoint_Rasterize_8_WClip( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3ColorRGB *pointColorRGB) |
{ |
long longX, longY; |
float upperLeftX, upperLeftY; |
unsigned char *cBuffer; |
TQ3Bitmap *clipMask = NULL; |
unsigned long *clipMaskPtr, clipBits, clipXMask; |
unsigned long clipMaskRowBytes; |
unsigned char pointColor; |
long rowBytes; |
const TQ3XDrawRegionDescriptor *descriptor; |
void *image; |
if (Q3XDrawRegion_GetClipMask(srPrivate->drawRegion, &clipMask) == kQ3Failure) { |
return (kQ3Failure); |
} |
if (clipMask == NULL) { |
return (kQ3Failure); |
} |
descriptor = srPrivate->descriptor; |
image = srPrivate->image; |
rowBytes = descriptor->rowBytes; |
COLOR_TO_PIXEL( |
pointColor, |
srPrivate->drawRegion, |
descriptor->pixelType, |
pointColorRGB->r, |
pointColorRGB->g, |
pointColorRGB->b); |
longX = FLOAT_ROUND_TO_LONG_POSITIVE(pt0->x); |
longY = FLOAT_ROUND_TO_LONG_POSITIVE(pt0->y); |
cBuffer = (unsigned char *)((unsigned char *)image + |
(((long)longY * rowBytes) + (long)longX * sizeof(char))); |
clipMaskRowBytes = clipMask->rowBytes; |
Q3XDrawRegion_GetDeviceOffsetX(srPrivate->drawRegion, &upperLeftX); |
Q3XDrawRegion_GetDeviceOffsetY(srPrivate->drawRegion, &upperLeftY); |
longX -= upperLeftX; |
longY -= upperLeftY; |
clipMaskPtr = (unsigned long *)((unsigned char *)clipMask->image + |
(longY * clipMaskRowBytes) + ((longX >> 5) << 2)); |
clipBits = *clipMaskPtr; |
clipXMask = (unsigned long)(1 << (0x1F - (longX & 0x1F))); |
if (clipBits & clipXMask) { |
*cBuffer = (unsigned char)pointColor; |
} |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRLine_Rasterize_Null() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRLine_Rasterize_Null( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3Point3D *pt1, |
const TQ3ColorRGB *lineColorRGB) |
{ |
UNUSED(srPrivate); |
UNUSED(pt0); |
UNUSED(pt1); |
UNUSED(lineColorRGB); |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRPoint_Rasterize_Null() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRPoint_Rasterize_Null( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TQ3ColorRGB *pointColorRGB) |
{ |
UNUSED(srPrivate); |
UNUSED(pt0); |
UNUSED(pointColorRGB); |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRMarker_Rasterize_Null() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRMarker_Rasterize_Null( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TSRMarkerRasterData *bitmap, |
const TQ3ColorRGB *pointColorRGB) |
{ |
UNUSED(srPrivate); |
UNUSED(pt0); |
UNUSED(bitmap); |
UNUSED(pointColorRGB); |
return (kQ3Success); |
} |
/*===========================================================================*\ |
* |
* Routine: SRPixmapMarker_Rasterize_Null() |
* |
* Comments: |
* |
\*===========================================================================*/ |
TQ3Status SRPixmapMarker_Rasterize_Null( |
const struct TSRPrivate *srPrivate, |
const TQ3Point3D *pt0, |
const TSRPixmapMarkerRasterData *pixmap, |
const TQ3ColorRGB *highlightColor) |
{ |
UNUSED(srPrivate); |
UNUSED(pt0); |
UNUSED(pixmap); |
UNUSED(highlightColor); |
return (kQ3Success); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14