Thursday, November 25, 2010

Some graphic functions

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