⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 offscr4bpp.c

📁 STM32+Grlib
💻 C
📖 第 1 页 / 共 3 页
字号:

//*****************************************************************************
//
//! Fills a rectangle.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//! \param pRect is a pointer to the structure describing the rectangle.
//! \param ulValue is the color of the rectangle.
//!
//! This function fills a rectangle on the display.  The coordinates of the
//! rectangle are assumed to be within the extents of the display, and the
//! rectangle specification is fully inclusive (in other words, both sXMin and
//! sXMax are drawn, along with sYMin and sYMax).
//!
//! \return None.
//
//*****************************************************************************
static void
GrOffScreen4BPPRectFill(void *pvDisplayData, const tRectangle *pRect,
                        unsigned long ulValue)
{
    unsigned char *pucData, *pucColumn;
    long lBytesPerRow, lX, lY;

    //
    // Check the arguments.
    //
    ASSERT(pvDisplayData);
    ASSERT(pRect);

    //
    // Create a character pointer for the display-specific data (which points
    // to the image buffer).
    //
    pucData = (unsigned char *)pvDisplayData;

    //
    // Compute the number of bytes per row in the image buffer.
    //
    lBytesPerRow = (*(unsigned short *)(pucData + 1) + 1) / 2;

    //
    // Get the offset to the byte of the image buffer that contains the
    // starting pixel.
    //
    pucData += ((lBytesPerRow * pRect->sYMin) + (pRect->sXMin / 2) + 6 +
                (16 * 3));

    //
    // Copy the pixel value into all 8 pixels of the unsigned long.  This will
    // be used later to write multiple pixels into memory (as opposed to one at
    // a time).
    //
    ulValue = ((ulValue << 28) | (ulValue << 24) | (ulValue << 20) |
               (ulValue << 16) | (ulValue << 12) | (ulValue << 8) |
               (ulValue << 4) | ulValue);

    //
    // Get the starting X coordinate of the rectangle.
    //
    lX = pRect->sXMin;

    //
    // See if the second pixel in a byte is part of the rectangle.
    //
    if(lX & 1)
    {
        //
        // Draw the second pixel of this column of the rectangle.
        //
        for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
            lY++, pucColumn += lBytesPerRow)
        {
            *pucColumn = (*pucColumn & 0xf0) | (ulValue & 0x0f);
        }
        pucData++;
        lX++;
    }

    //
    // See if the buffer pointer is not half-word aligned and there are at
    // least two pixel columns left to draw.
    //
    if(((unsigned long)pucData & 1) && (pRect->sXMax - lX) > 0)
    {
        //
        // Draw two pixels in this column of the rectangle.
        //
        for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
            lY++, pucColumn += lBytesPerRow)
        {
            *pucColumn = ulValue & 0xff;
        }
        pucData++;
        lX += 2;
    }

    //
    // See if the buffer pointer is not word aligned and there are at least
    // four pixel columns left to draw.
    //
    if(((unsigned long)pucData & 2) && ((pRect->sXMax - lX) > 2))
    {
        //
        // Draw four pixels in this column of the rectangle.
        //
        for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
            lY++, pucColumn += lBytesPerRow)
        {
            *(unsigned short *)pucColumn = ulValue & 0xffff;
        }
        pucData += 2;
        lX += 4;
    }

    //
    // Loop while there are at least eight pixel columns left to draw.
    //
    while((lX + 7) <= pRect->sXMax)
    {
        //
        // Draw eight pixels in this column of the rectangle.
        //
        for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
            lY++, pucColumn += lBytesPerRow)
        {
            *(unsigned long *)pucColumn = ulValue;
        }
        pucData += 4;
        lX += 8;
    }

    //
    // See if there are at least four pixel columns left to draw.
    //
    if((lX + 3) <= pRect->sXMax)
    {
        //
        // Draw four pixel columns, leaving the buffer pointer half-word
        // aligned.
        //
        ulValue &= 0xffff;
        for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
            lY++, pucColumn += lBytesPerRow)
        {
            *(unsigned short *)pucColumn = ulValue;
        }
        pucData += 2;
        lX += 4;
    }

    //
    // See if there are at least two pixel columns left to draw.
    //
    if((lX + 1) <= pRect->sXMax)
    {
        //
        // Draw two pixel columns, leaving the buffer pointer byte aligned.
        //
        ulValue &= 0xff;
        for(lY = pRect->sYMin, pucColumn = pucData; lY <= pRect->sYMax;
            lY++, pucColumn += lBytesPerRow)
        {
            *pucColumn = ulValue;
        }
        pucData++;
        lX += 2;
    }

    //
    // See if there is one pixel column left to draw.
    //
    if(lX == pRect->sXMax)
    {
        //
        // Draw the final pixel column.
        //
        ulValue = ulValue & 0xf0;
        for(lY = pRect->sYMin; lY <= pRect->sYMax;
            lY++, pucData += lBytesPerRow)
        {
            *pucData = (*pucData & 0x0f) | ulValue;
        }
    }
}

//*****************************************************************************
//
//! Flushes any cached drawing operations.
//!
//! \param pvDisplayData is a pointer to the driver-specific data for this
//! display driver.
//!
//! This functions flushes any cached drawing operations to the display.  This
//! is useful when a local frame buffer is used for drawing operations, and the
//! flush would copy the local frame buffer to the display.  For the off-screen
//! display buffer driver, the flush is a no operation.
//!
//! \return None.
//
//*****************************************************************************
static void
GrOffScreen4BPPFlush(void *pvDisplayData)
{
    //
    // Check the arguments.
    //
    ASSERT(pvDisplayData);
}

//*****************************************************************************
//
//! Initializes a 4 BPP off-screen buffer.
//!
//! \param pDisplay is a pointer to the display structure to be configured for
//! the 4 BPP off-screen buffer.
//! \param pucImage is a pointer to the image buffer to be used for the
//! off-screen buffer.
//! \param lWidth is the width of the image buffer in pixels.
//! \param lHeight is the height of the image buffer in pixels.
//!
//! This function initializes a display structure, preparing it to draw into
//! the supplied image buffer.  The image buffer is assumed to be large enough
//! to hold an image of the specified geometry.
//!
//! \return None.
//
//*****************************************************************************
void
GrOffScreen4BPPInit(tDisplay *pDisplay, unsigned char *pucImage, long lWidth,
                    long lHeight)
{
    //
    // Check the arguments.
    //
    ASSERT(pDisplay);
    ASSERT(pucImage);

    //
    // Initialize the display structure.
    //
    pDisplay->lSize = sizeof(tDisplay);
    pDisplay->pvDisplayData = pucImage;
    pDisplay->usWidth = lWidth;
    pDisplay->usHeight = lHeight;
    pDisplay->pfnPixelDraw = GrOffScreen4BPPPixelDraw;
    pDisplay->pfnPixelDrawMultiple = GrOffScreen4BPPPixelDrawMultiple;
    pDisplay->pfnLineDrawH = GrOffScreen4BPPLineDrawH;
    pDisplay->pfnLineDrawV = GrOffScreen4BPPLineDrawV;
    pDisplay->pfnRectFill = GrOffScreen4BPPRectFill;
    pDisplay->pfnColorTranslate = GrOffScreen4BPPColorTranslate;
    pDisplay->pfnFlush = GrOffScreen4BPPFlush;

    //
    // Initialize the image buffer.
    //
    pucImage[0] = IMAGE_FMT_4BPP_UNCOMP;
    *(unsigned short *)(pucImage + 1) = lWidth;
    *(unsigned short *)(pucImage + 3) = lHeight;
    pucImage[5] = 15;
}

//*****************************************************************************
//
//! Sets the palette of a 4 BPP off-screen buffer.
//!
//! \param pDisplay is a pointer to the display structure for the 4 BPP
//! off-screen buffer.
//! \param pulPalette is a pointer to the array of 24-bit RGB values to be
//! placed into the palette.
//! \param ulOffset is the starting offset into the image palette.
//! \param ulCount is the number of palette entries to set.
//!
//! This function sets the entries of the palette used by the 4 BPP off-screen
//! buffer.  The palette is used to select colors for drawing via
//! GrOffScreen4BPPColorTranslate(), and for the final rendering of the image
//! to a real display via GrImageDraw().
//!
//! \return None.
//
//*****************************************************************************
void
GrOffScreen4BPPPaletteSet(tDisplay *pDisplay, unsigned long *pulPalette,
                          unsigned long ulOffset, unsigned long ulCount)
{
    unsigned char *pucData;

    //
    // Check the arguments.
    //
    ASSERT(pDisplay);
    ASSERT(pulPalette);
    ASSERT(ulOffset < 16);
    ASSERT((ulOffset + ulCount) <= 16);

    //
    // Get a pointer to the start of the image buffer's palette.
    //
    pucData = (unsigned char *)pDisplay->pvDisplayData + 6;

    //
    // Skip to the specified offset in the palette.
    //
    pucData += ulOffset * 3;

    //
    // Loop while there are more palette entries to add.
    //
    while(ulCount--)
    {
        //
        // Copy this palette entry to the image buffer's palette.
        //
        *pucData++ = (*pulPalette >> ClrBlueShift) & 0xff;
        *pucData++ = (*pulPalette >> ClrGreenShift) & 0xff;
        *pucData++ = (*pulPalette++ >> ClrRedShift) & 0xff;
    }
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -