Exemple #1
0
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 );

    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 );
}
Exemple #2
0
/***********************************************************************
 *           GetClipBox    (GDI32.@)
 */
INT WINAPI GetClipBox( HDC hdc, LPRECT rect )
{
    RECT visrect;
    INT ret;
    DC *dc = get_dc_ptr( hdc );
    if (!dc) return ERROR;

    update_dc( dc );
    if (get_dc_region( dc ))
    {
        ret = GetRgnBox( get_dc_region( dc ), rect );
    }
    else
    {
        ret = is_rect_empty( &dc->vis_rect ) ? ERROR : SIMPLEREGION;
        *rect = dc->vis_rect;
    }

    if (get_dc_device_rect( dc, &visrect ) && !intersect_rect( rect, rect, &visrect )) ret = NULLREGION;

    if (dc->layout & LAYOUT_RTL)
    {
        int tmp = rect->left;
        rect->left = rect->right - 1;
        rect->right = tmp - 1;
    }
    DPtoLP( hdc, (LPPOINT)rect, 2 );
    release_dc_ptr( dc );
    TRACE("%p => %d %s\n", hdc, ret, wine_dbgstr_rect( rect ));
    return ret;
}
Exemple #3
0
int clip_rect_to_dib( const dib_info *dib, RECT *rc )
{
    RECT rect;

    rect.left   = max( 0, -dib->rect.left );
    rect.top    = max( 0, -dib->rect.top );
    rect.right  = min( dib->rect.right, dib->width ) - dib->rect.left;
    rect.bottom = min( dib->rect.bottom, dib->height ) - dib->rect.top;
    if (is_rect_empty( &rect )) return 0;
    return intersect_rect( rc, &rect, rc );
}
Exemple #4
0
/***********************************************************************
 * GetRandomRgn [GDI32.@]
 *
 * NOTES
 *     This function is documented in MSDN online for the case of
 *     iCode == SYSRGN (4).
 *
 *     For iCode == 1 it should return the clip region
 *                  2 "    "       "   the meta region
 *                  3 "    "       "   the intersection of the clip with
 *                                     the meta region (== 'Rao' region).
 *
 *     See http://www.codeproject.com/gdi/cliprgnguide.asp
 */
INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
{
    INT ret = 1;
    DC *dc = get_dc_ptr( hDC );

    if (!dc) return -1;

    switch (iCode)
    {
    case 1:
        if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
        else ret = 0;
        break;
    case 2:
        if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
        else ret = 0;
        break;
    case 3:
        if (dc->hClipRgn && dc->hMetaRgn) CombineRgn( hRgn, dc->hClipRgn, dc->hMetaRgn, RGN_AND );
        else if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
        else if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
        else ret = 0;
        break;
    case SYSRGN: /* == 4 */
        update_dc( dc );
        if (dc->hVisRgn)
        {
            CombineRgn( hRgn, dc->hVisRgn, 0, RGN_COPY );
            /* On Windows NT/2000, the SYSRGN returned is in screen coordinates */
            if (!(GetVersion() & 0x80000000)) OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top );
        }
        else if (!is_rect_empty( &dc->device_rect ))
            SetRectRgn( hRgn, dc->device_rect.left, dc->device_rect.top,
                        dc->device_rect.right, dc->device_rect.bottom );
        else
            ret = 0;
        break;
    default:
        WARN("Unknown code %d\n", iCode);
        ret = -1;
        break;
    }
    release_dc_ptr( dc );
    return ret;
}
Exemple #5
0
void add_clipped_bounds( dibdrv_physdev *dev, const RECT *rect, HRGN clip )
{
    const WINEREGION *region;
    RECT rc;

    if (!dev->bounds) return;
    if (clip)
    {
        if (!(region = get_wine_region( clip ))) return;
        if (!rect) rc = region->extents;
        else intersect_rect( &rc, rect, &region->extents );
        release_wine_region( clip );
    }
    else rc = *rect;

    if (is_rect_empty( &rc )) return;
    offset_rect( &rc, dev->dib.rect.left, dev->dib.rect.top );
    add_bounds_rect( dev->bounds, &rc );
}
Exemple #6
0
int get_clipped_rects( const dib_info *dib, const RECT *rc, HRGN clip, struct clipped_rects *clip_rects )
{
    const WINEREGION *region;
    RECT rect, *out = clip_rects->buffer;
    int i;

    init_clipped_rects( clip_rects );

    rect.left   = max( 0, -dib->rect.left );
    rect.top    = max( 0, -dib->rect.top );
    rect.right  = min( dib->rect.right, dib->width ) - dib->rect.left;
    rect.bottom = min( dib->rect.bottom, dib->height ) - dib->rect.top;
    if (is_rect_empty( &rect )) return 0;
    if (rc && !intersect_rect( &rect, &rect, rc )) return 0;

    if (!clip)
    {
        *out = rect;
        clip_rects->count = 1;
        return 1;
    }

    if (!(region = get_wine_region( clip ))) return 0;

    for (i = 0; i < region->numRects; i++)
    {
        if (region->rects[i].top >= rect.bottom) break;
        if (!intersect_rect( out, &rect, &region->rects[i] )) continue;
        out++;
        if (out == &clip_rects->buffer[sizeof(clip_rects->buffer) / sizeof(RECT)])
        {
            clip_rects->rects = HeapAlloc( GetProcessHeap(), 0, region->numRects * sizeof(RECT) );
            if (!clip_rects->rects) return 0;
            memcpy( clip_rects->rects, clip_rects->buffer, (out - clip_rects->buffer) * sizeof(RECT) );
            out = clip_rects->rects + (out - clip_rects->buffer);
        }
    }
    release_wine_region( clip );
    clip_rects->count = out - clip_rects->rects;
    return clip_rects->count;
}
Exemple #7
0
/******************************************************************************
 *           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     = GetLayout( hdcSrc );
        dst.log_x      = xDst;
        dst.log_y      = yDst;
        dst.log_width  = widthDst;
        dst.log_height = heightDst;
        dst.layout     = GetLayout( hdcDst );
        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;
}
Exemple #8
0
/* return the DC device rectangle if not empty */
static inline BOOL get_dc_device_rect( DC *dc, RECT *rect )
{
    *rect = dc->device_rect;
    offset_rect( rect, -dc->vis_rect.left, -dc->vis_rect.top );
    return !is_rect_empty( rect );
}
Exemple #9
0
static inline void lock_surface( struct windrv_physdev *dev )
{
    GDI_CheckNotLock();
    dev->surface->funcs->lock( dev->surface );
    if (is_rect_empty( dev->dibdrv->bounds )) dev->start_ticks = GetTickCount();
}