ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

BOOL UserDrawIconEx ( HDC  hDc,
INT  xLeft,
INT  yTop,
PCURICON_OBJECT  pIcon,
INT  cxWidth,
INT  cyHeight,
UINT  istepIfAniCur,
HBRUSH  hbrFlickerFreeDraw,
UINT  diFlags 
)

Definition at line 1047 of file cursoricon.c.

Referenced by NtUserDrawIconEx(), and UserDrawCaption().

{
    BOOL Ret = FALSE;
    HBITMAP hbmMask, hbmColor;
    BITMAP bmpColor, bm;
    BOOL DoFlickerFree;
    INT iOldBkColor = 0, iOldTxtColor = 0;

    HDC hMemDC, hDestDC = hDc;
    HGDIOBJ hOldOffBrush = 0;
    HGDIOBJ hOldOffBmp = 0;
    HBITMAP hTmpBmp = 0, hOffBmp = 0;
    BOOL bAlpha = FALSE;
    INT x=xLeft, y=yTop;

    hbmMask = pIcon->IconInfo.hbmMask;
    hbmColor = pIcon->IconInfo.hbmColor;

    if (istepIfAniCur)
        ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");

    if (!hbmMask || !GreGetObject(hbmMask, sizeof(BITMAP), (PVOID)&bm))
    {
        return FALSE;
    }

    if (hbmColor && !GreGetObject(hbmColor, sizeof(BITMAP), (PVOID)&bmpColor))
    {
        return FALSE;
    }

    if(!(hMemDC = NtGdiCreateCompatibleDC(hDc)))
    {
        ERR("NtGdiCreateCompatibleDC failed!\n");
        return FALSE;
    }

    /* Check for alpha */
    if (hbmColor
            && (bmpColor.bmBitsPixel == 32)
            && (diFlags & DI_IMAGE))
    {
        SURFACE *psurfOff = NULL;
        PFN_DIB_GetPixel fnSource_GetPixel = NULL;
        INT i, j;

        /* In order to correctly display 32 bit icons Windows first scans the image,
           because information about transparency is not stored in any image's headers */
        psurfOff = SURFACE_ShareLockSurface(hbmColor);
        if (psurfOff)
        {
            fnSource_GetPixel = DibFunctionsForBitmapFormat[psurfOff->SurfObj.iBitmapFormat].DIB_GetPixel;
            if (fnSource_GetPixel)
            {
                for (i = 0; i < psurfOff->SurfObj.sizlBitmap.cx; i++)
                {
                    for (j = 0; j < psurfOff->SurfObj.sizlBitmap.cy; j++)
                    {
                        bAlpha = ((BYTE)(fnSource_GetPixel(&psurfOff->SurfObj, i, j) >> 24) & 0xff);
                        if (bAlpha)
                            break;
                    }
                    if (bAlpha)
                        break;
                }
            }
            SURFACE_ShareUnlockSurface(psurfOff);
        }
    }

    if (!cxWidth)
        cxWidth = ((diFlags & DI_DEFAULTSIZE) ?
                   UserGetSystemMetrics(SM_CXICON) : pIcon->Size.cx);

    if (!cyHeight)
        cyHeight = ((diFlags & DI_DEFAULTSIZE) ?
                    UserGetSystemMetrics(SM_CYICON) : pIcon->Size.cy);

    DoFlickerFree = (hbrFlickerFreeDraw &&
                     (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH));

    if (DoFlickerFree)
    {
        hDestDC = NtGdiCreateCompatibleDC(hDc);
        if(!hDestDC)
        {
            ERR("NtGdiCreateCompatibleDC failed!\n");
            Ret = FALSE;
            goto Cleanup ;
        }
        hOffBmp = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
        if(!hOffBmp)
        {
            ERR("NtGdiCreateCompatibleBitmap failed!\n");
            goto Cleanup ;
        }
        hOldOffBmp = NtGdiSelectBitmap(hDestDC, hOffBmp);
        hOldOffBrush = NtGdiSelectBrush(hDestDC, hbrFlickerFreeDraw);
        NtGdiPatBlt(hDestDC, 0, 0, cxWidth, cyHeight, PATCOPY);
        NtGdiSelectBrush(hDestDC, hOldOffBrush);
        x=y=0;
    }

    /* Set Background/foreground colors */
    iOldTxtColor = IntGdiSetTextColor(hDc, 0);          // Black
    iOldBkColor = IntGdiSetBkColor(hDc, 0x00FFFFFF);    // White

    if(bAlpha && (diFlags & DI_IMAGE))
    {
        BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
        BYTE Alpha;
        INT i, j;
        PSURFACE psurf;
        PBYTE ptr ;
        HBITMAP hMemBmp = NULL;

        hMemBmp = BITMAP_CopyBitmap(hbmColor);
        if(!hMemBmp)
        {
            ERR("BITMAP_CopyBitmap failed!");
            goto CleanupAlpha;
        }

        psurf = SURFACE_ShareLockSurface(hMemBmp);
        if(!psurf)
        {
            ERR("SURFACE_LockSurface failed!\n");
            goto CleanupAlpha;
        }

        /* Premultiply with the alpha channel value */
        for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++)
        {
            ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta;
            for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++)
            {
                Alpha = ptr[3];
                ptr[0] = (ptr[0] * Alpha) / 0xff;
                ptr[1] = (ptr[1] * Alpha) / 0xff;
                ptr[2] = (ptr[2] * Alpha) / 0xff;

                ptr += 4;
            }
        }

        SURFACE_ShareUnlockSurface(psurf);

        hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);

        Ret = NtGdiAlphaBlend(hDestDC,
                              x,
                              y,
                              cxWidth,
                              cyHeight,
                              hMemDC,
                              0,
                              0,
                              pIcon->Size.cx,
                              pIcon->Size.cy,
                              pixelblend,
                              NULL);
        NtGdiSelectBitmap(hMemDC, hTmpBmp);
    CleanupAlpha:
        if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
        if(Ret) goto done;
    }

    if (diFlags & DI_MASK)
    {
        DWORD rop = (diFlags & DI_IMAGE) ? SRCAND : SRCCOPY;
        hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
        NtGdiStretchBlt(hDestDC,
                        x,
                        y,
                        cxWidth,
                        cyHeight,
                        hMemDC,
                        0,
                        0,
                        pIcon->Size.cx,
                        pIcon->Size.cy,
                        rop,
                        0);
        NtGdiSelectBitmap(hMemDC, hTmpBmp);
    }

    if(diFlags & DI_IMAGE)
    {
        if (hbmColor)
        {
            DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
            hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmColor);
            NtGdiStretchBlt(hDestDC,
                            x,
                            y,
                            cxWidth,
                            cyHeight,
                            hMemDC,
                            0,
                            0,
                            pIcon->Size.cx,
                            pIcon->Size.cy,
                            rop,
                            0);
            NtGdiSelectBitmap(hMemDC, hTmpBmp);
        }
        else
        {
            /* Mask bitmap holds the information in its second half */
            DWORD rop = (diFlags & DI_MASK) ? SRCINVERT : SRCCOPY ;
            hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
            NtGdiStretchBlt(hDestDC,
                            x,
                            y,
                            cxWidth,
                            cyHeight,
                            hMemDC,
                            0,
                            pIcon->Size.cy,
                            pIcon->Size.cx,
                            pIcon->Size.cy,
                            rop,
                            0);
            NtGdiSelectBitmap(hMemDC, hTmpBmp);
        }
    }

done:
    if(hDestDC != hDc)
    {
        NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, cyHeight, hDestDC, 0, 0, SRCCOPY, 0, 0);
    }

    /* Restore foreground and background colors */
    IntGdiSetBkColor(hDc, iOldBkColor);
    IntGdiSetTextColor(hDc, iOldTxtColor);

    Ret = TRUE ;

Cleanup:
    NtGdiDeleteObjectApp(hMemDC);
    if(hDestDC != hDc)
    {
        if(hOldOffBmp) NtGdiSelectBitmap(hDestDC, hOldOffBmp);
        NtGdiDeleteObjectApp(hDestDC);
        if(hOffBmp) NtGdiDeleteObjectApp(hOffBmp);
    }

    return Ret;
}

Generated on Sun May 27 2012 06:11:13 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.