Пример #1
0
void Test_GetClipRgn()
{
	HWND hWnd;
	HDC hDC;
	HRGN hrgn;//, hrgn2;
	int ret;

	/* Create a window */
	hWnd = CreateWindowW(L"BUTTON", L"TestWindow", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
	                    CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
	                    NULL, NULL, 0, 0);

	hDC = GetDC(hWnd);
	hrgn = CreateRectRgn(0,0,0,0);

	/* Test invalid DC */
	SetLastError(ERROR_SUCCESS);
	ret = GetClipRgn((HDC)0x12345, hrgn);
	ok(ret == -1, "Expected -1, got %d\n", ret);
	ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());

	/* Test invalid hrgn */
	SetLastError(ERROR_SUCCESS);
	ret = GetClipRgn(hDC, (HRGN)0x12345);
	ok(ret == 0, "Expected 0, got %d\n", ret);
	ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %ld\n", GetLastError());

	ReleaseDC(hWnd, hDC);
	DestroyWindow(hWnd);
}
Пример #2
0
static void test_memory_dc_clipping(void)
{
    HDC hdc;
    HRGN hrgn, hrgn_empty;
    HBITMAP hbmp;
    RECT rc;
    int ret;

    hdc = CreateCompatibleDC(0);
    hrgn_empty = CreateRectRgn(0, 0, 0, 0);
    hrgn = CreateRectRgn(0, 0, 0, 0);
    hbmp = CreateCompatibleBitmap(hdc, 100, 100);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "expected 0, got %d\n", ret);

    ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 1, "expected 1, got %d\n", ret);

    ret = GetRgnBox(hrgn, &rc);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
    ok(rc.left == 0 && rc.top == 0 && rc.right == 1 && rc.bottom == 1,
       "expected 0,0-1,1, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);

    ret = ExtSelectClipRgn(hdc, 0, RGN_COPY);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "expected 0, got %d\n", ret);

    SelectObject(hdc, hbmp);

    ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 1, "expected 1, got %d\n", ret);

    ret = GetRgnBox(hrgn, &rc);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
    ok(rc.left == 0 && rc.top == 0 && rc.right == 100 && rc.bottom == 100,
       "expected 0,0-100,100, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);

    DeleteDC(hdc);
    DeleteObject(hrgn);
    DeleteObject(hrgn_empty);
    DeleteObject(hbmp);
}
Пример #3
0
static void test_window_dc_clipping(void)
{
    HDC hdc;
    HRGN hrgn, hrgn_empty;
    HWND hwnd;
    RECT rc;
    int ret, screen_width, screen_height;

    /* Windows versions earlier than Win2k do not support the virtual screen metrics,
     * so we fall back to the primary screen metrics. */
    screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    if(!screen_width) screen_width = GetSystemMetrics(SM_CXSCREEN);
    screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    if(!screen_height) screen_height = GetSystemMetrics(SM_CYSCREEN);

    trace("screen resolution %d x %d\n", screen_width, screen_height);

    hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
                           -100, -100, screen_width * 2, screen_height * 2, 0, 0, 0, NULL);
    hdc = GetWindowDC(0);
    hrgn_empty = CreateRectRgn(0, 0, 0, 0);
    hrgn = CreateRectRgn(0, 0, 0, 0);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "expected 0, got %d\n", ret);

    ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
    ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
       "expected SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 1, "expected 1, got %d\n", ret);

    ret = GetRgnBox(hrgn, &rc);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
    ok(rc.left == 0 && rc.top == 0 && rc.right == screen_width && rc.bottom == screen_height,
       "expected 0,0-%d,%d, got %d,%d-%d,%d\n", screen_width, screen_height,
        rc.left, rc.top, rc.right, rc.bottom);

    ret = ExtSelectClipRgn(hdc, 0, RGN_COPY);
    ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
       "expected SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "expected 0, got %d\n", ret);

    DeleteDC(hdc);
    DeleteObject(hrgn);
    DeleteObject(hrgn_empty);
    DestroyWindow(hwnd);
}
Пример #4
0
	void DrawOnRichEdit(void)
	{ 
		HDC hdc = GetDC(m_hwnd);
		if (RectVisible(hdc, &m_orect)) {
			RECT crct;
			GetClientRect(m_hwnd, &crct);

			HRGN hrgnOld = CreateRectRgnIndirect(&crct);
			int res = GetClipRgn(hdc, hrgnOld);

			HRGN hrgn = CreateRectRgnIndirect(&crct); 
			SelectClipRgn(hdc, hrgn); 
			DeleteObject(hrgn);

			DoDirectDraw(hdc);

			SelectClipRgn(hdc, res < 1 ? NULL : hrgnOld); 
			DeleteObject(hrgnOld);
		}
		else {
			m_visible = false;
			m_allowAni = false;
			UnloadSmiley();
		}
		ReleaseDC(m_hwnd, hdc);
	}
Пример #5
0
	void Unlock(bool p_update)
	{
		if (m_bitmap == nil)
			return;

		if (p_update)
		{
			if (m_mask != nil)
				MCWin32ApplyMaskToRasterRegion(m_raster, m_area.x, m_area.y, *m_mask, m_redraw_region);

			HDC t_src_dc = ((MCScreenDC *)MCscreen) -> getsrchdc();

			HGDIOBJ t_old_object;
			HRGN t_old_clip;

			t_old_clip = CreateRectRgn(0, 0, 0, 0);
			GetClipRgn(m_dc, t_old_clip);
			t_old_object = SelectObject(t_src_dc, m_bitmap);
			SelectClipRgn(m_dc, (HRGN)m_redraw_region);

			BitBlt(m_dc, m_area . x, m_area . y, m_area . width, m_area . height, t_src_dc, 0, 0, SRCCOPY);

			SelectClipRgn(m_dc, t_old_clip);
			SelectObject(t_src_dc, t_old_object);

			DeleteObject(t_old_clip);
		}

		DeleteObject(m_redraw_region);
		DeleteObject(m_bitmap);
		m_bitmap = nil;
	}
static cairo_int_status_t
_cairo_win32_save_initial_clip (HDC hdc, cairo_win32_display_surface_t *surface)
{
    RECT rect;
    int clipBoxType;
    int gm;
    XFORM saved_xform;

    /* GetClipBox/GetClipRgn and friends interact badly with a world transform
     * set.  GetClipBox returns values in logical (transformed) coordinates;
     * it's unclear what GetClipRgn returns, because the region is empty in the
     * case of a SIMPLEREGION clip, but I assume device (untransformed) coordinates.
     * Similarly, IntersectClipRect works in logical units, whereas SelectClipRgn
     * works in device units.
     *
     * So, avoid the whole mess and get rid of the world transform
     * while we store our initial data and when we restore initial coordinates.
     *
     * XXX we may need to modify x/y by the ViewportOrg or WindowOrg
     * here in GM_COMPATIBLE; unclear.
     */
    gm = GetGraphicsMode (hdc);
    if (gm == GM_ADVANCED) {
	GetWorldTransform (hdc, &saved_xform);
	ModifyWorldTransform (hdc, NULL, MWT_IDENTITY);
    }

    clipBoxType = GetClipBox (hdc, &rect);
    if (clipBoxType == ERROR) {
	_cairo_win32_print_gdi_error (__FUNCTION__);
	SetGraphicsMode (hdc, gm);
	/* XXX: Can we make a more reasonable guess at the error cause here? */
	return _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
    }

    surface->win32.extents.x = rect.left;
    surface->win32.extents.y = rect.top;
    surface->win32.extents.width = rect.right - rect.left;
    surface->win32.extents.height = rect.bottom - rect.top;

    surface->initial_clip_rgn = NULL;
    surface->had_simple_clip = FALSE;

    if (clipBoxType == COMPLEXREGION) {
	surface->initial_clip_rgn = CreateRectRgn (0, 0, 0, 0);
	if (GetClipRgn (hdc, surface->initial_clip_rgn) <= 0) {
	    DeleteObject(surface->initial_clip_rgn);
	    surface->initial_clip_rgn = NULL;
	}
    } else if (clipBoxType == SIMPLEREGION) {
	surface->had_simple_clip = TRUE;
    }

    if (gm == GM_ADVANCED)
	SetWorldTransform (hdc, &saved_xform);

    return CAIRO_STATUS_SUCCESS;
}
Пример #7
0
/***********************************************************************
 *           PSDRV_ResetClip
 */
void PSDRV_ResetClip( PHYSDEV dev )
{
    PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
    HRGN hrgn = CreateRectRgn(0,0,0,0);
    BOOL empty;

    empty = !GetClipRgn(dev->hdc, hrgn);
    if(!empty && !physDev->pathdepth)
        PSDRV_WriteGRestore(dev);
    DeleteObject(hrgn);
}
Пример #8
0
//
//	UspAttrTextOut
//
//	Display a line of text previously analyzed with UspAnalyze. The stored
//	ATTR[] visual-attribute list is used to stylize the text as it is drawn.
//  
//	Coloured text-display using Uniscribe is very complicated. 
//  Three passes are required if high-quality text output is the goal.
//
//	Returns: adjusted x-coordinate 
//
int WINAPI UspTextOut (
		USPDATA  *	uspData,
		HDC			hdc, 
		int			xpos, 
		int			ypos, 
		int			lineHeight,
		int			lineAdjustY,
		RECT	 *	bounds
	)
{
	HRGN hrgn, hrgnClip;

	if(uspData->stringLen == 0 || uspData->glyphCount == 0)
		return xpos;

	hrgnClip = CreateRectRgn(0,0,1,1); 
	GetClipRgn(hdc, hrgnClip);

	//
	//	1. draw all background colours, including selection-highlights;
	//	   selected areas are added to the HDC clipping region which prevents
	//	   step#2 (below) from drawing over them
	//
	SetBkMode(hdc, OPAQUE);
	PaintBackground(uspData, hdc, xpos, ypos, lineHeight, bounds);

	//
	//  2. draw the text normally. Selected areas are left untouched
	//	   because of the clipping-region created in step#1
	//
	SetBkMode(hdc, TRANSPARENT);
	PaintForeground(uspData, hdc, xpos, ypos + lineAdjustY, bounds, FALSE);

	//
	//  3. redraw the text using a single text-selection-colour (i.e. white)
	//	   in the same position, directly over the top of the text drawn in step#2
	//
	//	   Before we do this, the HDC clipping-region is inverted, 
	//	   so only selection areas are modified this time 
	//
	hrgn = CreateRectRgnIndirect(bounds);
	ExtSelectClipRgn(hdc, hrgn, RGN_XOR);

	SetBkMode(hdc, TRANSPARENT);
	xpos = 
	PaintForeground(uspData, hdc, xpos, ypos + lineAdjustY, bounds, TRUE);
	
	// remove clipping regions
	SelectClipRgn(hdc, hrgnClip);
	DeleteObject(hrgn);
	DeleteObject(hrgnClip);

	return xpos;
}
Пример #9
0
// This function clears the graphics screen (with the background color) and
// moves the current point to (0,0)
//
void cleardevice( )
{
    HDC hDC;
    WindowData* pWndData = BGI__GetWindowDataPtr( );
    int color;          // Background color to fill with
    RECT rect;          // The rectangle to fill
    HRGN hRGN;          // The clipping region (if any)
    int is_rgn;         // Whether or not a clipping region is present
    POINT p;            // Upper left point of window (convert from device to logical points)
    HBRUSH hBrush;      // Brush in the background color

    // Convert from BGI color to RGB color
    color = converttorgb( pWndData->bgColor );

    hDC = BGI__GetWinbgiDC( );
    // Even though a viewport may be set, this function clears the entire screen.
    // Compute the origin in logical coordinates.
    p.x = 0;
    p.y = 0;
    DPtoLP( hDC, &p, 1 );
    rect.left = p.x;
    rect.top = p.y;
    rect.right = pWndData->width;
    rect.bottom = pWndData->height;

    // Get the current clipping region, if any.  The region object must first
    // be created with some valid region.  If the GetClipRgn function
    // succeeds, the region info will be updated to reflect the new region.
    // However, this does not create a new region object.  That is, this
    // simply overwrites the memory of the old region object and we don't have
    // to worry about deleting the old region.
    hRGN = CreateRectRgn( 0, 0, 5, 5 );
    is_rgn = GetClipRgn( hDC, hRGN );
    // If there is a clipping region, select none
    if ( is_rgn != 0 )
        SelectClipRgn( hDC, NULL );
    
    // Fill hDC with background color
    hBrush = CreateSolidBrush( color );
    FillRect( hDC, &rect, hBrush );
    DeleteObject( hBrush );
    // Move the CP back to (0,0) (NOT viewport relative)
    moveto( p.x, p.y );

    // Select the old clipping region back into the device context
    if ( is_rgn != 0 )
        SelectClipRgn( hDC, hRGN );
    // Delete the region
    DeleteRgn( hRGN );
    BGI__ReleaseWinbgiDC( );
    
    RefreshWindow( NULL );
}
Пример #10
0
static HRGN
get_clip(HDC dc)
{
    /* Create dummy region as we need a valid region handle beforehand. */
    HRGN rgn = CreateRectRgn(0, 0, 1, 1);

    if(GetClipRgn(dc, rgn) != 1) {
        /* GetClipRgn() failed. This should always mean there is no
         * clipping region applied at the moment. Delete the dummy region. */
        DeleteObject(rgn);
        return NULL;
    }

    return rgn;
}
Пример #11
0
/***********************************************************************
 *           set_control_clipping
 *
 * Set clipping for a builtin control that uses CS_PARENTDC.
 * Return the previous clip region if any.
 */
HRGN set_control_clipping( HDC hdc, const RECT *rect )
{
    RECT rc = *rect;
    HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );

    if (GetClipRgn( hdc, hrgn ) != 1)
    {
        DeleteObject( hrgn );
        hrgn = 0;
    }
    DPtoLP( hdc, (POINT *)&rc, 2 );
    if (GetLayout( hdc ) & LAYOUT_RTL)  /* compensate for the shifting done by IntersectClipRect */
    {
        rc.left++;
        rc.right++;
    }
    IntersectClipRect( hdc, rc.left, rc.top, rc.right, rc.bottom );
    return hrgn;
}
Пример #12
0
/***********************************************************************
 *           PSDRV_SetClip
 *
 * The idea here is that every graphics operation should bracket
 * output in PSDRV_SetClip/ResetClip calls.  The clip path outside
 * these calls will be empty; the reason for this is that it is
 * impossible in PostScript to cleanly make the clip path larger than
 * the current one.  Also Photoshop assumes that despite having set a
 * small clip area in the printer dc that it can still write raw
 * PostScript to the driver and expect this code not to be clipped.
 */
void PSDRV_SetClip( PHYSDEV dev )
{
    PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
    HRGN hrgn;

    TRACE("hdc=%p\n", dev->hdc);

    if(physDev->pathdepth) {
        TRACE("inside a path, so not clipping\n");
        return;
    }

    hrgn = CreateRectRgn(0,0,0,0);
    if (GetClipRgn(dev->hdc, hrgn))
    {
        PSDRV_WriteGSave(dev);
        PSDRV_AddClip( dev, hrgn );
    }
    DeleteObject(hrgn);
}
Пример #13
0
// CDropT
	HRESULT CDropT::OnDraw(ATL_DRAWINFO& di)
	{
		RECT& rc = *(RECT*)di.prcBounds;
		// Set Clip region to the rectangle specified by di.prcBounds
		HRGN hRgnOld = NULL;
		if (GetClipRgn(di.hdcDraw, hRgnOld) != 1)
			hRgnOld = NULL;
		bool bSelectOldRgn = false;

		HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);

		if (hRgnNew != NULL)
		{
			bSelectOldRgn = (SelectClipRgn(di.hdcDraw, hRgnNew) != ERROR);
		}

		Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
		SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
		LPCTSTR pszText = _T("DropT");
	#ifndef _WIN32_WCE
		TextOut(di.hdcDraw,
			(rc.left + rc.right) / 2,
			(rc.top + rc.bottom) / 2,
			pszText,
			lstrlen(pszText));
	#else
		ExtTextOut(di.hdcDraw,
			(rc.left + rc.right) / 2,
			(rc.top + rc.bottom) / 2,
			ETO_OPAQUE,
			NULL,
			pszText,
			ATL::lstrlen(pszText),
			NULL);
	#endif
		if (bSelectOldRgn)
			SelectClipRgn(di.hdcDraw, hRgnOld);

		DeleteObject(hRgnNew);
		return S_OK;
	}
Пример #14
0
void
_gdk_win32_print_dc (HDC hdc)
{
  HGDIOBJ obj;
  LOGBRUSH logbrush;
  EXTLOGPEN extlogpen;
  HRGN hrgn;
  RECT rect;
  int flag;

  g_print ("%p:\n", hdc);
  obj = GetCurrentObject (hdc, OBJ_BRUSH);
  GetObject (obj, sizeof (LOGBRUSH), &logbrush);
  g_print ("brush: %s color=%06lx hatch=%p\n",
	   _gdk_win32_lbstyle_to_string (logbrush.lbStyle),
	   logbrush.lbColor, (gpointer) logbrush.lbHatch);
  obj = GetCurrentObject (hdc, OBJ_PEN);
  GetObject (obj, sizeof (EXTLOGPEN), &extlogpen);
  g_print ("pen: %s %s %s %s w=%d %s\n",
	   _gdk_win32_pstype_to_string (extlogpen.elpPenStyle),
	   _gdk_win32_psstyle_to_string (extlogpen.elpPenStyle),
	   _gdk_win32_psendcap_to_string (extlogpen.elpPenStyle),
	   _gdk_win32_psjoin_to_string (extlogpen.elpPenStyle),
	   extlogpen.elpWidth,
	   _gdk_win32_lbstyle_to_string (extlogpen.elpBrushStyle));
  g_print ("rop2: %s textcolor=%06lx\n",
	   _gdk_win32_rop2_to_string (GetROP2 (hdc)),
	   GetTextColor (hdc));
  hrgn = CreateRectRgn (0, 0, 0, 0);
  if ((flag = GetClipRgn (hdc, hrgn)) == -1)
    WIN32_API_FAILED ("GetClipRgn");
  else if (flag == 0)
    g_print ("no clip region\n");
  else if (flag == 1)
    {
      GetRgnBox (hrgn, &rect);
      g_print ("clip region: %p bbox: %s\n",
	       hrgn, _gdk_win32_rect_to_string (&rect));
    }
  DeleteObject (hrgn);
}
Пример #15
0
HRGN WinGetClipRgnPicture (OSPictContext context)
{
	HRGN theRegion;
	int error;

	theRegion = CreateRectRgn (0,0, 1,1);
	if (theRegion==NULL)
		ErrorExit ("Fatal error in WinGetClipRgnPicture: CreateRectRgn returned NULL.");

	error = GetClipRgn (context->hDC, theRegion);

	if (error==0)
	{
		DeleteObject (theRegion);
		theRegion = NULL;
	}
	if (error==-1)
		ErrorExit ("Fatal error in WinGetClipRgnPicture: GetClipRgn returned -1.");

	return theRegion;
}	/* WinGetClipRgnPicture */
Пример #16
0
    BOOL Save(HDC hDC)
    {
        assert(hDC != NULL);
        assert(m_hOldRgn == NULL);
        assert(m_hDC == NULL);
        m_hOldRgn = ::CreateRectRgn(0, 0, 0, 0);

        if (m_hOldRgn != NULL)
        {
            switch (GetClipRgn(hDC, m_hOldRgn))
            {
            case 1:
            {
                // success, m_hOldRgn contains the current clipping region for the DC
                m_hDC = hDC;
            }
            break;

            case 0:
            {
                // success, but the DC has no clipping region
                m_hDC = hDC;
                DeleteObject(m_hOldRgn);
                m_hOldRgn = NULL;
            }
            break;

            default:
            case -1:
            {
                // erro
                DeleteObject(m_hOldRgn);
                m_hOldRgn = NULL;
            }
            break;
            }
        }

        return (m_hDC != NULL);
    }
Пример #17
0
void Test_OffsetRgn()
{
    HRGN hrgn1, hrgn2;
    HDC hdc;

    hrgn1 = CreateRectRgn(0, 0, 0, 0);
    ok(hrgn1 != NULL, "CreateRectRgn failed\n");
    ok_int(OffsetRgn(hrgn1, INT_MIN + 10, 10), NULLREGION);
    ok_int(OffsetRgn(hrgn1, 0xF000000, 0xF000000), NULLREGION);
    DeleteObject(hrgn1);

    hrgn1 = CreateRectRgn(0, 0, 100, 100);
    ok(hrgn1 != NULL, "CreateRectRgn failed\n");
    ok_int(OffsetRgn(hrgn1, 10, 10), SIMPLEREGION);
    ok_int(OffsetRgn(hrgn1, 0x8000000 - 110, 10), ERROR);
    ok_int(OffsetRgn(hrgn1, 0x8000000 - 111, 10), SIMPLEREGION);
    DeleteObject(hrgn1);

    hrgn1 = CreateRectRgn(0, 0, 100, 100);
    ok(hrgn1 != NULL, "CreateRectRgn failed\n");
    ok_int(OffsetRgn(hrgn1, -10, 10), SIMPLEREGION);
    ok_int(OffsetRgn(hrgn1, -(0x8000000 - 9), 10), ERROR);
    ok_int(OffsetRgn(hrgn1, -(0x8000000 - 10), 10), SIMPLEREGION);
    DeleteObject(hrgn1);

    hrgn1 = CreateRectRgn(0, 0, 10, 10);
    hrgn2 = CreateRectRgn(1000, 20, 1010, 30);
    ok_int(CombineRgn(hrgn1, hrgn1, hrgn2, RGN_OR), COMPLEXREGION);
    ok_int(OffsetRgn(hrgn1, 0x8000000 - 100, 10), ERROR);
    ok_int(CombineRgn(hrgn1, hrgn1, hrgn2, RGN_XOR), SIMPLEREGION);
    DeleteObject(hrgn2);
    hrgn2 = CreateRectRgn(0, 0, 10, 10);
    ok_int(CombineRgn(hrgn1, hrgn1, hrgn2, RGN_XOR), NULLREGION);

    hrgn1 = CreateRectRgn(0, 0, 0, 0);
    hdc = CreateCompatibleDC(NULL);
    ok_int(GetClipRgn(hdc, hrgn1), 0);
    ok_int(OffsetRgn(hrgn1, 10, 10), NULLREGION);

}
Пример #18
0
BOOL CGifSmileyCtrl::SelectSmileyClipRgn(HDC hDC, RECT& SmileyPos, HRGN& hOldRegion,  HRGN& hNewRegion, BOOL bTuneBorder)
{
	hNewRegion=NULL;
	hOldRegion=NULL;

	if (!bTuneBorder)
	{
		hNewRegion=CreateRectRgn(SmileyPos.left, SmileyPos.top, SmileyPos.right, SmileyPos.bottom);
	}
	else if (m_hwndParent)
	{
		RECT rcParent;
		RECT rcVis;
		RECT wrc;
		POINT pt={0};

		::ClientToScreen(m_hwndParent, &pt);
		::GetClientRect(m_hwndParent, &rcParent);
		::GetWindowRect(m_hwndParent,&wrc);
		OffsetRect(&rcParent, pt.x-wrc.left, pt.y-wrc.top);

		IntersectRect(&rcVis, &rcParent, &SmileyPos);
		if (IsRectEmpty(&rcVis)) return FALSE;
		hNewRegion=CreateRectRgn(rcVis.left,rcVis.top,rcVis.right,rcVis.bottom);
	}
	else return FALSE;

	if (GetClipRgn(hDC,hOldRegion)!=1)
	{
		DeleteObject(hOldRegion);
		hOldRegion=NULL;
	}

	SelectClipRgn(hDC, hNewRegion);
	return TRUE;
}
Пример #19
0
static void test_savedc_2(void)
{
    HWND hwnd;
    HDC hdc;
    HRGN hrgn;
    RECT rc, rc_clip;
    int ret;

    hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
                           0, 0, 0, NULL);
    assert(hwnd != 0);
    ShowWindow(hwnd, SW_SHOW);
    UpdateWindow(hwnd);

    hrgn = CreateRectRgn(0, 0, 0, 0);
    assert(hrgn != 0);

    hdc = GetDC(hwnd);
    ok(hdc != NULL, "GetDC failed\n");

    ret = GetClipBox(hdc, &rc_clip);
    ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
    ret = GetRgnBox(hrgn, &rc);
    ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
       ret, rc.left, rc.top, rc.right, rc.bottom);
    /*dump_region(hrgn);*/
    SetRect(&rc, 0, 0, 100, 100);
    ok(EqualRect(&rc, &rc_clip),
       "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
       rc.left, rc.top, rc.right, rc.bottom,
       rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);

    ret = SaveDC(hdc);
todo_wine
{
    ok(ret == 1, "ret = %d\n", ret);
}

    ret = IntersectClipRect(hdc, 0, 0, 50, 50);
    if (ret == COMPLEXREGION)
    {
        /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
        trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
        /* let's make sure that it's a simple region */
        ret = GetClipRgn(hdc, hrgn);
        ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
        dump_region(hrgn);
    }
    else
        ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);

    ret = GetClipBox(hdc, &rc_clip);
    ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
    SetRect(&rc, 0, 0, 50, 50);
    ok(EqualRect(&rc, &rc_clip), "rects are not equal\n");

    ret = RestoreDC(hdc, 1);
    ok(ret, "ret = %d\n", ret);

    ret = GetClipBox(hdc, &rc_clip);
    ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
    SetRect(&rc, 0, 0, 100, 100);
    ok(EqualRect(&rc, &rc_clip), "rects are not equal\n");

    DeleteObject(hrgn);
    ReleaseDC(hwnd, hdc);
    DestroyWindow(hwnd);
}
Пример #20
0
void CardWindow::PaintCardRgn(HDC hdc, int dx, int dy, int width, int height, int sx, int sy)
{
    RECT rect;

    //if just a solid background colour
    if(hbmBackImage == 0)
    {
        SetRect(&rect, dx, dy, dx+width, dy+height);

        /*if(GetVersion() < 0x80000000)
        {
            PaintRect(hdc, &rect, MAKE_PALETTERGB(crBackgnd));
        }
        else*/
        {
            HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBackgnd));
            FillRect(hdc, &rect, hbr);
            DeleteObject(hbr);
        }
    }
    //otherwise, paint using the bitmap
    else
    {
        // Draw whatever part of background we can
        BitBlt(hdc, dx, dy, width, height, hdcBackImage, sx, sy, SRCCOPY);

        // Now we need to paint any area outside the bitmap,
        // just in case the bitmap is too small to fill whole window
        if(0)//sx + width > bm.bmWidth || sy + height > bm.bmHeight)
        {
            // Find out size of bitmap
            BITMAP bm;
            GetObject(hbmBackImage, sizeof(bm), &bm);

            HRGN hr1 = CreateRectRgn(sx, sy, sx+width, sy+height);
            HRGN hr2 = CreateRectRgn(0, 0, bm.bmWidth, bm.bmHeight);
            HRGN hr3 = CreateRectRgn(0,0, 1, 1);
            HRGN hr4 = CreateRectRgn(0,0, 1, 1);

            CombineRgn(hr3, hr1, hr2, RGN_DIFF);

            GetClipRgn(hdc, hr4);

            CombineRgn(hr3, hr4, hr3, RGN_AND);
            SelectClipRgn(hdc, hr3);

            // Fill remaining space not filled with bitmap
            HBRUSH hbr = CreateSolidBrush(crBackgnd);
            FillRgn(hdc, hr3, hbr);
            DeleteObject(hbr);

            // Clean up
            SelectClipRgn(hdc, hr4);

            DeleteObject(hr1);
            DeleteObject(hr2);
            DeleteObject(hr3);
            DeleteObject(hr4);
        }
    }
}
Пример #21
0
void sClipPush()
{
  sVERIFY(ClipIndex<MAX_CLIPS);
  ClipStackResult[ClipIndex] = GetClipRgn(sGDIDC,ClipStack[ClipIndex]);
  ClipIndex++;
}
static cairo_surface_t *
_cairo_win32_surface_create_for_dc (HDC             original_dc,
				    cairo_format_t  format,
				    int	            width,
				    int	            height)
{
    cairo_status_t status;
    cairo_win32_surface_t *surface;
    char *bits;
    int rowstride;

    surface = malloc (sizeof (cairo_win32_surface_t));
    if (surface == NULL) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return &_cairo_surface_nil;
    }

    status = _create_dc_and_bitmap (surface, original_dc, format,
				    width, height,
				    &bits, &rowstride);
    if (status)
	goto FAIL;

    surface->image = cairo_image_surface_create_for_data (bits, format,
							  width, height, rowstride);
    if (surface->image->status) {
	status = CAIRO_STATUS_NO_MEMORY;
	goto FAIL;
    }
    
    surface->format = format;
    
    surface->clip_rect.x = 0;
    surface->clip_rect.y = 0;
    surface->clip_rect.width = width;
    surface->clip_rect.height = height;

    surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
    if (GetClipRgn (surface->dc, surface->saved_clip) == 0) {
        DeleteObject(surface->saved_clip);
        surface->saved_clip = NULL;
    }

    surface->extents = surface->clip_rect;

    _cairo_surface_init (&surface->base, &cairo_win32_surface_backend);

    return (cairo_surface_t *)surface;

 FAIL:
    if (surface->bitmap) {
	SelectObject (surface->dc, surface->saved_dc_bitmap);
  	DeleteObject (surface->bitmap);
        DeleteDC (surface->dc);
    }
    if (surface)
	free (surface);

    if (status == CAIRO_STATUS_NO_MEMORY) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return &_cairo_surface_nil;
    } else {
	_cairo_error (status);
	return &_cairo_surface_nil;
    }
}
Пример #23
0
static void test_GetClipRgn(void)
{
    HDC hdc;
    HRGN hrgn, hrgn2, hrgn3, hrgn4;
    int ret;

    /* Test calling GetClipRgn with NULL device context and region handles. */
    ret = GetClipRgn(NULL, NULL);
    ok(ret == -1, "Expected GetClipRgn to return -1, got %d\n", ret);

    hdc = GetDC(NULL);
    ok(hdc != NULL, "Expected GetDC to return a valid device context handle\n");

    /* Test calling GetClipRgn with a valid device context and NULL region. */
    ret = GetClipRgn(hdc, NULL);
    ok(ret == 0 ||
       ret == -1 /* Win9x */,
       "Expected GetClipRgn to return 0, got %d\n", ret);

    /* Initialize the test regions. */
    hrgn = CreateRectRgn(100, 100, 100, 100);
    ok(hrgn != NULL,
       "Expected CreateRectRgn to return a handle to a new rectangular region\n");

    hrgn2 = CreateRectRgn(1, 2, 3, 4);
    ok(hrgn2 != NULL,
       "Expected CreateRectRgn to return a handle to a new rectangular region\n");

    hrgn3 = CreateRectRgn(1, 2, 3, 4);
    ok(hrgn3 != NULL,
       "Expected CreateRectRgn to return a handle to a new rectangular region\n");

    hrgn4 = CreateRectRgn(1, 2, 3, 4);
    ok(hrgn4 != NULL,
       "Expected CreateRectRgn to return a handle to a new rectangular region\n");

    /* Try getting a clipping region from the device context
     * when the device context's clipping region isn't set. */
    ret = GetClipRgn(hdc, hrgn2);
    ok(ret == 0, "Expected GetClipRgn to return 0, got %d\n", ret);

    /* The region passed to GetClipRgn should be unchanged. */
    ret = EqualRgn(hrgn2, hrgn3);
    ok(ret == 1,
       "Expected EqualRgn to compare the two regions as equal, got %d\n", ret);

    /* Try setting and getting back a clipping region. */
    ret = SelectClipRgn(hdc, hrgn);
    ok(ret == NULLREGION,
       "Expected SelectClipRgn to return NULLREGION, got %d\n", ret);

    /* Passing a NULL region handle when the device context
     * has a clipping region results in an error. */
    ret = GetClipRgn(hdc, NULL);
    ok(ret == -1, "Expected GetClipRgn to return -1, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn2);
    ok(ret == 1, "Expected GetClipRgn to return 1, got %d\n", ret);

    ret = EqualRgn(hrgn, hrgn2);
    ok(ret == 1,
       "Expected EqualRgn to compare the two regions as equal, got %d\n", ret);

    /* Try unsetting and then query the clipping region. */
    ret = SelectClipRgn(hdc, NULL);
    ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
       "Expected SelectClipRgn to return SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, NULL);
    ok(ret == 0 ||
       ret == -1 /* Win9x */,
       "Expected GetClipRgn to return 0, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn3);
    ok(ret == 0, "Expected GetClipRgn to return 0, got %d\n", ret);

    ret = EqualRgn(hrgn3, hrgn4);
    ok(ret == 1,
       "Expected EqualRgn to compare the two regions as equal, got %d\n", ret);

    DeleteObject(hrgn4);
    DeleteObject(hrgn3);
    DeleteObject(hrgn2);
    DeleteObject(hrgn);
    ReleaseDC(NULL, hdc);
}
Пример #24
0
static void test_dc_layout(void)
{
    INT ret, size_cx, size_cy, res_x, res_y, dpi_x, dpi_y;
    SIZE size;
    POINT pt;
    HBITMAP bitmap;
    RECT rc, ret_rc;
    HDC hdc;
    HRGN hrgn;

    if (!pGetLayout || !pSetLayout)
    {
        win_skip( "Don't have SetLayout\n" );
        return;
    }

    hdc = CreateCompatibleDC(0);
    bitmap = CreateCompatibleBitmap( hdc, 100, 100 );
    SelectObject( hdc, bitmap );

    size_cx = GetDeviceCaps(hdc, HORZSIZE);
    size_cy = GetDeviceCaps(hdc, VERTSIZE);
    res_x = GetDeviceCaps(hdc, HORZRES);
    res_y = GetDeviceCaps(hdc, VERTRES);
    dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
    dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);

    ret = GetMapMode( hdc );
    ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret);
    expect_viewport_ext(hdc, 1, 1);
    expect_window_ext(hdc, 1, 1);
    expect_world_transform(hdc, 1.0, 1.0);
    expect_LPtoDP(hdc, 1000, 1000);

    pSetLayout( hdc, LAYOUT_RTL );
    if (!pGetLayout( hdc ))
    {
        win_skip( "SetLayout not supported\n" );
        DeleteDC(hdc);
        return;
    }

    ret = GetMapMode( hdc );
    ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret);
    expect_viewport_ext(hdc, 1, 1);
    expect_window_ext(hdc, 1, 1);
    expect_world_transform(hdc, 1.0, 1.0);
    expect_LPtoDP(hdc, -1000 + 99, 1000);
    GetViewportOrgEx( hdc, &pt );
    ok( pt.x == 0 && pt.y == 0, "wrong origin %d,%d\n", pt.x, pt.y );
    GetWindowOrgEx( hdc, &pt );
    ok( pt.x == 0 && pt.y == 0, "wrong origin %d,%d\n", pt.x, pt.y );
    GetDCOrgEx( hdc, &pt );
    ok( pt.x == 0 && pt.y == 0, "wrong origin %d,%d\n", pt.x, pt.y );
    if (pGetTransform)
    {
        XFORM xform;
        BOOL ret = pGetTransform( hdc, 0x204, &xform ); /* World -> Device */
        ok( ret, "got %d\n", ret );
        ok( xform.eM11 == -1.0, "got %f\n", xform.eM11 );
        ok( xform.eM12 == 0.0, "got %f\n", xform.eM12 );
        ok( xform.eM21 == 0.0, "got %f\n", xform.eM21 );
        ok( xform.eM22 == 1.0, "got %f\n", xform.eM22 );
        ok( xform.eDx == 99.0, "got %f\n", xform.eDx );
        ok( xform.eDy == 0.0, "got %f\n", xform.eDy );
    }

    SetRect( &rc, 10, 10, 20, 20 );
    IntersectClipRect( hdc, 10, 10, 20, 20 );
    hrgn = CreateRectRgn( 0, 0, 0, 0 );
    GetClipRgn( hdc, hrgn );
    GetRgnBox( hrgn, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );
    pSetLayout( hdc, LAYOUT_LTR );
    SetRect( &rc, 80, 10, 90, 20 );
    GetClipRgn( hdc, hrgn );
    GetRgnBox( hrgn, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );
    GetClipBox( hdc, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );
    IntersectClipRect( hdc, 80, 10, 85, 20 );
    pSetLayout( hdc, LAYOUT_RTL );
    SetRect( &rc, 15, 10, 20, 20 );
    GetClipRgn( hdc, hrgn );
    GetRgnBox( hrgn, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );
    GetClipBox( hdc, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );
    SetRectRgn( hrgn, 60, 10, 80, 20 );
    pSetLayout( hdc, LAYOUT_LTR );
    ExtSelectClipRgn( hdc, hrgn, RGN_OR );
    pSetLayout( hdc, LAYOUT_RTL );
    SetRect( &rc, 15, 10, 40, 20 );
    GetClipRgn( hdc, hrgn );
    GetRgnBox( hrgn, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );
    GetClipBox( hdc, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );

    /* OffsetClipRgn mirrors too */
    OffsetClipRgn( hdc, 5, 5 );
    OffsetRect( &rc, 5, 5 );
    GetClipRgn( hdc, hrgn );
    GetRgnBox( hrgn, &ret_rc );
    ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
        ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );

    /* GetRandomRgn returns the raw region */
    if (pGetRandomRgn)
    {
        SetRect( &rc, 55, 15, 80, 25 );
        pGetRandomRgn( hdc, hrgn, 1 );
        GetRgnBox( hrgn, &ret_rc );
        ok( EqualRect( &rc, &ret_rc ), "wrong clip box %d,%d - %d,%d\n",
            ret_rc.left, ret_rc.top, ret_rc.right, ret_rc.bottom );
    }

    SetMapMode(hdc, MM_LOMETRIC);
    ret = GetMapMode( hdc );
    ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret);

    expect_viewport_ext(hdc, res_x, -res_y);
    ok( GetWindowExtEx( hdc, &size ), "GetWindowExtEx failed\n" );
    ok( rough_match( size.cx, size_cx * 10 ) ||
        rough_match( size.cx, MulDiv( res_x, 254, dpi_x )),  /* Vista uses a more precise method */
        "expected cx %d or %d, got %d\n", size_cx * 10, MulDiv( res_x, 254, dpi_x ), size.cx );
    ok( rough_match( size.cy, size_cy * 10 ) ||
        rough_match( size.cy, MulDiv( res_y, 254, dpi_y )),  /* Vista uses a more precise method */
        "expected cy %d or %d, got %d\n", size_cy * 10, MulDiv( res_y, 254, dpi_y ), size.cy );
    expect_world_transform(hdc, 1.0, 1.0);
    expect_LPtoDP(hdc, -MulDiv(1000 / 10, res_x, size_cx) + 99, -MulDiv(1000 / 10, res_y, size_cy));

    SetMapMode(hdc, MM_TEXT);
    ret = GetMapMode( hdc );
    ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret);
    pSetLayout( hdc, LAYOUT_LTR );
    ret = GetMapMode( hdc );
    ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret);
    SetMapMode(hdc, MM_TEXT);
    ret = GetMapMode( hdc );
    ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret);

    DeleteDC(hdc);
    DeleteObject( bitmap );
}
Пример #25
0
/***********************************************************************
 *           PSDRV_SetClip
 *
 * The idea here is that every graphics operation should bracket
 * output in PSDRV_SetClip/ResetClip calls.  The clip path outside
 * these calls will be empty; the reason for this is that it is
 * impossible in PostScript to cleanly make the clip path larger than
 * the current one.  Also Photoshop assumes that despite having set a
 * small clip area in the printer dc that it can still write raw
 * PostScript to the driver and expect this code not to be clipped.
 */
void PSDRV_SetClip( PHYSDEV dev )
{
    PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
    CHAR szArrayName[] = "clippath";
    DWORD size;
    RGNDATA *rgndata = NULL;
    HRGN hrgn = CreateRectRgn(0,0,0,0);
    BOOL empty;

    TRACE("hdc=%p\n", dev->hdc);

    if(physDev->pathdepth) {
        TRACE("inside a path, so not clipping\n");
        goto end;
    }

    empty = !GetClipRgn(dev->hdc, hrgn);

    if(!empty) {
        size = GetRegionData(hrgn, 0, NULL);
        if(!size) {
            ERR("Invalid region\n");
            goto end;
        }

        rgndata = HeapAlloc( GetProcessHeap(), 0, size );
        if(!rgndata) {
            ERR("Can't allocate buffer\n");
            goto end;
        }

        GetRegionData(hrgn, size, rgndata);

        PSDRV_WriteGSave(dev);

        /* check for NULL region */
        if (rgndata->rdh.nCount == 0)
        {
            /* set an empty clip path. */
            PSDRV_WriteRectClip(dev, 0, 0, 0, 0);
        }
        /* optimize when it is a simple region */
        else if (rgndata->rdh.nCount == 1)
        {
            RECT *pRect = (RECT *)rgndata->Buffer;

            PSDRV_WriteRectClip(dev, pRect->left, pRect->top,
                                pRect->right - pRect->left,
                                pRect->bottom - pRect->top);
        }
        else
        {
            UINT i;
            RECT *pRect = (RECT *)rgndata->Buffer;

            PSDRV_WriteArrayDef(dev, szArrayName, rgndata->rdh.nCount * 4);

            for (i = 0; i < rgndata->rdh.nCount; i++, pRect++)
            {
                PSDRV_WriteArrayPut(dev, szArrayName, i * 4,
                                    pRect->left);
                PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 1,
                                    pRect->top);
                PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 2,
                                    pRect->right - pRect->left);
                PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 3,
                                    pRect->bottom - pRect->top);
            }
            PSDRV_WriteRectClip2(dev, szArrayName);
        }
    }
end:
    HeapFree( GetProcessHeap(), 0, rgndata );
    DeleteObject(hrgn);
}
Пример #26
0
/***********************************************************************
 * Draw a card. Unlike cdtDrawCard, this version allows you to stretch
 * card bitmaps to the size you specify (dx, dy). See cdtDraw for info
 * on card, mode and color parameters.
 */
BOOL WINAPI cdtDrawExt(HDC hdc, int x, int y, int dx, int dy, int card, int mode, DWORD color)
{
	HDC hMemoryDC;
	HBITMAP hCardBitmap;
	HGDIOBJ result;
	DWORD rasterOp = SRCCOPY;
	BOOL roundCornersFlag;
	BOOL eraseFlag = FALSE;
	BOOL drawFlag = TRUE;

	TRACE("(%p, %d, %d, %d, %d, %d, %d, %d)\n", hdc, x, y, dx, dy, card, mode, color);

	roundCornersFlag = !(mode & MODEFLAG_DONT_ROUND_CORNERS) &&
			   (dx == cardWidth) && (dy == cardHeight);
	mode &= ~MODEFLAG_DONT_ROUND_CORNERS;

	if((card < 0) || (card > CARD_MAX))
	{
		FIXME("Unexpected card: %d\n", card);
		return FALSE;
	}

	if((mode < MODE_FACEUP) || (mode > MODE_DECKO))
	{
		FIXME("Unexpected mode: %d\n", mode);
		return FALSE;
	}

	switch(mode)
	{
	case MODE_FACEUP:
		break;
	case MODE_FACEDOWN:
		break;
	case MODE_HILITE:
		rasterOp = NOTSRCCOPY;
		break;
	case MODE_GHOST:
		card = CARD_FREE_MASK;
		eraseFlag = TRUE;
		rasterOp = SRCAND;
		break;
	case MODE_REMOVE:
		eraseFlag = TRUE;
		drawFlag = FALSE;
		break;
	case MODE_INVISIBLEGHOST:
		card = CARD_FREE_MASK;
		rasterOp = SRCAND;
		break;
	case MODE_DECKX:
		card = CARD_BACK_THE_X;
		break;
	case MODE_DECKO:
		card = CARD_BACK_THE_O;
		break;
	}

	hMemoryDC = CreateCompatibleDC(hdc);
	if(hMemoryDC == 0)
		return FALSE;

	if(eraseFlag)
	{
		HBRUSH hBrush;
		RECT rect;
		hBrush = CreateSolidBrush(color);
		rect.left = x;
		rect.top = y;
		rect.right = x + cardWidth - 1;
		rect.bottom = y + cardHeight - 1;
		FillRect(hdc, &rect, hBrush);
	}

	if(drawFlag)
	{
		hCardBitmap = cardBitmaps[card];
		if(hCardBitmap == 0)
			return FALSE;

		result = SelectObject(hMemoryDC, hCardBitmap);
		if((result == 0) || (result == HGDI_ERROR))
		{
			DeleteDC(hMemoryDC);
			return FALSE;
		}

		SetBkColor(hdc, color);

		if(roundCornersFlag)
		{
                    /* NOTE: native uses Get/SetPixel for corners, but that really
                     * hurts on X11 since it needs a server round-trip for each pixel.
                     * So we use a clip region instead. */
                    HRGN saved = CreateRectRgn( 0, 0, 0, 0 );
                    HRGN line = CreateRectRgn( x + 2, y, x + dx - 2, y + 1 );
                    HRGN clip = CreateRectRgn( x, y + 2, x + dx, y + dy - 2 );

                    CombineRgn( clip, clip, line, RGN_OR );
                    SetRectRgn( line, x + 1, y + 1, x + dx - 1, y + 2 );
                    CombineRgn( clip, clip, line, RGN_OR );
                    SetRectRgn( line, x + 1, y + dy - 2, x + dx - 1, y + dy - 1 );
                    CombineRgn( clip, clip, line, RGN_OR );
                    SetRectRgn( line, x + 2, y + dy - 1, x + dx - 2, y + dy );
                    CombineRgn( clip, clip, line, RGN_OR );
                    DeleteObject( line );

                    if (!GetClipRgn( hdc, saved ))
                    {
                        DeleteObject( saved );
                        saved = 0;
                    }
                    ExtSelectClipRgn( hdc, clip, RGN_AND );
                    DeleteObject( clip );

                    do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);

                    SelectClipRgn( hdc, saved );
                    if (saved) DeleteObject( saved );
		}
		else
			do_blt(hdc, x, y, dx, dy, hMemoryDC, rasterOp);
	}

	DeleteDC(hMemoryDC);

	return TRUE;
}
Пример #27
0
static void test_window_dc_clipping(void)
{
    HDC hdc;
    HRGN hrgn, hrgn_empty;
    HWND hwnd;
    RECT rc, virtual_rect;
    int ret, screen_width, screen_height;

    /* Windows versions earlier than Win2k do not support the virtual screen metrics,
     * so we fall back to the primary screen metrics. */
    screen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    if(!screen_width) screen_width = GetSystemMetrics(SM_CXSCREEN);
    screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    if(!screen_height) screen_height = GetSystemMetrics(SM_CYSCREEN);
    SetRect(&virtual_rect, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
            GetSystemMetrics(SM_XVIRTUALSCREEN) + screen_width, GetSystemMetrics(SM_YVIRTUALSCREEN) + screen_height);

    trace("screen resolution %d x %d\n", screen_width, screen_height);

    hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
                           -100, -100, screen_width * 2, screen_height * 2, 0, 0, 0, NULL);
    hdc = GetWindowDC(0);
    hrgn_empty = CreateRectRgn(0, 0, 0, 0);
    hrgn = CreateRectRgn(0, 0, 0, 0);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "expected 0, got %d\n", ret);

    ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
    ok(ret == 0, "expected 0, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "expected 0, got %d\n", ret);

    ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
    ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
       "expected SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 1, "expected 1, got %d\n", ret);

    ret = GetRgnBox(hrgn, &rc);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
    ok(EqualRect(&rc, &virtual_rect), "expected %s, got %s\n", wine_dbgstr_rect(&virtual_rect),
       wine_dbgstr_rect(&rc));

    SetRect( &rc, 10, 10, 20, 20 );
    ret = RectVisible( hdc, &rc );
    ok( ret, "RectVisible failed for %s\n", wine_dbgstr_rect(&rc));

    SetRect( &rc, 20, 20, 10, 10 );
    ret = RectVisible( hdc, &rc );
    ok( ret, "RectVisible failed for %s\n", wine_dbgstr_rect(&rc));

    ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
    ok(ret == 0, "expected 0, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 1, "expected 1, got %d\n", ret);

    ret = GetRgnBox(hrgn, &rc);
    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
    ok(EqualRect(&rc, &virtual_rect), "expected %s, got %s\n", wine_dbgstr_rect(&virtual_rect),
       wine_dbgstr_rect(&rc));

    ret = ExtSelectClipRgn(hdc, 0, RGN_COPY);
    ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
       "expected SIMPLEREGION, got %d\n", ret);

    ret = GetClipRgn(hdc, hrgn);
    ok(ret == 0, "expected 0, got %d\n", ret);

    DeleteDC(hdc);
    DeleteObject(hrgn);
    DeleteObject(hrgn_empty);
    DestroyWindow(hwnd);
}
Пример #28
0
void KDCAttributes::DumpDC(HDC hDC)
{
	POINT pnt;
	SIZE  size;

	m_List.DeleteAll();

	Add(_T("Technology"),  _T("%d"), GetDeviceCaps(hDC, TECHNOLOGY));
	Add(_T("width"),	   _T("%d"), GetDeviceCaps(hDC, HORZRES));
	Add(_T("height"),	   _T("%d"), GetDeviceCaps(hDC, VERTRES));

	GetDCOrgEx(hDC, & pnt); 
	Add(_T("DC Origin"), _T("{ %d, %d }"), pnt.x, pnt.y);

	TCHAR szTitle[MAX_PATH];

	szTitle[0] = 0;

	GetWindowText(WindowFromDC(hDC), szTitle, MAX_PATH);
	Add(_T("Window"),    _T("0x%X \"%s\""), WindowFromDC(hDC), szTitle);

	Add(_T("Bitmap"),        _T("0x%X"), GetCurrentObject(hDC, OBJ_BITMAP));

	Add(_T("Graphics Mode"), _T("%d"), GetGraphicsMode(hDC));
	Add(_T("Mapping Mode"),  _T("%d"), GetMapMode(hDC));

	GetViewportExtEx(hDC, & size);
	Add(_T("Viewport Extent"), _T("{ %d, %d }"), size.cx, size.cy);
	
	GetViewportOrgEx(hDC, & pnt);
	Add(_T("Viewport Origin"), _T("{ %d, %d }"), pnt.x, pnt.y);

	GetWindowExtEx(hDC, & size);
	Add(_T("Window Extent"), _T("{ %d, %d }"), size.cx, size.cy);
	
	GetWindowOrgEx(hDC, & pnt);
	Add(_T("Window Origin"), _T("{ %d, %d }"), pnt.x, pnt.y);

	XFORM xform;
	GetWorldTransform(hDC, & xform);

	Add(_T("World transformation"), _T("{ %f, %f, %f, %f, %f, %f }"),
		xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy);

	// transformation

	Add(_T("Background Color"), _T("0x%X"), GetBkColor(hDC));
	Add(_T("Text Color"),       _T("0x%X"), GetTextColor(hDC));
	Add(_T("Palette"),          _T("0x%X"), GetCurrentObject(hDC, OBJ_PAL));

	{
		COLORADJUSTMENT ca;
		GetColorAdjustment(hDC, & ca);
	
		Add(_T("Color Adjustment"), _T("{ %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d }"), 
			ca.caSize, ca.caFlags, ca.caIlluminantIndex,
			ca.caRedGamma, ca.caGreenGamma, ca.caBlueGamma, 
			ca.caReferenceBlack, ca.caReferenceWhite,
			ca.caContrast, ca.caBrightness, ca.caColorfulness, ca.caRedGreenTint);
	}

	Add(_T("Color Space"), _T("0x%X"), GetColorSpace(hDC));
	Add(_T("ICM Mode"),    _T("%d"),   SetICMMode(hDC, ICM_QUERY));

	{
		TCHAR szProfile[MAX_PATH];
		DWORD dwSize = MAX_PATH;

		szProfile[0] = 0;
		GetICMProfile(hDC, & dwSize, szProfile);

		Add(_T("ICM Profile"), _T("%s"), szProfile);
	}

	GetCurrentPositionEx(hDC, & pnt);
	Add(_T("Current Position"), _T("{ %d, %d }"), pnt.x, pnt.y);

	Add(_T("ROP2"),				_T("%d"),	GetROP2(hDC));
	Add(_T("Background Mode"),	_T("%d"),	GetBkMode(hDC));
	Add(_T("Logical Pen"),		_T("0x%X"), GetCurrentObject(hDC, OBJ_PEN));
	Add(_T("DC Pen Color"),     _T("0x%X"), GetDCPenColor(hDC));
	Add(_T("Arc Direction"),	_T("%d"),	GetArcDirection(hDC));

	FLOAT miter;
	GetMiterLimit(hDC, & miter);

	Add(_T("Miter Limit"),		_T("%f"),	miter);
	
	Add(_T("Logical Brush"),    _T("0x%X"), GetCurrentObject(hDC, OBJ_BRUSH));
	Add(_T("DC Brush Color"),   _T("0x%X"), GetDCBrushColor(hDC));

	GetBrushOrgEx(hDC, & pnt);
	Add(_T("Brush Origin"),     _T("{ %d, %d }"), pnt.x, pnt.y);

	Add(_T("Polygon Filling Mode"),   _T("%d"), GetPolyFillMode(hDC));
	Add(_T("Bitmap Stretching Mode"), _T("%d"), GetStretchBltMode(hDC));
	Add(_T("Logical Font"),			  _T("0x%X"), GetCurrentObject(hDC, OBJ_FONT));
	Add(_T("Inter-character spacing"), _T("%d"), GetTextCharacterExtra(hDC));

	DWORD flag = SetMapperFlags(hDC, 0);
	SetMapperFlags(hDC, flag);

	Add(_T("Font Mapper Flags"),       _T("0x%X"), flag);

	Add(_T("Text Alignment"),		   _T("0x%X"), GetTextAlign(hDC));

	Add(_T("Text Justification"),      _T("write only"), 0);

	Add(_T("Layout"),                  _T("%d"), GetLayout(hDC));

	Add(_T("Path"),					   _T("%d bytes"), GetPath(hDC, NULL, NULL, 0));

	RECT rect;

	int typ = GetClipBox(hDC, & rect);

	HRGN hRgn = CreateRectRgn(0, 0, 1, 1);
	
	GetClipRgn(hDC, hRgn);

	Add(_T("Clipping"),				   _T("type %d clip box { %d, %d, %d, %d } size %d bytes"), 
		typ, rect.left, rect.top, rect.right, rect.bottom,
		GetRegionData(hRgn, 0, NULL)
		);
	
	GetMetaRgn(hDC, hRgn);

	GetRgnBox(hRgn, & rect);
	Add(_T("Meta Region"), _T("size %d bytes, rgn box { %d, %d, %d, %d }"), 
		GetRegionData(hRgn, 0, NULL), rect.left, rect.top, rect.right, rect.bottom);

	for (int i=1; i<=5; i++)
	{
		int rslt = GetRandomRgn(hDC, hRgn, i);

		if ( rslt==1 )
		{
			GetRgnBox(hRgn, & rect);
			Add(_T("Random Region"), _T("size %d bytes, rgn box { %d, %d, %d, %d }"), 
			GetRegionData(hRgn, 0, NULL), rect.left, rect.top, rect.right, rect.bottom);
		}
		else if ( rslt==0 )
			Add(_T("Random Region"), _T("NULL"), 0);
		else
			Add(_T("Random Region"), _T("FAIL"), 0);
	}
	DeleteObject(hRgn);

	GetBoundsRect(hDC, & rect, 0);

	Add(_T("Bounds Rectangle"),		_T("{ %d, %d, %d, %d }"), 
		rect.left, rect.top, rect.right, rect.bottom);
}
Пример #29
0
/*************************************************************************
 *		ScrollDC   (X11DRV.@)
 */
BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
                      const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
{
    RECT rcSrc, rcClip, offset;
    INT dxdev, dydev, res;
    HRGN DstRgn, clipRgn, visrgn;
    INT code = X11DRV_START_EXPOSURES;

    TRACE("dx,dy %d,%d rcScroll %s rcClip %s hrgnUpdate %p lprcUpdate %p\n",
          dx, dy, wine_dbgstr_rect(lprcScroll), wine_dbgstr_rect(lprcClip),
          hrgnUpdate, lprcUpdate);
    /* enable X-exposure events */
    if (hrgnUpdate || lprcUpdate)
        ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
    /* get the visible region */
    visrgn=CreateRectRgn( 0, 0, 0, 0);
    GetRandomRgn( hdc, visrgn, SYSRGN);
    if( !(GetVersion() & 0x80000000)) {
        /* Window NT/2k/XP */
        POINT org;
        GetDCOrgEx(hdc, &org);
        OffsetRgn( visrgn, -org.x, -org.y);
    }
    /* intersect with the clipping Region if the DC has one */
    clipRgn = CreateRectRgn( 0, 0, 0, 0);
    if (GetClipRgn( hdc, clipRgn) != 1) {
        DeleteObject(clipRgn);
        clipRgn=NULL;
    } else
        CombineRgn( visrgn, visrgn, clipRgn, RGN_AND);
    /* only those pixels in the scroll rectangle that remain in the clipping
     * rect are scrolled. */
    if( lprcClip)
        rcClip = *lprcClip;
    else
        GetClipBox( hdc, &rcClip);
    rcSrc = rcClip;
    OffsetRect( &rcClip, -dx, -dy);
    IntersectRect( &rcSrc, &rcSrc, &rcClip);
    /* if an scroll rectangle is specified, only the pixels within that
     * rectangle are scrolled */
    if( lprcScroll)
        IntersectRect( &rcSrc, &rcSrc, lprcScroll);
    /* now convert to device coordinates */
    LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
    TRACE("source rect: %s\n", wine_dbgstr_rect(&rcSrc));
    /* also dx and dy */
    SetRect(&offset, 0, 0, dx, dy);
    LPtoDP(hdc, (LPPOINT)&offset, 2);
    dxdev = offset.right - offset.left;
    dydev = offset.bottom - offset.top;
    /* now intersect with the visible region to get the pixels that will
     * actually scroll */
    DstRgn = CreateRectRgnIndirect( &rcSrc);
    res = CombineRgn( DstRgn, DstRgn, visrgn, RGN_AND);
    /* and translate, giving the destination region */
    OffsetRgn( DstRgn, dxdev, dydev);
    if( TRACE_ON( scroll)) dump_region( "Destination scroll region: ", DstRgn);
    /* if there are any, do it */
    if( res > NULLREGION) {
        RECT rect ;
        /* clip to the destination region, so we can BitBlt with a simple
         * bounding rectangle */
        if( clipRgn)
            ExtSelectClipRgn( hdc, DstRgn, RGN_AND);
        else
            SelectClipRgn( hdc, DstRgn);
        GetRgnBox( DstRgn, &rect);
        DPtoLP(hdc, (LPPOINT)&rect, 2);
        TRACE("destination rect: %s\n", wine_dbgstr_rect(&rect));

        BitBlt( hdc, rect.left, rect.top,
                rect.right - rect.left, rect.bottom - rect.top,
                hdc, rect.left - dx, rect.top - dy, SRCCOPY);
    }
    /* compute the update areas.  This is the combined clip rectangle
     * minus the scrolled region, and intersected with the visible
     * region. */
    if (hrgnUpdate || lprcUpdate)
    {
        HRGN hrgn = hrgnUpdate;
        HRGN ExpRgn = 0;

        /* collect all the exposures */
        code = X11DRV_END_EXPOSURES;
        ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code,
                   sizeof(ExpRgn), (LPSTR)&ExpRgn );
        /* Intersect clip and scroll rectangles, allowing NULL values */
        if( lprcScroll)
            if( lprcClip)
                IntersectRect( &rcClip, lprcClip, lprcScroll);
            else
                rcClip = *lprcScroll;
        else if( lprcClip)
            rcClip = *lprcClip;
        else
            GetClipBox( hdc, &rcClip);
        /* Convert the combined clip rectangle to device coordinates */
        LPtoDP(hdc, (LPPOINT)&rcClip, 2);
        if( hrgn )
            SetRectRgn( hrgn, rcClip.left, rcClip.top, rcClip.right,
                        rcClip.bottom);
        else
            hrgn = CreateRectRgnIndirect( &rcClip);
        CombineRgn( hrgn, hrgn, visrgn, RGN_AND);
        CombineRgn( hrgn, hrgn, DstRgn, RGN_DIFF);
        /* add the exposures to this */
        if( ExpRgn) {
            if( TRACE_ON( scroll)) dump_region( "Expose region: ", ExpRgn);
            CombineRgn( hrgn, hrgn, ExpRgn, RGN_OR);
            DeleteObject( ExpRgn);
        }
        if( TRACE_ON( scroll)) dump_region( "Update region: ", hrgn);
        if( lprcUpdate) {
            GetRgnBox( hrgn, lprcUpdate );
            /* Put the lprcUpdate in logical coordinates */
            DPtoLP( hdc, (LPPOINT)lprcUpdate, 2 );
            TRACE("returning lprcUpdate %s\n", wine_dbgstr_rect(lprcUpdate));
        }
        if( !hrgnUpdate)
            DeleteObject( hrgn);
    }
    /* restore original clipping region */
    SelectClipRgn( hdc, clipRgn);
    DeleteObject( visrgn);
    DeleteObject( DstRgn);
    if( clipRgn) DeleteObject( clipRgn);
    return TRUE;
}
Пример #30
0
void SharedBitmap::drawPattern(HDC hdc, const AffineTransform& transform, const FloatRect& tileRectIn, const AffineTransform& patternTransform,
                        const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect, const IntSize& origSourceSize)
{
    if (!m_pixels)
        return;

    if (tileRectIn.width() <= 0 || tileRectIn.height() <= 0)
        return;

    bool useAlpha = op == CompositeSourceOver && hasAlpha() && is32bit();

    int bmpWidth = width();
    int bmpHeight = height();

    FloatRect tileRect(tileRectIn);
    if (bmpWidth != origSourceSize.width()) {
        double rate = static_cast<double>(bmpWidth) / origSourceSize.width();
        double temp = tileRect.width() * rate;
        tileRect.setX(tileRect.x() * rate);
        tileRect.setWidth(temp);
        temp = tileRect.height() * rate;
        tileRect.setY(tileRect.y() * rate);
        tileRect.setHeight(temp);
    }

    OwnPtr<HBITMAP> clippedBmp;

    if (tileRect.x() || tileRect.y() || tileRect.width() != bmpWidth || tileRect.height() != bmpHeight) {
        BitmapInfo patternBmpInfo;
        void* patternPixels;
        clippedBmp = clipBitmap(IntRect(tileRect), useAlpha, patternBmpInfo, patternPixels);
        if (!clippedBmp)
            return;

        bmpWidth = tileRect.width();
        bmpHeight = tileRect.height();
    }

    AffineTransform tf = patternTransform * transform;

    FloatRect trRect = tf.mapRect(destRect);

    RECT clipBox;
    int clipType = GetClipBox(hdc, &clipBox);
    if (clipType == SIMPLEREGION)
        trRect.intersect(FloatRect(clipBox.left, clipBox.top, clipBox.right - clipBox.left, clipBox.bottom - clipBox.top));
    else if (clipType == COMPLEXREGION) {
        OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgn(0, 0, 0, 0));
        if (GetClipRgn(hdc, clipRgn.get()) > 0) {
            DWORD regionDataSize = GetRegionData(clipRgn.get(), sizeof(RGNDATA), 0);
            if (regionDataSize) {
                Vector<RGNDATA> regionData(regionDataSize);
                GetRegionData(clipRgn.get(), regionDataSize, regionData.data());
                RECT* rect = reinterpret_cast<RECT*>(regionData[0].Buffer);
                for (DWORD i = 0; i < regionData[0].rdh.nCount; ++i, ++rect)
                    trRect.intersect(FloatRect(rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top));
            }
        }
    }

    if (trRect.width() <= 0 || trRect.height() <= 0)
        return;

    trRect.inflate(1);
    IntRect visibleDstRect = enclosingIntRect(tf.inverse().mapRect(trRect));
    visibleDstRect.intersect(IntRect(destRect));

    if (visibleDstRect.width() <= 0 || visibleDstRect.height() <= 0)
        return;

    trRect = tf.mapRect(visibleDstRect);
    RECT dstRectWin = {
        stableRound(trRect.x()),
        stableRound(trRect.y()),
        stableRound(trRect.maxX()),
        stableRound(trRect.maxY()),
    };
    if (dstRectWin.right <= dstRectWin.left || dstRectWin.bottom <= dstRectWin.top)
        return;

    SIZE bmpSize = { bmpWidth, bmpHeight };

    // Relative to destination, in bitmap pixels
    POINT phaseWin = { stableRound(visibleDstRect.x() - phase.x()), stableRound(visibleDstRect.y() - phase.y()) };
    phaseWin.x = normalizePhase(phaseWin.x, bmpSize.cx);
    phaseWin.y = normalizePhase(phaseWin.y, bmpSize.cy);

    RECT srcRectWin = {
        0,
        0,
        stableRound(visibleDstRect.maxX()) - stableRound(visibleDstRect.x()),
        stableRound(visibleDstRect.maxY()) - stableRound(visibleDstRect.y())
    };
    if (srcRectWin.right <= 0 || srcRectWin.bottom <= 0)
        return;

    BitmapInfo bmpInfo = BitmapInfo::createBottomUp(IntSize(srcRectWin.right, srcRectWin.bottom), useAlpha ? BitmapInfo::BitCount32 : BitmapInfo::BitCount16);
    void* pixels;
    OwnPtr<HBITMAP> hbmpTemp = adoptPtr(CreateDIBSection(0, &bmpInfo, DIB_RGB_COLORS, &pixels, 0, 0));

    if (!hbmpTemp)
        return;

    OwnPtr<HDC> hmemdc = adoptPtr(CreateCompatibleDC(hdc));
    HGDIOBJ oldBmp = SelectObject(hmemdc.get(), hbmpTemp.get());
    if (clippedBmp)
        drawPatternSimple(hmemdc.get(), srcRectWin, clippedBmp.get(), phaseWin);
    else if ((op != CompositeSourceOver || canUseDIBits()) && srcRectWin.right <= bmpSize.cx * 2 && srcRectWin.bottom <= bmpSize.cy * 2)
        drawPatternSimple(hmemdc.get(), srcRectWin, this, bmpSize, phaseWin);
    else if (ensureHandle())
        drawPatternSimple(hmemdc.get(), srcRectWin, getHandle(), phaseWin);
    else {
        void* pixels;
        BitmapInfo bmpInfo;
        OwnPtr<HBITMAP> hbmp = createHandle(&pixels, &bmpInfo, -1, false);
        if (hbmp)
            drawPatternSimple(hmemdc.get(), srcRectWin, hbmp.get(), phaseWin);
        else {
            SelectObject(hmemdc.get(), oldBmp);
            return;
        }
    }

    if (useAlpha && hasAlphaBlendSupport()) {
        static const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
        bool success = alphaBlendIfSupported(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left, dstRectWin.bottom - dstRectWin.top,
            hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, blend);
        ASSERT_UNUSED(success, success);
    } else if (useAlpha && !hasAlphaBlendSupport() || op == CompositeSourceOver && usesTransparentColor()) {
        TransparentBlt(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left,
            dstRectWin.bottom - dstRectWin.top, hmemdc.get(), 0, 0, srcRectWin.right, srcRectWin.bottom, transparentColor());
    } else {
        DWORD bmpOp = op == CompositeCopy ? SRCCOPY
                    : op == CompositeSourceOver ? SRCCOPY
                    : op == CompositeXOR ? PATINVERT
                    : op == CompositeClear ? WHITENESS
                    : SRCCOPY; // FIXEME: other types?

        StretchDIBits(hdc, dstRectWin.left, dstRectWin.top, dstRectWin.right - dstRectWin.left,
            dstRectWin.bottom - dstRectWin.top, 0, 0, srcRectWin.right, srcRectWin.bottom,
            pixels, &bmpInfo, DIB_RGB_COLORS, bmpOp);
    }
    SelectObject(hmemdc.get(), oldBmp);
}