static int driverDrawPixel(kernelGraphicBuffer *buffer, color *foreground,
drawMode mode, int xCoord, int yCoord)
{
// Draws a single pixel to the graphic buffer using the preset foreground
// color
int status = 0;
unsigned char *framebufferPointer = NULL;
short pix = 0;
// If the supplied kernelGraphicBuffer is NULL, we draw directly to the
// whole screen
if (buffer == NULL)
buffer = &wholeScreen;
// Make sure the pixel is in the buffer
if ((xCoord >= buffer->width) || (yCoord >= buffer->height))
// Don't make an error condition, just skip it
return (status = 0);
// Make sure we're not drawing off the screen
if ((xCoord < 0) || (xCoord >= buffer->width) ||
(yCoord < 0) || (yCoord >= buffer->height))
return (status = 0);
// Draw the pixel using the supplied color
framebufferPointer = buffer->data +
(((buffer->width * yCoord) + xCoord) * adapter->bytesPerPixel);
if ((adapter->bitsPerPixel == 32) || (adapter->bitsPerPixel == 24))
{
if (mode == draw_normal)
{
framebufferPointer[0] = foreground->blue;
framebufferPointer[1] = foreground->green;
framebufferPointer[2] = foreground->red;
}
else if (mode == draw_or)
{
framebufferPointer[0] |= foreground->blue;
framebufferPointer[1] |= foreground->green;
framebufferPointer[2] |= foreground->red;
}
else if (mode == draw_xor)
{
framebufferPointer[0] ^= foreground->blue;
framebufferPointer[1] ^= foreground->green;
framebufferPointer[2] ^= foreground->red;
}
}
else if ((adapter->bitsPerPixel == 16) || (adapter->bitsPerPixel == 15))
{
if (adapter->bitsPerPixel == 16)
pix = (((foreground->red >> 3) << 11) |
((foreground->green >> 2) << 5) |
(foreground->blue >> 3));
else
pix = (((foreground->red >> 3) << 10) |
((foreground->green >> 3) << 5) |
(foreground->blue >> 3));
if (mode == draw_normal)
*((short *) framebufferPointer) = pix;
else if (mode == draw_or)
*((short *) framebufferPointer) |= pix;
else if (mode == draw_xor)
*((short *) framebufferPointer) ^= pix;
}
return (status = 0);
}
// driverDrawMonoImage is used to draw font image.Evert char will be inserted MONOCHROME into memory buffer for later use.
static int driverDrawMonoImage(kernelGraphicBuffer *buffer, image *drawImage,
drawMode mode,color *foreground,
color *background, int xCoord, int yCoord)
{
// Draws the supplied image on the screen at the requested coordinates
int status = 0;
unsigned lineLength = 0;
unsigned lineBytes = 0;
int numberLines = 0;
unsigned char *framebufferPointer = NULL;
unsigned char *monoImageData = NULL;
int lineCounter = 0;
unsigned pixelCounter = 0;
short onPixel, offPixel;
unsigned count;
// If the supplied kernelGraphicBuffer is NULL, we draw directly to the
// whole screen
if (buffer == NULL)
buffer = &wholeScreen;
// Check params
if ((xCoord < 0) || (xCoord >= buffer->width) ||
(yCoord < 0) || (yCoord >= buffer->height))
return (status = ERR_BOUNDS);
// Make sure it's a mono image
if (drawImage->type != IMAGETYPE_MONO)
return (status = ERR_INVALID);
// If the image goes off the right edge of the screen, only attempt to
// display what will fit
if ((int)(xCoord + drawImage->width) < buffer->width)
lineLength = drawImage->width;
else
lineLength = (buffer->width - xCoord);
// If the image goes off the bottom of the screen, only show the
// lines that will fit
if ((int)(yCoord + drawImage->height) < buffer->height)
numberLines = drawImage->height;
else
numberLines = (buffer->height - yCoord);
// images are lovely little data structures that give us image
// data in the most convenient form we can imagine.
// How many bytes in a line of data?
lineBytes = (adapter->bytesPerPixel * lineLength);
framebufferPointer = buffer->data +
(((buffer->width * yCoord) + xCoord) * adapter->bytesPerPixel);
// A mono image has a bitmap of 'on' bits and 'off' bits. We will
// draw all 'on' bits using the current foreground color.
monoImageData = (unsigned char *) drawImage->data;
// Loop for each line
for (lineCounter = 0; lineCounter < numberLines; lineCounter++)
{
// Do a loop through the line, copying either the foreground color
// value or the background color into framebuffer
if ((adapter->bitsPerPixel == 32) || (adapter->bitsPerPixel == 24))
for (count = 0; count < lineBytes; )
{
// Isolate the bit from the bitmap
if ((monoImageData[pixelCounter / 8] &
(0x80 >> (pixelCounter % 8))) != 0)
{
// 'on' bit.
framebufferPointer[count++] = foreground->blue;
framebufferPointer[count++] = foreground->green;
framebufferPointer[count++] = foreground->red;
if (adapter->bitsPerPixel == 32)
count++;
}
else
{
if (mode == draw_translucent)
count += adapter->bytesPerPixel;
else
{
// 'off' bit.
framebufferPointer[count++] = background->blue;
framebufferPointer[count++] = background->green;
framebufferPointer[count++] = background->red;
if (adapter->bitsPerPixel == 32)
count++;
}
}
pixelCounter += 1;
}
else if ((adapter->bitsPerPixel == 16) || (adapter->bitsPerPixel == 15))
{
if (adapter->bitsPerPixel == 16)
{
onPixel = (((foreground->red >> 3) << 11) |
((foreground->green >> 2) << 5) |
(foreground->blue >> 3));
offPixel = (((background->red >> 3) << 11) |
((background->green >> 2) << 5) |
(background->blue >> 3));
}
else
{
onPixel = (((foreground->red >> 3) << 10) |
((foreground->green >> 3) << 5) |
(foreground->blue >> 3));
offPixel = (((background->red >> 3) << 10) |
((background->green >> 3) << 5) |
(background->blue >> 3));
}
for (count = 0; count < lineLength; count ++)
{
// Isolate the bit from the bitmap
if ((monoImageData[pixelCounter / 8] &
(0x80 >> (pixelCounter % 8))) != 0)
// 'on' bit - means that it will be inserted into Buffer.
((short *) framebufferPointer)[count] = onPixel;
else if (mode != draw_translucent)
// 'off' bit - means that it will not be inserted into Buffer
((short *) framebufferPointer)[count] = offPixel;
pixelCounter += 1;
}
}
// Move to the next line in the framebuffer
framebufferPointer += (buffer->width * adapter->bytesPerPixel);
// Are we skipping any because it's off the screen?
if (drawImage->width > lineLength)
pixelCounter += (drawImage->width - lineLength);
}
// Success :)
return (status = 0);
}
No comments:
Post a Comment