Code: Select all

```
/**********************************************************************************************/
wxColour GetColorAverage( wxColour color1, wxColour color2, float weight)
{
unsigned char r, g, b;
r = (unsigned char)( 1.0 * color1.Red() * weight + 1.0 * color2.Red() * ( 1 - weight) );
g = (unsigned char)( 1.0 * color1.Green() * weight + 1.0 * color2.Green() * ( 1 - weight) );
b = (unsigned char)(1.0 * color1.Blue() * weight + 1.0 * color2.Blue() * ( 1 - weight) );
return wxColour(r, g, b);
}
/**********************************************************************************************/
void DrawWuLine( wxDC *pDC, short X0, short Y0, short X1, short Y1 )
{
wxASSERT( pDC );
if( !pDC )
return;
wxColour cl = pDC->GetPen().GetColour();
wxColour clb = pDC->GetBrush().GetColour();
unsigned short IntensityShift, ErrorAdj, ErrorAcc;
unsigned short ErrorAccTemp, Weighting, WeightingComplementMask;
short DeltaX, DeltaY, Temp, XDir;
/* Make sure the line runs top to bottom */
if (Y0 > Y1) {
Temp = Y0; Y0 = Y1; Y1 = Temp;
Temp = X0; X0 = X1; X1 = Temp;
}
/* Draw the initial pixel, which is always exactly intersected by
the line and so needs no weighting */
pDC->SetPen( cl );
pDC->DrawPoint( X0, Y0 );
if ((DeltaX = X1 - X0) >= 0) {
XDir = 1;
} else {
XDir = -1;
DeltaX = -DeltaX; /* make DeltaX positive */
}
/* Special-case horizontal, vertical, and diagonal lines, which
require no weighting because they go right through the center of
every pixel */
if ((DeltaY = Y1 - Y0) == 0) {
/* Horizontal line */
while (DeltaX-- != 0) {
X0 += XDir;
pDC->DrawPoint( X0, Y0 );
}
return;
}
if (DeltaX == 0) {
/* Vertical line */
do {
Y0++;
pDC->DrawPoint( X0, Y0 );
} while (--DeltaY != 0);
return;
}
if (DeltaX == DeltaY) {
/* Diagonal line */
do {
X0 += XDir;
Y0++;
pDC->DrawPoint( X0, Y0 );
} while (--DeltaY != 0);
return;
}
/* Line is not horizontal, diagonal, or vertical */
ErrorAcc = 0; /* initialize the line error accumulator to 0 */
/* # of bits by which to shift ErrorAcc to get intensity level */
IntensityShift = 8;
/* Mask used to flip all bits in an intensity weighting, producing the
result (1 - intensity weighting) */
WeightingComplementMask = 255;
/* Is this an X-major or Y-major line? */
if (DeltaY > DeltaX) {
/* Y-major line; calculate 16-bit fixed-point fractional part of a
pixel that X advances each time Y advances 1 pixel, truncating the
result so that we won't overrun the endpoint along the X axis */
ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY;
/* Draw all pixels other than the first and last */
while (--DeltaY) {
ErrorAccTemp = ErrorAcc; /* remember current accumulated error */
ErrorAcc += ErrorAdj; /* calculate error for next pixel */
if (ErrorAcc <= ErrorAccTemp) {
/* The error accumulator turned over, so advance the X coord */
X0 += XDir;
}
Y0++; /* Y-major, so always advance Y */
/* The IntensityBits most significant bits of ErrorAcc give us the
intensity weighting for this pixel, and the complement of the
weighting for the paired pixel */
Weighting = ErrorAcc >> IntensityShift;
wxColour cl2 = GetColorAverage( clb, cl, 1. * Weighting / 255 );
pDC->SetPen( cl2 );
pDC->DrawPoint( X0, Y0 );
cl2 = GetColorAverage( clb, cl, 1. * ( Weighting ^ WeightingComplementMask ) / 255 );
pDC->SetPen( cl2 );
pDC->DrawPoint( X0 + XDir, Y0 );
}
/* Draw the final pixel, which is
always exactly intersected by the line
and so needs no weighting */
pDC->SetPen( cl );
pDC->DrawPoint( X1, Y1 );
return;
}
/* It's an X-major line; calculate 16-bit fixed-point fractional part of a
pixel that Y advances each time X advances 1 pixel, truncating the
result to avoid overrunning the endpoint along the X axis */
ErrorAdj = ((unsigned long) DeltaY << 16) / (unsigned long) DeltaX;
/* Draw all pixels other than the first and last */
while (--DeltaX) {
ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */
ErrorAcc += ErrorAdj; /* calculate error for next pixel */
if (ErrorAcc <= ErrorAccTemp) {
/* The error accumulator turned over, so advance the Y coord */
Y0++;
}
X0 += XDir; /* X-major, so always advance X */
/* The IntensityBits most significant bits of ErrorAcc give us the
intensity weighting for this pixel, and the complement of the
weighting for the paired pixel */
Weighting = ErrorAcc >> IntensityShift;
wxColour cl2 = GetColorAverage( clb, cl, 1. * Weighting / 255 );
pDC->SetPen( cl2 );
pDC->DrawPoint( X0, Y0 );
cl2 = GetColorAverage( clb, cl, 1. * ( Weighting ^ WeightingComplementMask ) / 255 );
pDC->SetPen( cl2 );
pDC->DrawPoint( X0, Y0 + 1 );
}
/* Draw the final pixel, which is always exactly intersected by the line
and so needs no weighting */
pDC->SetPen( cl );
pDC->DrawPoint( X1, Y1 );
}
```