// CDIB <- CDIB void CDIB::ClipDraw( int dx, int dy, int dw, int dh, CDIB* dib, int sx, int sy ) { SelectClipRgn(DC, dib->Rgn); OffsetClipRgn(DC, dx-sx, dy-sy); StretchBlt(DC, dx, dy, dw, dh, dib->DC, sx, sy, dw, dh, SRCCOPY); SelectClipRgn(DC, NULL); }
void CDrawContext::SetClipRect( const CRect &rc ) { HRGN hrgn = CreateRectRgnIndirect( &rc ); ::SelectClipRgn( m_hdc, hrgn ); POINT pt; GetWindowOrgEx( m_hdc, &pt ); OffsetClipRgn( m_hdc, -pt.x, -pt.y ); VAPI( ::DeleteObject( hrgn ) ); }
// DC <- CDIB void CDIB::ClipDraw( HDC dc, int dx, int dy, int dw, int dh, int sx, int sy ) { POINT p; GetViewportOrgEx(dc, &p); SelectClipRgn(dc, Rgn); OffsetClipRgn(dc, p.x+dx-sx, p.y+dy-sy); StretchBlt(dc, dx, dy, dw, dh, DC, sx, sy, dw, dh, SRCCOPY); SelectClipRgn(dc, NULL); }
void VDVideoWindow::NCPaint(HRGN hrgn) { HDC hdc; // MSDN docs are in error -- if you do not include 0x10000, GetDCEx() will // return NULL but still won't set an error flag. Feng Yuan's Windows // Graphics book calls this the "undocumented flag that makes GetDCEx() // succeed" flag. ^^; // // WINE's source code documents it as DCX_USESTYLE, which makes more sense, // and that is the way WINE's DefWindowProc() handles WM_NCPAINT. This is // a cleaner solution than using DCX_CACHE, which also works but overrides // CS_OWNDC and CS_PARENTDC. I'm not going to argue with years of reverse // engineering. // // NOTE: Using DCX_INTERSECTRGN as recommended by MSDN causes Windows 98 // GDI to intermittently crash! hdc = GetDCEx(mhwnd, NULL, DCX_WINDOW|0x10000); if (hdc) { RECT rc; GetWindowRect(mhwnd, &rc); if ((WPARAM)hrgn > 1) { OffsetClipRgn(hdc, rc.left, rc.top); ExtSelectClipRgn(hdc, hrgn, RGN_AND); OffsetClipRgn(hdc, -rc.left, -rc.top); } OffsetRect(&rc, -rc.left, -rc.top); DrawEdge(hdc, &rc, BDR_RAISEDOUTER|BDR_RAISEDINNER, BF_RECT); rc.left += 2; rc.right -= 2; rc.top += 2; rc.bottom -= 2; DrawEdge(hdc, &rc, BDR_SUNKENOUTER|BDR_SUNKENINNER, BF_RECT); ReleaseDC(mhwnd, hdc); } }
int XCopyArea( Display *display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y) { HDC srcDC, destDC; TkWinDCState srcState, destState; TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; srcDC = TkWinGetDrawableDC(display, src, &srcState); if (src != dest) { destDC = TkWinGetDrawableDC(display, dest, &destState); } else { destDC = srcDC; } if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { SelectClipRgn(destDC, (HRGN) clipPtr->value.region); OffsetClipRgn(destDC, gc->clip_x_origin, gc->clip_y_origin); } BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC, src_x, src_y, (DWORD) tkpWinBltModes[gc->function]); SelectClipRgn(destDC, NULL); if (src != dest) { TkWinReleaseDrawableDC(dest, destDC, &destState); } TkWinReleaseDrawableDC(src, srcDC, &srcState); return Success; }
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 ); }
void XCopyPlane( Display *display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y, unsigned long plane) { HDC srcDC, destDC; TkWinDCState srcState, destState; HBRUSH bgBrush, fgBrush, oldBrush; TkpClipMask *clipPtr = (TkpClipMask*)gc->clip_mask; display->request++; if (plane != 1) { Tcl_Panic("Unexpected plane specified for XCopyPlane"); } srcDC = TkWinGetDrawableDC(display, src, &srcState); if (src != dest) { destDC = TkWinGetDrawableDC(display, dest, &destState); } else { destDC = srcDC; } if (clipPtr == NULL || clipPtr->type == TKP_CLIP_REGION) { /* * Case 1: opaque bitmaps. Windows handles the conversion from one bit * to multiple bits by setting 0 to the foreground color, and 1 to the * background color (seems backwards, but there you are). */ if (clipPtr && clipPtr->type == TKP_CLIP_REGION) { SelectClipRgn(destDC, (HRGN) clipPtr->value.region); OffsetClipRgn(destDC, gc->clip_x_origin, gc->clip_y_origin); } SetBkMode(destDC, OPAQUE); SetBkColor(destDC, gc->foreground); SetTextColor(destDC, gc->background); BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC, src_x, src_y, SRCCOPY); SelectClipRgn(destDC, NULL); } else if (clipPtr->type == TKP_CLIP_PIXMAP) { if (clipPtr->value.pixmap == src) { /* * Case 2: transparent bitmaps are handled by setting the * destination to the foreground color whenever the source pixel * is set. */ fgBrush = CreateSolidBrush(gc->foreground); oldBrush = SelectObject(destDC, fgBrush); SetBkColor(destDC, RGB(255,255,255)); SetTextColor(destDC, RGB(0,0,0)); BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, srcDC, src_x, src_y, MASKPAT); SelectObject(destDC, oldBrush); DeleteObject(fgBrush); } else { /* * Case 3: two arbitrary bitmaps. Copy the source rectangle into a * color pixmap. Use the result as a brush when copying the clip * mask into the destination. */ HDC memDC, maskDC; HBITMAP bitmap; TkWinDCState maskState; fgBrush = CreateSolidBrush(gc->foreground); bgBrush = CreateSolidBrush(gc->background); maskDC = TkWinGetDrawableDC(display, clipPtr->value.pixmap, &maskState); memDC = CreateCompatibleDC(destDC); bitmap = CreateBitmap((int) width, (int) height, 1, 1, NULL); SelectObject(memDC, bitmap); /* * Set foreground bits. We create a new bitmap containing (source * AND mask), then use it to set the foreground color into the * destination. */ BitBlt(memDC, 0, 0, (int) width, (int) height, srcDC, src_x, src_y, SRCCOPY); BitBlt(memDC, 0, 0, (int) width, (int) height, maskDC, dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, SRCAND); oldBrush = SelectObject(destDC, fgBrush); BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, memDC, 0, 0, MASKPAT); /* * Set background bits. Same as foreground, except we use ((NOT * source) AND mask) and the background brush. */ BitBlt(memDC, 0, 0, (int) width, (int) height, srcDC, src_x, src_y, NOTSRCCOPY); BitBlt(memDC, 0, 0, (int) width, (int) height, maskDC, dest_x - gc->clip_x_origin, dest_y - gc->clip_y_origin, SRCAND); SelectObject(destDC, bgBrush); BitBlt(destDC, dest_x, dest_y, (int) width, (int) height, memDC, 0, 0, MASKPAT); TkWinReleaseDrawableDC(clipPtr->value.pixmap, maskDC, &maskState); SelectObject(destDC, oldBrush); DeleteDC(memDC); DeleteObject(bitmap); DeleteObject(fgBrush); DeleteObject(bgBrush); } } if (src != dest) { TkWinReleaseDrawableDC(dest, destDC, &destState); } TkWinReleaseDrawableDC(src, srcDC, &srcState); }