/*
 * GDI bit-blit operations
 *
 * Copyright 1993, 1994  Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>
#include <limits.h>
#include <math.h>
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "gdi_private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(bitblt);

static inline BOOL rop_uses_src( DWORD rop )
{
    return ((rop >> 2) & 0x330000) != (rop & 0x330000);
}

static inline void swap_ints( int *i, int *j )
{
    int tmp = *i;
    *i = *j;
    *j = tmp;
}

BOOL intersect_vis_rectangles( struct bitblt_coords *dst, struct bitblt_coords *src )
{
    RECT rect;

    /* intersect the rectangles */

    if ((src->width == dst->width) && (src->height == dst->height)) /* no stretching */
    {
        offset_rect( &src->visrect, dst->x - src->x, dst->y - src->y );
        if (!intersect_rect( &rect, &src->visrect, &dst->visrect )) return FALSE;
        src->visrect = dst->visrect = rect;
        offset_rect( &src->visrect, src->x - dst->x, src->y - dst->y );
    }
    else  /* stretching */
    {
        /* map source rectangle into destination coordinates */
        rect = src->visrect;
        offset_rect( &rect, -min( src->x, src->x + src->width + 1),
                     -min( src->y, src->y + src->height + 1) );
        rect.left   = dst->x + rect.left * dst->width / abs(src->width);
        rect.top    = dst->y + rect.top * dst->height / abs(src->height);
        rect.right  = dst->x + rect.right * dst->width / abs(src->width);
        rect.bottom = dst->y + rect.bottom * dst->height / abs(src->height);
        if (rect.left > rect.right) swap_ints( &rect.left, &rect.right );
        if (rect.top > rect.bottom) swap_ints( &rect.top, &rect.bottom );

        /* avoid rounding errors */
        rect.left--;
        rect.top--;
        rect.right++;
        rect.bottom++;
        if (!intersect_rect( &dst->visrect, &rect, &dst->visrect )) return FALSE;

        /* map destination rectangle back to source coordinates */
        rect = dst->visrect;
        offset_rect( &rect, -min( dst->x, dst->x + dst->width + 1),
                     -min( dst->y, dst->y + dst->height + 1) );
        rect.left   = src->x + rect.left * src->width / abs(dst->width);
        rect.top    = src->y + rect.top * src->height / abs(dst->height);
        rect.right  = src->x + rect.right * src->width / abs(dst->width);
        rect.bottom = src->y + rect.bottom * src->height / abs(dst->height);
        if (rect.left > rect.right) swap_ints( &rect.left, &rect.right );
        if (rect.top > rect.bottom) swap_ints( &rect.top, &rect.bottom );

        /* avoid rounding errors */
        rect.left--;
        rect.top--;
        rect.right++;
        rect.bottom++;
        if (!intersect_rect( &src->visrect, &rect, &src->visrect )) return FALSE;
    }
    return TRUE;
}

static BOOL get_vis_rectangles( DC *dc_dst, struct bitblt_coords *dst,
                                DC *dc_src, struct bitblt_coords *src )
{
    RECT rect;

    /* get the destination visible rectangle */

    rect.left   = dst->log_x;
    rect.top    = dst->log_y;
    rect.right  = dst->log_x + dst->log_width;
    rect.bottom = dst->log_y + dst->log_height;
    LPtoDP( dc_dst->hSelf, (POINT *)&rect, 2 );
    dst->x      = rect.left;
    dst->y      = rect.top;
    dst->width  = rect.right - rect.left;
    dst->height = rect.bottom - rect.top;
    if (dst->layout & LAYOUT_RTL && dst->layout & LAYOUT_BITMAPORIENTATIONPRESERVED)
    {
        dst->x += dst->width;
        dst->width = -dst->width;
    }
    get_bounding_rect( &rect, dst->x, dst->y, dst->width, dst->height );

    clip_visrect( dc_dst, &dst->visrect, &rect );

    /* get the source visible rectangle */

    if (!src) return !is_rect_empty( &dst->visrect );

    rect.left   = src->log_x;
    rect.top    = src->log_y;
    rect.right  = src->log_x + src->log_width;
    rect.bottom = src->log_y + src->log_height;
    LPtoDP( dc_src->hSelf, (POINT *)&rect, 2 );
    src->x      = rect.left;
    src->y      = rect.top;
    src->width  = rect.right - rect.left;
    src->height = rect.bottom - rect.top;
    if (src->layout & LAYOUT_RTL && src->layout & LAYOUT_BITMAPORIENTATIONPRESERVED)
    {
        src->x += src->width;
        src->width = -src->width;
    }
    get_bounding_rect( &rect, src->x, src->y, src->width, src->height );

    /* source is not clipped */
    if (dc_src->header.type == OBJ_MEMDC)
        intersect_rect( &src->visrect, &rect, &dc_src->vis_rect );
    else
        src->visrect = rect;  /* FIXME: clip to device size */

    if (is_rect_empty( &src->visrect )) return FALSE;
    if (is_rect_empty( &dst->visrect )) return FALSE;

    return intersect_vis_rectangles( dst, src );
}

void free_heap_bits( struct gdi_image_bits *bits )
{
    HeapFree( GetProcessHeap(), 0, bits->ptr );
}

DWORD convert_bits( const BITMAPINFO *src_info, struct bitblt_coords *src,
                    BITMAPINFO *dst_info, struct gdi_image_bits *bits, BOOL add_alpha )
{
    void *ptr;
    DWORD err;

    dst_info->bmiHeader.biWidth = src->visrect.right - src->visrect.left;
    dst_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );

    if (!(ptr = HeapAlloc( GetProcessHeap(), 0, dst_info->bmiHeader.biSizeImage )))
        return ERROR_OUTOFMEMORY;

    err = convert_bitmapinfo( src_info, bits->ptr, src, dst_info, ptr, add_alpha );
    if (bits->free) bits->free( bits );
    bits->ptr = ptr;
    bits->is_copy = TRUE;
    bits->free = free_heap_bits;
    return err;
}

DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src,
                    BITMAPINFO *dst_info, struct bitblt_coords *dst,
                    struct gdi_image_bits *bits, int mode )
{
    void *ptr;
    DWORD err;

    dst_info->bmiHeader.biWidth = dst->visrect.right - dst->visrect.left;
    dst_info->bmiHeader.biHeight = dst->visrect.bottom - dst->visrect.top;
    dst_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );

    if (src_info->bmiHeader.biHeight < 0) dst_info->bmiHeader.biHeight = -dst_info->bmiHeader.biHeight;
    if (!(ptr = HeapAlloc( GetProcessHeap(), 0, dst_info->bmiHeader.biSizeImage )))
        return ERROR_OUTOFMEMORY;

    err = stretch_bitmapinfo( src_info, bits->ptr, src, dst_info, ptr, dst, mode );
    if (bits->free) bits->free( bits );
    bits->ptr = ptr;
    bits->is_copy = TRUE;
    bits->free = free_heap_bits;
    return err;
}

static DWORD blend_bits( const BITMAPINFO *src_info, const struct gdi_image_bits *src_bits,
                         struct bitblt_coords *src, BITMAPINFO *dst_info,
                         struct gdi_image_bits *dst_bits, struct bitblt_coords *dst, BLENDFUNCTION blend )
{
    if (!dst_bits->is_copy)
    {
        int size = dst_info->bmiHeader.biSizeImage;
        void *ptr = HeapAlloc( GetProcessHeap(), 0, size );
        if (!ptr) return ERROR_OUTOFMEMORY;
        memcpy( ptr, dst_bits->ptr, size );
        if (dst_bits->free) dst_bits->free( dst_bits );
        dst_bits->ptr = ptr;
        dst_bits->is_copy = TRUE;
        dst_bits->free = free_heap_bits;
    }
    return blend_bitmapinfo( src_info, src_bits->ptr, src, dst_info, dst_bits->ptr, dst, blend );
}

/***********************************************************************
 *           null driver fallback implementations
 */

BOOL nulldrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
                         PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop )
{
    DC *dc_src, *dc_dst = get_nulldrv_dc( dst_dev );
    char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
    BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
    DWORD err;
    struct gdi_image_bits bits;

    if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE;
    src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
    err = src_dev->funcs->pGetImage( src_dev, 0, src_info, &bits, src );
    release_dc_ptr( dc_src );
    if (err) return FALSE;

    /* 1-bpp source without a color table uses the destination DC colors */
    if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed)
    {
        COLORREF color = GetTextColor( dst_dev->hdc );
        src_info->bmiColors[0].rgbRed      = GetRValue( color );
        src_info->bmiColors[0].rgbGreen    = GetGValue( color );
        src_info->bmiColors[0].rgbBlue     = GetBValue( color );
        src_info->bmiColors[0].rgbReserved = 0;
        color = GetBkColor( dst_dev->hdc );
        src_info->bmiColors[1].rgbRed      = GetRValue( color );
        src_info->bmiColors[1].rgbGreen    = GetGValue( color );
        src_info->bmiColors[1].rgbBlue     = GetBValue( color );
        src_info->bmiColors[1].rgbReserved = 0;
        src_info->bmiHeader.biClrUsed = 2;
    }

    dst_dev = GET_DC_PHYSDEV( dc_dst, pPutImage );
    copy_bitmapinfo( dst_info, src_info );
    err = dst_dev->funcs->pPutImage( dst_dev, 0, 0, dst_info, &bits, src, dst, rop );
    if (err == ERROR_BAD_FORMAT)
    {
        /* 1-bpp destination without a color table requires a fake 1-entry table
         * that contains only the background color */
        if (dst_info->bmiHeader.biBitCount == 1 && !dst_info->bmiHeader.biClrUsed)
        {
            COLORREF color = GetBkColor( src_dev->hdc );
            dst_info->bmiColors[0].rgbRed      = GetRValue( color );
            dst_info->bmiColors[0].rgbGreen    = GetGValue( color );
            dst_info->bmiColors[0].rgbBlue     = GetBValue( color );
            dst_info->bmiColors[0].rgbReserved = 0;
            dst_info->bmiHeader.biClrUsed = 1;
        }

        if (!(err = convert_bits( src_info, src, dst_info, &bits, FALSE )))
        {
            /* get rid of the fake 1-bpp table */
            if (dst_info->bmiHeader.biClrUsed == 1) dst_info->bmiHeader.biClrUsed = 0;
            err = dst_dev->funcs->pPutImage( dst_dev, 0, 0, dst_info, &bits, src, dst, rop );
        }
    }

    if (err == ERROR_TRANSFORM_NOT_SUPPORTED &&
        ((src->width != dst->width) || (src->height != dst->height)))
    {
        copy_bitmapinfo( src_info, dst_info );
        err = stretch_bits( src_info, src, dst_info, dst, &bits, GetStretchBltMode( dst_dev->hdc ));
        if (!err) err = dst_dev->funcs->pPutImage( dst_dev, 0, 0, dst_info, &bits, src, dst, rop );
    }

    if (bits.free) bits.free( &bits );
    return !err;
}


BOOL nulldrv_AlphaBlend( PHYSDEV dst_dev, struct bitblt_coords *dst,
                         PHYSDEV src_dev, struct bitblt_coords *src, BLENDFUNCTION func )
{
    DC *dc_src, *dc_dst = get_nulldrv_dc( dst_dev );
    char src_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    char dst_buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *src_info = (BITMAPINFO *)src_buffer;
    BITMAPINFO *dst_info = (BITMAPINFO *)dst_buffer;
    DWORD err;
    struct gdi_image_bits bits;

    if (!(dc_src = get_dc_ptr( src_dev->hdc ))) return FALSE;
    src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
    err = src_dev->funcs->pGetImage( src_dev, 0, src_info, &bits, src );
    release_dc_ptr( dc_src );
    if (err) goto done;

    dst_dev = GET_DC_PHYSDEV( dc_dst, pBlendImage );
    copy_bitmapinfo( dst_info, src_info );
    err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func );
    if (err == ERROR_BAD_FORMAT)
    {
        err = convert_bits( src_info, src, dst_info, &bits, TRUE );
        if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func );
    }

    if (err == ERROR_TRANSFORM_NOT_SUPPORTED &&
        ((src->width != dst->width) || (src->height != dst->height)))
    {
        copy_bitmapinfo( src_info, dst_info );
        err = stretch_bits( src_info, src, dst_info, dst, &bits, COLORONCOLOR );
        if (!err) err = dst_dev->funcs->pBlendImage( dst_dev, dst_info, &bits, src, dst, func );
    }

    if (bits.free) bits.free( &bits );
done:
    if (err) SetLastError( err );
    return !err;
}


DWORD nulldrv_BlendImage( PHYSDEV dev, BITMAPINFO *info, const struct gdi_image_bits *bits,
                          struct bitblt_coords *src, struct bitblt_coords *dst, BLENDFUNCTION blend )
{
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *dst_info = (BITMAPINFO *)buffer;
    struct gdi_image_bits dst_bits;
    struct bitblt_coords orig_dst;
    DC *dc = get_nulldrv_dc( dev );
    DWORD err;

    if (info->bmiHeader.biPlanes != 1) goto update_format;
    if (info->bmiHeader.biBitCount != 32) goto update_format;
    if (info->bmiHeader.biCompression == BI_BITFIELDS)
    {
        DWORD *masks = (DWORD *)info->bmiColors;
        if (masks[0] != 0xff0000 || masks[1] != 0x00ff00 || masks[2] != 0x0000ff)
            goto update_format;
    }

    if (!bits) return ERROR_SUCCESS;
    if ((src->width != dst->width) || (src->height != dst->height)) return ERROR_TRANSFORM_NOT_SUPPORTED;

    dev = GET_DC_PHYSDEV( dc, pGetImage );
    orig_dst = *dst;
    err = dev->funcs->pGetImage( dev, 0, dst_info, &dst_bits, dst );
    if (err) return err;

    dev = GET_DC_PHYSDEV( dc, pPutImage );
    err = blend_bits( info, bits, src, dst_info, &dst_bits, dst, blend );
    if (!err) err = dev->funcs->pPutImage( dev, 0, 0, dst_info, &dst_bits, dst, &orig_dst, SRCCOPY );

    if (dst_bits.free) dst_bits.free( &dst_bits );
    return err;

update_format:
    if (blend.AlphaFormat & AC_SRC_ALPHA)  /* source alpha requires A8R8G8B8 format */
        return ERROR_INVALID_PARAMETER;

    info->bmiHeader.biPlanes      = 1;
    info->bmiHeader.biBitCount    = 32;
    info->bmiHeader.biCompression = BI_RGB;
    info->bmiHeader.biClrUsed     = 0;
    return ERROR_BAD_FORMAT;
}

BOOL nulldrv_GradientFill( PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert,
                           void * grad_array, ULONG ngrad, ULONG mode )
{
    DC *dc = get_nulldrv_dc( dev );
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    struct bitblt_coords src, dst;
    struct gdi_image_bits bits;
    unsigned int i;
    POINT *pts;
    BOOL ret = FALSE;
    DWORD err;
    HRGN rgn;

    if (!(pts = HeapAlloc( GetProcessHeap(), 0, nvert * sizeof(*pts) ))) return FALSE;
    for (i = 0; i < nvert; i++)
    {
        pts[i].x = vert_array[i].x;
        pts[i].y = vert_array[i].y;
    }
    LPtoDP( dev->hdc, pts, nvert );

    /* compute bounding rect of all the rectangles/triangles */
    dst.visrect.left = dst.visrect.top = INT_MAX;
    dst.visrect.right = dst.visrect.bottom = INT_MIN;
    for (i = 0; i < ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2); i++)
    {
        ULONG v = ((ULONG *)grad_array)[i];
        dst.visrect.left   = min( dst.visrect.left,   pts[v].x );
        dst.visrect.top    = min( dst.visrect.top,    pts[v].y );
        dst.visrect.right  = max( dst.visrect.right,  pts[v].x );
        dst.visrect.bottom = max( dst.visrect.bottom, pts[v].y );
    }

    dst.x = dst.visrect.left;
    dst.y = dst.visrect.top;
    dst.width = dst.visrect.right - dst.visrect.left;
    dst.height = dst.visrect.bottom - dst.visrect.top;
    if (!clip_visrect( dc, &dst.visrect, &dst.visrect )) goto done;

    /* query the bitmap format */
    info->bmiHeader.biSize          = sizeof(info->bmiHeader);
    info->bmiHeader.biPlanes        = 1;
    info->bmiHeader.biBitCount      = 0;
    info->bmiHeader.biCompression   = BI_RGB;
    info->bmiHeader.biXPelsPerMeter = 0;
    info->bmiHeader.biYPelsPerMeter = 0;
    info->bmiHeader.biClrUsed       = 0;
    info->bmiHeader.biClrImportant  = 0;
    info->bmiHeader.biWidth         = dst.visrect.right - dst.visrect.left;
    info->bmiHeader.biHeight        = dst.visrect.bottom - dst.visrect.top;
    info->bmiHeader.biSizeImage     = 0;
    dev = GET_DC_PHYSDEV( dc, pPutImage );
    err = dev->funcs->pPutImage( dev, 0, 0, info, NULL, NULL, NULL, 0 );
    if (err && err != ERROR_BAD_FORMAT) goto done;

    info->bmiHeader.biSizeImage = get_dib_image_size( info );
    if (!(bits.ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, info->bmiHeader.biSizeImage )))
        goto done;
    bits.is_copy = TRUE;
    bits.free = free_heap_bits;

    /* make src and points relative to the bitmap */
    src = dst;
    src.x -= dst.visrect.left;
    src.y -= dst.visrect.top;
    offset_rect( &src.visrect, -dst.visrect.left, -dst.visrect.top );
    for (i = 0; i < nvert; i++)
    {
        pts[i].x -= dst.visrect.left;
        pts[i].y -= dst.visrect.top;
    }

    rgn = CreateRectRgn( 0, 0, 0, 0 );
    gradient_bitmapinfo( info, bits.ptr, vert_array, nvert, grad_array, ngrad, mode, pts, rgn );
    OffsetRgn( rgn, dst.visrect.left, dst.visrect.top );
    ret = !dev->funcs->pPutImage( dev, 0, rgn, info, &bits, &src, &dst, SRCCOPY );

    if (bits.free) bits.free( &bits );
    DeleteObject( rgn );

done:
    HeapFree( GetProcessHeap(), 0, pts );
    return ret;
}

COLORREF nulldrv_GetPixel( PHYSDEV dev, INT x, INT y )
{
    DC *dc = get_nulldrv_dc( dev );
    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
    BITMAPINFO *info = (BITMAPINFO *)buffer;
    struct bitblt_coords src;
    struct gdi_image_bits bits;
    COLORREF ret;

    src.visrect.left = x;
    src.visrect.top  = y;
    LPtoDP( dev->hdc, (POINT *)&src.visrect, 1 );
    src.visrect.right  = src.visrect.left + 1;
    src.visrect.bottom = src.visrect.top + 1;
    src.x = src.visrect.left;
    src.y = src.visrect.top;
    src.width = src.height = 1;

    if (!clip_visrect( dc, &src.visrect, &src.visrect )) return CLR_INVALID;

    dev = GET_DC_PHYSDEV( dc, pGetImage );
    if (dev->funcs->pGetImage( dev, 0, info, &bits, &src )) return CLR_INVALID;

    ret = get_pixel_bitmapinfo( info, bits.ptr, &src );
    if (bits.free) bits.free( &bits );
    return ret;
}


/***********************************************************************
 *           PatBlt    (GDI32.@)
 */
BOOL WINAPI PatBlt( HDC hdc, INT left, INT top, INT width, INT height, DWORD rop)
{
    DC * dc;
    BOOL ret = FALSE;

    if (rop_uses_src( rop )) return FALSE;
    if ((dc = get_dc_ptr( hdc )))
    {
        struct bitblt_coords dst;
        PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPatBlt );

        update_dc( dc );

        dst.log_x      = left;
        dst.log_y      = top;
        dst.log_width  = width;
        dst.log_height = height;
        dst.layout     = dc->layout;
        if (rop & NOMIRRORBITMAP)
        {
            dst.layout |= LAYOUT_BITMAPORIENTATIONPRESERVED;
            rop &= ~NOMIRRORBITMAP;
        }
        ret = !get_vis_rectangles( dc, &dst, NULL, NULL );

        TRACE("dst %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s  rop=%06x\n",
              hdc, dst.log_x, dst.log_y, dst.log_width, dst.log_height,
              dst.x, dst.y, dst.width, dst.height, wine_dbgstr_rect(&dst.visrect), rop );

        if (!ret) ret = physdev->funcs->pPatBlt( physdev, &dst, rop );

        release_dc_ptr( dc );
    }
    return ret;
}


/***********************************************************************
 *           BitBlt    (GDI32.@)
 */
BOOL WINAPI BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width,
                    INT height, HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop )
{
    if (!rop_uses_src( rop )) return PatBlt( hdcDst, xDst, yDst, width, height, rop );
    else return StretchBlt( hdcDst, xDst, yDst, width, height,
                            hdcSrc, xSrc, ySrc, width, height, rop );
}


/***********************************************************************
 *           StretchBlt    (GDI32.@)
 */
BOOL WINAPI StretchBlt( HDC hdcDst, INT xDst, INT yDst, INT widthDst, INT heightDst,
                        HDC hdcSrc, INT xSrc, INT ySrc, INT widthSrc, INT heightSrc, DWORD rop )
{
    BOOL ret = FALSE;
    DC *dcDst, *dcSrc;

    if (!rop_uses_src( rop )) return PatBlt( hdcDst, xDst, yDst, widthDst, heightDst, rop );

    if (!(dcDst = get_dc_ptr( hdcDst ))) return FALSE;

    if ((dcSrc = get_dc_ptr( hdcSrc )))
    {
        struct bitblt_coords src, dst;
        PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pStretchBlt );
        PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pStretchBlt );

        update_dc( dcSrc );
        update_dc( dcDst );

        src.log_x      = xSrc;
        src.log_y      = ySrc;
        src.log_width  = widthSrc;
        src.log_height = heightSrc;
        src.layout     = dcSrc->layout;
        dst.log_x      = xDst;
        dst.log_y      = yDst;
        dst.log_width  = widthDst;
        dst.log_height = heightDst;
        dst.layout     = dcDst->layout;
        if (rop & NOMIRRORBITMAP)
        {
            src.layout |= LAYOUT_BITMAPORIENTATIONPRESERVED;
            dst.layout |= LAYOUT_BITMAPORIENTATIONPRESERVED;
            rop &= ~NOMIRRORBITMAP;
        }
        ret = !get_vis_rectangles( dcDst, &dst, dcSrc, &src );

        TRACE("src %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s  dst %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s  rop=%06x\n",
              hdcSrc, src.log_x, src.log_y, src.log_width, src.log_height,
              src.x, src.y, src.width, src.height, wine_dbgstr_rect(&src.visrect),
              hdcDst, dst.log_x, dst.log_y, dst.log_width, dst.log_height,
              dst.x, dst.y, dst.width, dst.height, wine_dbgstr_rect(&dst.visrect), rop );

        if (!ret) ret = dst_dev->funcs->pStretchBlt( dst_dev, &dst, src_dev, &src, rop );
        release_dc_ptr( dcSrc );
    }
    release_dc_ptr( dcDst );
    return ret;
}

#define FRGND_ROP3(ROP4)	((ROP4) & 0x00FFFFFF)
#define BKGND_ROP3(ROP4)	(ROP3Table[((ROP4)>>24) & 0xFF])

/***********************************************************************
 *           MaskBlt [GDI32.@]
 */
BOOL WINAPI MaskBlt(HDC hdcDest, INT nXDest, INT nYDest,
                        INT nWidth, INT nHeight, HDC hdcSrc,
			INT nXSrc, INT nYSrc, HBITMAP hbmMask,
			INT xMask, INT yMask, DWORD dwRop)
{
    HBITMAP hBitmap1, hOldBitmap1, hBitmap2, hOldBitmap2;
    HDC hDC1, hDC2;
    HBRUSH hbrMask, hbrDst, hbrTmp;

    static const DWORD ROP3Table[256] = 
    {
        0x00000042, 0x00010289,
        0x00020C89, 0x000300AA,
        0x00040C88, 0x000500A9,
        0x00060865, 0x000702C5,
        0x00080F08, 0x00090245,
        0x000A0329, 0x000B0B2A,
        0x000C0324, 0x000D0B25,
        0x000E08A5, 0x000F0001,
        0x00100C85, 0x001100A6,
        0x00120868, 0x001302C8,
        0x00140869, 0x001502C9,
        0x00165CCA, 0x00171D54,
        0x00180D59, 0x00191CC8,
        0x001A06C5, 0x001B0768,
        0x001C06CA, 0x001D0766,
        0x001E01A5, 0x001F0385,
        0x00200F09, 0x00210248,
        0x00220326, 0x00230B24,
        0x00240D55, 0x00251CC5,
        0x002606C8, 0x00271868,
        0x00280369, 0x002916CA,
        0x002A0CC9, 0x002B1D58,
        0x002C0784, 0x002D060A,
        0x002E064A, 0x002F0E2A,
        0x0030032A, 0x00310B28,
        0x00320688, 0x00330008,
        0x003406C4, 0x00351864,
        0x003601A8, 0x00370388,
        0x0038078A, 0x00390604,
        0x003A0644, 0x003B0E24,
        0x003C004A, 0x003D18A4,
        0x003E1B24, 0x003F00EA,
        0x00400F0A, 0x00410249,
        0x00420D5D, 0x00431CC4,
        0x00440328, 0x00450B29,
        0x004606C6, 0x0047076A,
        0x00480368, 0x004916C5,
        0x004A0789, 0x004B0605,
        0x004C0CC8, 0x004D1954,
        0x004E0645, 0x004F0E25,
        0x00500325, 0x00510B26,
        0x005206C9, 0x00530764,
        0x005408A9, 0x00550009,
        0x005601A9, 0x00570389,
        0x00580785, 0x00590609,
        0x005A0049, 0x005B18A9,
        0x005C0649, 0x005D0E29,
        0x005E1B29, 0x005F00E9,
        0x00600365, 0x006116C6,
        0x00620786, 0x00630608,
        0x00640788, 0x00650606,
        0x00660046, 0x006718A8,
        0x006858A6, 0x00690145,
        0x006A01E9, 0x006B178A,
        0x006C01E8, 0x006D1785,
        0x006E1E28, 0x006F0C65,
        0x00700CC5, 0x00711D5C,
        0x00720648, 0x00730E28,
        0x00740646, 0x00750E26,
        0x00761B28, 0x007700E6,
        0x007801E5, 0x00791786,
        0x007A1E29, 0x007B0C68,
        0x007C1E24, 0x007D0C69,
        0x007E0955, 0x007F03C9,
        0x008003E9, 0x00810975,
        0x00820C49, 0x00831E04,
        0x00840C48, 0x00851E05,
        0x008617A6, 0x008701C5,
        0x008800C6, 0x00891B08,
        0x008A0E06, 0x008B0666,
        0x008C0E08, 0x008D0668,
        0x008E1D7C, 0x008F0CE5,
        0x00900C45, 0x00911E08,
        0x009217A9, 0x009301C4,
        0x009417AA, 0x009501C9,
        0x00960169, 0x0097588A,
        0x00981888, 0x00990066,
        0x009A0709, 0x009B07A8,
        0x009C0704, 0x009D07A6,
        0x009E16E6, 0x009F0345,
        0x00A000C9, 0x00A11B05,
        0x00A20E09, 0x00A30669,
        0x00A41885, 0x00A50065,
        0x00A60706, 0x00A707A5,
        0x00A803A9, 0x00A90189,
        0x00AA0029, 0x00AB0889,
        0x00AC0744, 0x00AD06E9,
        0x00AE0B06, 0x00AF0229,
        0x00B00E05, 0x00B10665,
        0x00B21974, 0x00B30CE8,
        0x00B4070A, 0x00B507A9,
        0x00B616E9, 0x00B70348,
        0x00B8074A, 0x00B906E6,
        0x00BA0B09, 0x00BB0226,
        0x00BC1CE4, 0x00BD0D7D,
        0x00BE0269, 0x00BF08C9,
        0x00C000CA, 0x00C11B04,
        0x00C21884, 0x00C3006A,
        0x00C40E04, 0x00C50664,
        0x00C60708, 0x00C707AA,
        0x00C803A8, 0x00C90184,
        0x00CA0749, 0x00CB06E4,
        0x00CC0020, 0x00CD0888,
        0x00CE0B08, 0x00CF0224,
        0x00D00E0A, 0x00D1066A,
        0x00D20705, 0x00D307A4,
        0x00D41D78, 0x00D50CE9,
        0x00D616EA, 0x00D70349,
        0x00D80745, 0x00D906E8,
        0x00DA1CE9, 0x00DB0D75,
        0x00DC0B04, 0x00DD0228,
        0x00DE0268, 0x00DF08C8,
        0x00E003A5, 0x00E10185,
        0x00E20746, 0x00E306EA,
        0x00E40748, 0x00E506E5,
        0x00E61CE8, 0x00E70D79,
        0x00E81D74, 0x00E95CE6,
        0x00EA02E9, 0x00EB0849,
        0x00EC02E8, 0x00ED0848,
        0x00EE0086, 0x00EF0A08,
        0x00F00021, 0x00F10885,
        0x00F20B05, 0x00F3022A,
        0x00F40B0A, 0x00F50225,
        0x00F60265, 0x00F708C5,
        0x00F802E5, 0x00F90845,
        0x00FA0089, 0x00FB0A09,
        0x00FC008A, 0x00FD0A0A,
        0x00FE02A9, 0x00FF0062,
    };

    if (!hbmMask)
	return BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));

    hbrMask = CreatePatternBrush(hbmMask);
    hbrDst = SelectObject(hdcDest, GetStockObject(NULL_BRUSH));

    /* make bitmap */
    hDC1 = CreateCompatibleDC(hdcDest);
    hBitmap1 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
    hOldBitmap1 = SelectObject(hDC1, hBitmap1);

    /* draw using bkgnd rop */
    BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
    hbrTmp = SelectObject(hDC1, hbrDst);
    BitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, BKGND_ROP3(dwRop));
    SelectObject(hDC1, hbrTmp);

    /* make bitmap */
    hDC2 = CreateCompatibleDC(hdcDest);
    hBitmap2 = CreateCompatibleBitmap(hdcDest, nWidth, nHeight);
    hOldBitmap2 = SelectObject(hDC2, hBitmap2);

    /* draw using foregnd rop */
    BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
    hbrTmp = SelectObject(hDC2, hbrDst);
    BitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop));

    /* combine both using the mask as a pattern brush */
    SelectObject(hDC2, hbrMask);
    BitBlt(hDC2, 0, 0, nWidth, nHeight, hDC1, 0, 0, 0xac0744 ); /* (D & P) | (S & ~P) */ 
    SelectObject(hDC2, hbrTmp);

    /* blit to dst */
    BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC2, 0, 0, SRCCOPY);

    /* restore all objects */
    SelectObject(hdcDest, hbrDst);
    SelectObject(hDC1, hOldBitmap1);
    SelectObject(hDC2, hOldBitmap2);

    /* delete all temp objects */
    DeleteObject(hBitmap1);
    DeleteObject(hBitmap2);
    DeleteObject(hbrMask);

    DeleteDC(hDC1);
    DeleteDC(hDC2);

    return TRUE;
}

/******************************************************************************
 *           GdiTransparentBlt [GDI32.@]
 */
BOOL WINAPI GdiTransparentBlt( HDC hdcDest, int xDest, int yDest, int widthDest, int heightDest,
                            HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
                            UINT crTransparent )
{
    BOOL ret = FALSE;
    HDC hdcWork;
    HBITMAP bmpWork;
    HGDIOBJ oldWork;
    HDC hdcMask = NULL;
    HBITMAP bmpMask = NULL;
    HBITMAP oldMask = NULL;
    COLORREF oldBackground;
    COLORREF oldForeground;
    int oldStretchMode;

    if(widthDest < 0 || heightDest < 0 || widthSrc < 0 || heightSrc < 0) {
        TRACE("Cannot mirror\n");
        return FALSE;
    }

    oldBackground = SetBkColor(hdcDest, RGB(255,255,255));
    oldForeground = SetTextColor(hdcDest, RGB(0,0,0));

    /* Stretch bitmap */
    oldStretchMode = GetStretchBltMode(hdcSrc);
    if(oldStretchMode == BLACKONWHITE || oldStretchMode == WHITEONBLACK)
        SetStretchBltMode(hdcSrc, COLORONCOLOR);
    hdcWork = CreateCompatibleDC(hdcDest);
    bmpWork = CreateCompatibleBitmap(hdcDest, widthDest, heightDest);
    oldWork = SelectObject(hdcWork, bmpWork);
    if(!StretchBlt(hdcWork, 0, 0, widthDest, heightDest, hdcSrc, xSrc, ySrc, widthSrc, heightSrc, SRCCOPY)) {
        TRACE("Failed to stretch\n");
        goto error;
    }
    SetBkColor(hdcWork, crTransparent);

    /* Create mask */
    hdcMask = CreateCompatibleDC(hdcDest);
    bmpMask = CreateCompatibleBitmap(hdcMask, widthDest, heightDest);
    oldMask = SelectObject(hdcMask, bmpMask);
    if(!BitBlt(hdcMask, 0, 0, widthDest, heightDest, hdcWork, 0, 0, SRCCOPY)) {
        TRACE("Failed to create mask\n");
        goto error;
    }

    /* Replace transparent color with black */
    SetBkColor(hdcWork, RGB(0,0,0));
    SetTextColor(hdcWork, RGB(255,255,255));
    if(!BitBlt(hdcWork, 0, 0, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
        TRACE("Failed to mask out background\n");
        goto error;
    }

    /* Replace non-transparent area on destination with black */
    if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcMask, 0, 0, SRCAND)) {
        TRACE("Failed to clear destination area\n");
        goto error;
    }

    /* Draw the image */
    if(!BitBlt(hdcDest, xDest, yDest, widthDest, heightDest, hdcWork, 0, 0, SRCPAINT)) {
        TRACE("Failed to paint image\n");
        goto error;
    }

    ret = TRUE;
error:
    SetStretchBltMode(hdcSrc, oldStretchMode);
    SetBkColor(hdcDest, oldBackground);
    SetTextColor(hdcDest, oldForeground);
    if(hdcWork) {
        SelectObject(hdcWork, oldWork);
        DeleteDC(hdcWork);
    }
    if(bmpWork) DeleteObject(bmpWork);
    if(hdcMask) {
        SelectObject(hdcMask, oldMask);
        DeleteDC(hdcMask);
    }
    if(bmpMask) DeleteObject(bmpMask);
    return ret;
}

/******************************************************************************
 *           GdiAlphaBlend [GDI32.@]
 */
BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst,
                          HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc,
                          BLENDFUNCTION blendFunction)
{
    BOOL ret = FALSE;
    DC *dcDst, *dcSrc;

    dcSrc = get_dc_ptr( hdcSrc );
    if (!dcSrc) return FALSE;

    if ((dcDst = get_dc_ptr( hdcDst )))
    {
        struct bitblt_coords src, dst;
        PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pAlphaBlend );
        PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pAlphaBlend );

        update_dc( dcSrc );
        update_dc( dcDst );

        src.log_x      = xSrc;
        src.log_y      = ySrc;
        src.log_width  = widthSrc;
        src.log_height = heightSrc;
        src.layout     = GetLayout( src_dev->hdc );
        dst.log_x      = xDst;
        dst.log_y      = yDst;
        dst.log_width  = widthDst;
        dst.log_height = heightDst;
        dst.layout     = GetLayout( dst_dev->hdc );
        ret = !get_vis_rectangles( dcDst, &dst, dcSrc, &src );

        TRACE("src %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s  dst %p log=%d,%d %dx%d phys=%d,%d %dx%d vis=%s  blend=%02x/%02x/%02x/%02x\n",
              hdcSrc, src.log_x, src.log_y, src.log_width, src.log_height,
              src.x, src.y, src.width, src.height, wine_dbgstr_rect(&src.visrect),
              hdcDst, dst.log_x, dst.log_y, dst.log_width, dst.log_height,
              dst.x, dst.y, dst.width, dst.height, wine_dbgstr_rect(&dst.visrect),
              blendFunction.BlendOp, blendFunction.BlendFlags,
              blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat );

        if (src.x < 0 || src.y < 0 || src.width < 0 || src.height < 0 ||
            src.log_width < 0 || src.log_height < 0 ||
            (dcSrc->header.type == OBJ_MEMDC &&
             (src.width > dcSrc->vis_rect.right - dcSrc->vis_rect.left - src.x ||
              src.height > dcSrc->vis_rect.bottom - dcSrc->vis_rect.top - src.y)))
        {
            WARN( "Invalid src coords: (%d,%d), size %dx%d\n", src.x, src.y, src.width, src.height );
            SetLastError( ERROR_INVALID_PARAMETER );
            ret = FALSE;
        }
        else if (dst.log_width < 0 || dst.log_height < 0)
        {
            WARN( "Invalid dst coords: (%d,%d), size %dx%d\n",
                  dst.log_x, dst.log_y, dst.log_width, dst.log_height );
            SetLastError( ERROR_INVALID_PARAMETER );
            ret = FALSE;
        }
        else if (dcSrc == dcDst && src.x + src.width > dst.x && src.x < dst.x + dst.width &&
                 src.y + src.height > dst.y && src.y < dst.y + dst.height)
        {
            WARN( "Overlapping coords: (%d,%d), %dx%d and (%d,%d), %dx%d\n",
                  src.x, src.y, src.width, src.height, dst.x, dst.y, dst.width, dst.height );
            SetLastError( ERROR_INVALID_PARAMETER );
            ret = FALSE;
        }
        else if (!ret) ret = dst_dev->funcs->pAlphaBlend( dst_dev, &dst, src_dev, &src, blendFunction );

        release_dc_ptr( dcDst );
    }
    release_dc_ptr( dcSrc );
    return ret;
}

/*********************************************************************
 *      PlgBlt [GDI32.@]
 *
 */
BOOL WINAPI PlgBlt( HDC hdcDest, const POINT *lpPoint,
                        HDC hdcSrc, INT nXSrc, INT nYSrc, INT nWidth,
                        INT nHeight, HBITMAP hbmMask, INT xMask, INT yMask)
{
    int oldgMode;
    /* parallelogram coords */
    POINT plg[3];
    /* rect coords */
    POINT rect[3];
    XFORM xf;
    XFORM SrcXf;
    XFORM oldDestXf;
    double det;

    /* save actual mode, set GM_ADVANCED */
    oldgMode = SetGraphicsMode(hdcDest,GM_ADVANCED);
    if (oldgMode == 0)
        return FALSE;

    memcpy(plg,lpPoint,sizeof(POINT)*3);
    rect[0].x = nXSrc;
    rect[0].y = nYSrc;
    rect[1].x = nXSrc + nWidth;
    rect[1].y = nYSrc;
    rect[2].x = nXSrc;
    rect[2].y = nYSrc + nHeight;
    /* calc XFORM matrix to transform hdcDest -> hdcSrc (parallelogram to rectangle) */
    /* determinant */
    det = rect[1].x*(rect[2].y - rect[0].y) - rect[2].x*(rect[1].y - rect[0].y) - rect[0].x*(rect[2].y - rect[1].y);

    if (fabs(det) < 1e-5)
    {
        SetGraphicsMode(hdcDest,oldgMode);
        return FALSE;
    }

    TRACE("hdcSrc=%p %d,%d,%dx%d -> hdcDest=%p %d,%d,%d,%d,%d,%d\n",
        hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hdcDest, plg[0].x, plg[0].y, plg[1].x, plg[1].y, plg[2].x, plg[2].y);

    /* X components */
    xf.eM11 = (plg[1].x*(rect[2].y - rect[0].y) - plg[2].x*(rect[1].y - rect[0].y) - plg[0].x*(rect[2].y - rect[1].y)) / det;
    xf.eM21 = (rect[1].x*(plg[2].x - plg[0].x) - rect[2].x*(plg[1].x - plg[0].x) - rect[0].x*(plg[2].x - plg[1].x)) / det;
    xf.eDx  = (rect[0].x*(rect[1].y*plg[2].x - rect[2].y*plg[1].x) -
               rect[1].x*(rect[0].y*plg[2].x - rect[2].y*plg[0].x) +
               rect[2].x*(rect[0].y*plg[1].x - rect[1].y*plg[0].x)
               ) / det;

    /* Y components */
    xf.eM12 = (plg[1].y*(rect[2].y - rect[0].y) - plg[2].y*(rect[1].y - rect[0].y) - plg[0].y*(rect[2].y - rect[1].y)) / det;
    xf.eM22 = (plg[1].x*(rect[2].y - rect[0].y) - plg[2].x*(rect[1].y - rect[0].y) - plg[0].x*(rect[2].y - rect[1].y)) / det;
    xf.eDy  = (rect[0].x*(rect[1].y*plg[2].y - rect[2].y*plg[1].y) -
               rect[1].x*(rect[0].y*plg[2].y - rect[2].y*plg[0].y) +
               rect[2].x*(rect[0].y*plg[1].y - rect[1].y*plg[0].y)
               ) / det;

    GetWorldTransform(hdcSrc,&SrcXf);
    CombineTransform(&xf,&xf,&SrcXf);

    /* save actual dest transform */
    GetWorldTransform(hdcDest,&oldDestXf);

    SetWorldTransform(hdcDest,&xf);
    /* now destination and source DCs use same coords */
    MaskBlt(hdcDest,nXSrc,nYSrc,nWidth,nHeight,
            hdcSrc, nXSrc,nYSrc,
            hbmMask,xMask,yMask,
            SRCCOPY);
    /* restore dest DC */
    SetWorldTransform(hdcDest,&oldDestXf);
    SetGraphicsMode(hdcDest,oldgMode);

    return TRUE;
}
