/*
 * 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;
    lp_to_dp( dc_dst, (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;
    lp_to_dp( dc_src, (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 );

    if (!clip_device_rect( dc_src, &src->visrect, &rect )) 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 )
{
    void *ptr;
    DWORD err;
    BOOL top_down = dst_info->bmiHeader.biHeight < 0;

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

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

    err = convert_bitmapinfo( src_info, bits->ptr, src, dst_info, ptr );
    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 );
}

static RGBQUAD get_dc_rgb_color( DC *dc, int color_table_size, COLORREF color )
{
    RGBQUAD ret = { 0, 0, 0, 0 };

    if (color & (1 << 24))  /* PALETTEINDEX */
    {
        PALETTEENTRY pal;

        if (!GetPaletteEntries( dc->hPalette, LOWORD(color), 1, &pal ))
            GetPaletteEntries( dc->hPalette, 0, 1, &pal );
        ret.rgbRed   = pal.peRed;
        ret.rgbGreen = pal.peGreen;
        ret.rgbBlue  = pal.peBlue;
        return ret;
    }
    if (color >> 16 == 0x10ff)  /* DIBINDEX */
    {
        if (color_table_size)
        {
            if (LOWORD(color) >= color_table_size) color = 0x10ff0000;  /* fallback to index 0 */
            *(DWORD *)&ret = color;
        }
        return ret;
    }
    ret.rgbRed   = GetRValue( color );
    ret.rgbGreen = GetGValue( color );
    ret.rgbBlue  = GetBValue( color );
    return ret;
}

/* helper to retrieve either both colors or only the background color for monochrome blits */
void get_mono_dc_colors( DC *dc, int color_table_size, BITMAPINFO *info, int count )
{
    info->bmiColors[count - 1] = get_dc_rgb_color( dc, color_table_size, dc->backgroundColor );
    if (count > 1) info->bmiColors[0] = get_dc_rgb_color( dc, color_table_size, dc->textColor );
    info->bmiHeader.biClrUsed = count;
}

/***********************************************************************
 *           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 = get_physdev_dc( src_dev ), *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;

    src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
    if (src_dev->funcs->pGetImage( src_dev, src_info, &bits, src ))
        return FALSE;

    dst_dev = GET_DC_PHYSDEV( dc_dst, pPutImage );
    copy_bitmapinfo( dst_info, src_info );
    err = dst_dev->funcs->pPutImage( dst_dev, 0, dst_info, &bits, src, dst, rop );
    if (err == ERROR_BAD_FORMAT)
    {
        DWORD dst_colors = dst_info->bmiHeader.biClrUsed;

        /* 1-bpp source without a color table uses the destination DC colors */
        if (src_info->bmiHeader.biBitCount == 1 && !src_info->bmiHeader.biClrUsed)
            get_mono_dc_colors( dc_dst, dst_info->bmiHeader.biClrUsed, src_info, 2 );

        /* 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_colors)
            get_mono_dc_colors( dc_src, src_info->bmiHeader.biClrUsed, dst_info, 1 );

        if (!(err = convert_bits( src_info, src, dst_info, &bits )))
        {
            /* get rid of the fake destination table */
            dst_info->bmiHeader.biClrUsed = dst_colors;
            err = dst_dev->funcs->pPutImage( dst_dev, 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, dc_dst->stretchBltMode );
        if (!err) err = dst_dev->funcs->pPutImage( dst_dev, 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 = get_physdev_dc( src_dev ), *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;

    src_dev = GET_DC_PHYSDEV( dc_src, pGetImage );
    err = src_dev->funcs->pGetImage( src_dev, src_info, &bits, 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 );
        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;
    DWORD *masks = (DWORD *)info->bmiColors;
    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)
    {
        if (blend.AlphaFormat & AC_SRC_ALPHA) return ERROR_INVALID_PARAMETER;
        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, 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, 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_BITFIELDS;
    info->bmiHeader.biClrUsed     = 0;
    masks[0] = 0xff0000;
    masks[1] = 0x00ff00;
    masks[2] = 0x0000ff;
    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;
    }
    lp_to_dp( dc, pts, nvert );

    /* compute bounding rect of all the rectangles/triangles */
    reset_bounds( &dst.visrect );
    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, 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, 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;
    lp_to_dp( dc, (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, 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;

        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)
        {
            PHYSDEV physdev = GET_DC_PHYSDEV( dc, pPatBlt );
            ret = physdev->funcs->pPatBlt( physdev, &dst, rop );
        }
        release_dc_ptr( dc );
    }
    return ret;
}


/***********************************************************************
 *           BitBlt    (GDI32.@)
 */
BOOL WINAPI DECLSPEC_HOTPATCH 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;

        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)
        {
            PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pStretchBlt );
            PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pStretchBlt );
            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);
    SetBrushOrgEx(hDC2, -xMask, -yMask, NULL);
    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;
    DIBSECTION dib;

    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);
    if ((GetObjectType( hdcDest ) != OBJ_MEMDC ||
         GetObjectW( GetCurrentObject( hdcDest, OBJ_BITMAP ), sizeof(dib), &dib ) == sizeof(BITMAP)) &&
        GetDeviceCaps( hdcDest, BITSPIXEL ) == 32)
    {
        /* screen DCs or DDBs are not supposed to have an alpha channel, so use a 24-bpp bitmap as copy */
        BITMAPINFO info;
        info.bmiHeader.biSize = sizeof(info.bmiHeader);
        info.bmiHeader.biWidth = widthDest;
        info.bmiHeader.biHeight = heightDest;
        info.bmiHeader.biPlanes = 1;
        info.bmiHeader.biBitCount = 24;
        info.bmiHeader.biCompression = BI_RGB;
        bmpWork = CreateDIBSection( 0, &info, DIB_RGB_COLORS, NULL, NULL, 0 );
    }
    else 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;

        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;
        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 ||
            (!is_rect_empty( &dcSrc->device_rect ) &&
             (src.width > dcSrc->device_rect.right - dcSrc->vis_rect.left - src.x ||
              src.height > dcSrc->device_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)
        {
            PHYSDEV src_dev = GET_DC_PHYSDEV( dcSrc, pAlphaBlend );
            PHYSDEV dst_dev = GET_DC_PHYSDEV( dcDst, pAlphaBlend );
            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 = (rect[1].x*(plg[2].y - plg[0].y) - rect[2].x*(plg[1].y - plg[0].y) - rect[0].x*(plg[2].y - plg[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;
}
