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

📄 swblt.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
    // Variables used for AlphaBlend.
    ULONG RedMask;
    ULONG GreenMask;
    ULONG BlueMask;
    ULONG AlphaMask;
    ULONG RedShift;
    ULONG GreenShift;
    ULONG BlueShift;
    ULONG AlphaShift;
    ULONG SrcAlphaMask;
    ULONG SrcAlphaShift;

    BOOL  BlendPalette = FALSE;

    // If the BLENDFUNCTION isn't Null, the destination pixel value will need
    // to be read.
    int alphaBlend = 0;
    if (*(DWORD *)&(pParms->blendFunction) != *(DWORD *)&g_NullBlendFunction)
    {
        // Get the format of the source and destination surfaces.
        GPEFormat * pDstFormat = pParms->pDst->FormatPtr();

        if (pDstFormat->m_PaletteEntries == 3)
        {
            RedMask   = pDstFormat->m_pPalette[0];
            GreenMask = pDstFormat->m_pPalette[1];
            BlueMask  = pDstFormat->m_pPalette[2];
            AlphaMask = 0;

            // If this is a 32 bpp surface, try to add an "implicit" Alpha mask.
            if (EGPEFormatToBpp[pParms->pDst->Format()] == 32
                && !(0xFF000000 & (RedMask | GreenMask | BlueMask)))
            {
                AlphaMask = 0xFF000000;
            }
        }
        else if (pDstFormat->m_PaletteEntries == 4 && EGPEFormatToBpp[pParms->pDst->Format()] > 8)
        {
            RedMask   = pDstFormat->m_pPalette[0];
            GreenMask = pDstFormat->m_pPalette[1];
            BlueMask  = pDstFormat->m_pPalette[2];
            AlphaMask = pDstFormat->m_pPalette[3];

        }
        else
        {
            RedMask   = 0x000000FF;
            GreenMask = 0x0000FF00;
            BlueMask  = 0x00FF0000;
            AlphaMask = 0xFF000000;

            BlendPalette = TRUE;
        }

        // Compute the shifts for each mask.
        ULONG bit;
        ULONG Mask = RedMask;
        for (bit = 0; Mask && !(Mask & 1); bit++)
        {
            Mask >>= 1;
        }
        RedShift = bit;

        Mask = GreenMask;
        for (bit = 0; Mask && !(Mask & 1); bit++)
        {
            Mask >>= 1;
        }
        GreenShift = bit;

        Mask = BlueMask;
        for (bit = 0; Mask && !(Mask & 1); bit++)
        {
            Mask >>= 1;
        }
        BlueShift = bit;

        Mask = AlphaMask;
        for (bit = 0; Mask && !(Mask & 1); bit++)
        {
            Mask >>= 1;
        }
        AlphaShift = bit;

        // If this is a per-pixel blend, get the source alpha format.
        if (pParms->blendFunction.AlphaFormat)
        {
            DWORD SavedSrcAlphaMask;

            if (pParms->pSrc->FormatPtr()->m_PaletteEntries == 4)
            {
                SrcAlphaMask = pParms->pSrc->FormatPtr()->m_pPalette[3];
            }
            else if (pParms->pSrc->FormatPtr()->m_PaletteEntries == 3)
            {
                // If a fourth mask isn't provided, GDI guarantees that
                // 0xFF000000 is a valid alpha mask.
                SrcAlphaMask = 0xFF000000;
            }
            else
            {
                ASSERT(0);
            }

            SavedSrcAlphaMask = SrcAlphaMask;
            SrcAlphaShift = 0;

            while (!(SrcAlphaMask & 1))
            {
                SrcAlphaMask >>= 1;
                SrcAlphaShift++;
            }

            SrcAlphaMask = SavedSrcAlphaMask;
        }

        dstMatters = 1;
        alphaBlend = 1;
    }
#endif /* Wince 500 */

    // Handle improperly ordered prclDst resulting from stretch Blt
    // Note that only prclDst is ever improperly ordered
    if( width < 0 || height < 0 )
    {
        tmpRclDst = *prclDst;
        prclDst = &tmpRclDst;
        if( width < 0 )
        {
            SWAP( tmpRclDst.left, tmpRclDst.right, LONG )
            width = -width;
            dstXPositive = !dstXPositive;
        }
        if( height < 0 )
        {
            SWAP( tmpRclDst.top, tmpRclDst.bottom, LONG )
            height = -height;
            dstYPositive = !dstYPositive;
        }
    }
    // prclDst is now properly ordered


    if( pParms->bltFlags & BLT_STRETCH )    // Check for stretching or shrinking vertically &/or horizontally
    {
        srcWidth = pParms->prclSrc->right - pParms->prclSrc->left;
        srcHeight = pParms->prclSrc->bottom - pParms->prclSrc->top;

        if( width > srcWidth )
        {
            xStretch = 1;
            xDMajor = width;
            xDMinor = srcWidth;
        }
        else if( width < srcWidth )
        {
            xShrink = 1;
            xDMajor = srcWidth;
            xDMinor = width;
        }

        if( xStretch || xShrink)
        {
            xShrinkStretch = 1;
            // Convert to Bresenham parameters
            xDMinor *= 2;
            xDMajor = xDMinor - 2 * xDMajor;
            rowXAccum = xShrink?(2*width - srcWidth):(3*srcWidth - 2*width);
                // loaded into xAccum at start of each row
        }

        if( height > srcHeight )
        {
            yStretch = 1;
            yDMajor = height;
            yDMinor = srcHeight;
        }
        else if( height < srcHeight )
        {
            yShrink = 1;
            yDMajor = srcHeight;
            yDMinor = height;
        }

        if( yStretch || yShrink)
        {
            yShrinkStretch = 1;
            // Convert to Bresenham parameters
            yDMinor *= 2;
            yDMajor = yDMinor - 2 * yDMajor;
            yAccum = yShrink?(2*height - srcHeight):(3*srcHeight - 2*height);
        }

        if( pParms->prclClip )  // ONLY happens if stretch blting
        {
            RECTL rclClipped = *prclDst;

            if( rclClipped.left < pParms->prclClip->left )
            {
                rclClipped.left = pParms->prclClip->left;
            }
            if( rclClipped.top < pParms->prclClip->top )
            {
                rclClipped.top = pParms->prclClip->top;
            }
            if( rclClipped.bottom > pParms->prclClip->bottom )
            {
                rclClipped.bottom = pParms->prclClip->bottom;
            }
            if( rclClipped.right > pParms->prclClip->right )
            {
                rclClipped.right = pParms->prclClip->right;
            }
            if( rclClipped.right <= rclClipped.left || rclClipped.bottom <= rclClipped.top )
            {
                return S_OK;    // the clipping left nothing to do
            }

            dstXStartSkip = dstXPositive?(rclClipped.left-prclDst->left):(prclDst->right-rclClipped.right);
            dstYStartSkip = dstYPositive?(rclClipped.top-prclDst->top):(prclDst->bottom-rclClipped.bottom);
            width = rclClipped.right - rclClipped.left;     // Calculate fully clipped destination width
            height = rclClipped.bottom - rclClipped.top;    // Fully clipped height
        }

        if( xShrink )
        {
            while( rowXAccum < 0 )
            {
                rowXAccum += xDMinor;
                srcXStartSkip++;
            }
            rowXAccum += xDMajor;
        }
        for( int skipCount = dstXStartSkip; skipCount; skipCount-- )
        {
            if( xShrink )
            {
                while( rowXAccum < 0 )
                {
                    rowXAccum += xDMinor;
                    srcXStartSkip++;
                }
                srcXStartSkip++;    //  <--- this is the srcSkip inherent with a dstSkip
                rowXAccum += xDMajor;
            }
            else if( xStretch )
            {
                if( rowXAccum < 0 )
                {
                    rowXAccum += xDMinor;
                }
                else
                {
                    rowXAccum += xDMajor;
                    srcXStartSkip++;
                }
            }
            else
            {
                srcXStartSkip++;
        }
        }
        if( yShrink )
        {
            yAccum += dstYStartSkip * yDMajor;
            srcYStartSkip += dstYStartSkip; //  <--- this is the srcSkip inherent with a dstSkip
        }
        else if( yStretch )
        {
            for( int skipCount = dstYStartSkip; skipCount; skipCount-- )
            {
                if( yAccum < 0 )
                {
                    yAccum += yDMinor;
                }
                else
                {
                    yAccum += yDMajor;
                    srcYStartSkip++;
                }
            }
        }
        else
        {
            srcYStartSkip += dstYStartSkip;
    }
     }

    int transparentBlt = pParms->bltFlags & BLT_TRANSPARENT;
    unsigned long transparentColor = pParms->solidColor;

    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pSrc=0x%08x, pDst=0x%08x, pBrush=%08x, pMask=%08x\r\n"),
        pParms->pSrc, pParms->pDst, pParms->pBrush, pParms->pMask ));

    PixelIterator src, dst, mask;
    BrushPixelIterator brush;
    src.Ptr = src.RowPtr = mask.Ptr = mask.RowPtr = brush.Ptr = brush.RowPtr = (unsigned char *)0;

    if( pParms->pSrc )
    {
        DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pSrc depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pSrc->Format()] ) );
        src.InitPixelIterator( pParms->pSrc, pParms->xPositive, pParms->yPositive, pParms->prclSrc,
            srcXStartSkip, srcYStartSkip );
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
        // If we're doing a transparent blt, we will need to know the real RGB
        // masks.
        if (transparentBlt)
        {
            GPEFormat * pFormat = pParms->pSrc->FormatPtr();

            // Make sure we're dealing with a known format.
            if (EGPEFormatToBpp[pParms->pSrc->Format()] > 8
                && (pFormat->m_PaletteEntries == 4
                    ||pFormat->m_PaletteEntries == 3))
            {
                ULONG * pMasks = pFormat->m_pPalette;

                SrcRGBMask = pMasks[0] | pMasks[1] | pMasks[2];
            }
            else
            {
                SrcRGBMask = src.Mask;
            }
        }
        else
        {
            SrcRGBMask = src.Mask;
        }
#endif
    }
    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pDst depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pDst->Format()] ) );

    if( pParms->pBrush )
    {
        // Calculate an rclBrush so that the correct starting pixel is chosen for the brush iterator
        DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Pattern depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pBrush->Format()] ) );
        int topIndent = (pParms->pptlBrush)?pParms->pBrush->Height()-pParms->pptlBrush->y:0;
        int leftIndent = (pParms->pptlBrush)?pParms->pBrush->Width()-pParms->pptlBrush->x:0;
        rclBrush.left = ( leftIndent + prclDst->left ) % pParms->pBrush->Width();
        rclBrush.right = ( leftIndent + prclDst->right ) % pParms->pBrush->Width();
        rclBrush.top = ( topIndent + prclDst->top ) % pParms->pBrush->Height();
        rclBrush.bottom = ( topIndent + prclDst->bottom ) % pParms->pBrush->Height();

        DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("pBrush depth: %d Bpp\r\n"), EGPEFormatToBpp[pParms->pBrush->Format()] ) );
        brush.InitBrushPixelIterator( pParms->pBrush, pParms->xPositive, pParms->yPositive, &rclBrush );
    }

    if( pParms->pMask )
    {
        mask.InitPixelIterator( pParms->pMask, pParms->xPositive, pParms->yPositive, pParms->prclMask,
            srcXStartSkip, srcYStartSkip );
    }
    else

⌨️ 快捷键说明

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