diff --git a/reactos/dll/win32/gdi32/objects/region.c b/reactos/dll/win32/gdi32/objects/region.c index e32abac26f0..3c809b3e118 100644 --- a/reactos/dll/win32/gdi32/objects/region.c +++ b/reactos/dll/win32/gdi32/objects/region.c @@ -232,7 +232,7 @@ GetClipRgn( HRGN hrgn ) { - INT Ret = NtGdiGetRandomRgn(hdc, hrgn, 1); + INT Ret = NtGdiGetRandomRgn(hdc, hrgn, CLIPRGN); // if (Ret) // { // if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL); @@ -248,7 +248,7 @@ STDCALL GetMetaRgn(HDC hdc, HRGN hrgn) { - return NtGdiGetRandomRgn(hdc,hrgn,2); + return NtGdiGetRandomRgn(hdc, hrgn, METARGN); } /* diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 75f9fe21ce4..997d18b127f 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -115,7 +115,7 @@ typedef struct _DC PVOID prfnt; // RFONT* unsigned co_[31]; // CLIPOBJ PVOID pPFFList; // PPFF* - PVOID ClrxFormObj; + PVOID ClrxFormLnk; INT ipfdDevMax; ULONG ulCopyCount; PVOID pSurfInfo; @@ -129,9 +129,6 @@ typedef struct _DC XLATEOBJ *XlateBrush; XLATEOBJ *XlatePen; - INT saveLevel; // DCLEVEL lSaveDepth - HDC hSelf; // DCLEVEL hdcSave Used only for MemoryDC & SaveDC. - UNICODE_STRING DriverName; } DC, *PDC; @@ -264,4 +261,5 @@ VOID FASTCALL IntGdiUnreferencePdev(PGDIDEVICE pPDev, DWORD CleanUpType); HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC); BOOL FASTCALL IntGdiCleanDC(HDC hDC); + #endif /* not __WIN32K_DC_H */ diff --git a/reactos/subsystems/win32/win32k/objects/arc.c b/reactos/subsystems/win32/win32k/objects/arc.c index f07a5e34a89..de8361e2af3 100644 --- a/reactos/subsystems/win32/win32k/objects/arc.c +++ b/reactos/subsystems/win32/win32k/objects/arc.c @@ -38,26 +38,6 @@ IntGdiArcInternal( IntGdiSetRect(&rc, LeftRect, TopRect, RightRect, BottomRect); IntGdiSetRect(&rc1, XStartArc, YStartArc, XEndArc, YEndArc); - if (dc->w.flags & DCX_WINDOW) //window rectangle instead of client rectangle - { - HWND hWnd; - PWINDOW_OBJECT Window; - - hWnd = IntWindowFromDC((HDC) dc->BaseObject.hHmgr); - Window = UserGetWindowObject(hWnd); - if(!Window) return FALSE; - - rc.left += Window->Wnd->ClientRect.left; - rc.top += Window->Wnd->ClientRect.top; - rc.right += Window->Wnd->ClientRect.left; - rc.bottom += Window->Wnd->ClientRect.top; - - rc1.left += Window->Wnd->ClientRect.left; - rc1.top += Window->Wnd->ClientRect.top; - rc1.right += Window->Wnd->ClientRect.left; - rc1.bottom += Window->Wnd->ClientRect.top; - } - rx = (rc.right - rc.left)/2 - 1; ry = (rc.bottom - rc.top)/2 -1; rc.left += rx; diff --git a/reactos/subsystems/win32/win32k/objects/cliprgn.c b/reactos/subsystems/win32/win32k/objects/cliprgn.c index bd47c37bec8..3f49f212ceb 100644 --- a/reactos/subsystems/win32/win32k/objects/cliprgn.c +++ b/reactos/subsystems/win32/win32k/objects/cliprgn.c @@ -225,13 +225,6 @@ NtGdiGetAppClipBox(HDC hDC, LPRECT rc) return Ret; } -int STDCALL NtGdiGetMetaRgn(HDC hDC, - HRGN hrgn) -{ - UNIMPLEMENTED; - return 0; -} - int STDCALL NtGdiExcludeClipRect(HDC hDC, int LeftRect, int TopRect, @@ -430,10 +423,146 @@ BOOL STDCALL NtGdiRectVisible(HDC hDC, return Result; } +int +FASTCALL +IntGdiSetMetaRgn(PDC pDC) +{ + INT Ret = ERROR; + PROSRGNDATA TempRgn; + + if ( pDC->DcLevel.prgnMeta ) + { + if ( pDC->DcLevel.prgnClip ) + { + TempRgn = REGION_AllocRgnWithHandle(1); + + if (TempRgn) + { + REGION_SetRectRgn(TempRgn, 0, 0, 0, 0); + Ret = IntGdiCombineRgn( TempRgn, + pDC->DcLevel.prgnMeta, + pDC->DcLevel.prgnClip, + RGN_AND); + if ( Ret ) + { + REGION_UnlockRgn(TempRgn); + TempRgn = GDIOBJ_ShareLockObj(TempRgn->BaseObject.hHmgr, + GDI_OBJECT_TYPE_REGION); + + GDIOBJ_ShareUnlockObjByPtr(pDC->DcLevel.prgnMeta); + if (!((PROSRGNDATA)pDC->DcLevel.prgnMeta)->BaseObject.ulShareCount) + REGION_FreeRgn(pDC->DcLevel.prgnMeta); + + pDC->DcLevel.prgnMeta = TempRgn; + + GDIOBJ_ShareUnlockObjByPtr(pDC->DcLevel.prgnClip); + if (!((PROSRGNDATA)pDC->DcLevel.prgnClip)->BaseObject.ulShareCount) + REGION_FreeRgn(pDC->DcLevel.prgnClip); + + pDC->DcLevel.prgnClip = NULL; + + pDC->DC_Flags |= DC_FLAG_DIRTY_RAO; + pDC->erclClip.left = 0; + pDC->erclClip.top = 0; + pDC->erclClip.right = 0; + pDC->erclClip.bottom = 0; + + } + else + REGION_FreeRgn(TempRgn); + } + } + else + Ret = REGION_Complexity(pDC->DcLevel.prgnMeta); + } + else + { + if ( pDC->DcLevel.prgnClip ) + { + Ret = REGION_Complexity(pDC->DcLevel.prgnClip); + pDC->DcLevel.prgnMeta = pDC->DcLevel.prgnClip; + pDC->DcLevel.prgnClip = NULL; + } + else + Ret = SIMPLEREGION; + } + return Ret; +} + + int STDCALL NtGdiSetMetaRgn(HDC hDC) { - UNIMPLEMENTED; - return 0; + INT Ret; + PDC pDC = DC_LockDc(hDC); + + if (!pDC) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return ERROR; + } + Ret = IntGdiSetMetaRgn(pDC); + + DC_UnlockDc(pDC); + return Ret; +} + +INT FASTCALL +NEW_CLIPPING_UpdateGCRegion(PDC pDC) +{ + CLIPOBJ * co; + + if (!pDC->prgnVis) return 0; + + if (pDC->prgnAPI) + { + REGION_FreeRgn(pDC->prgnAPI); + pDC->prgnAPI = REGION_AllocRgnWithHandle(1); + REGION_SetRectRgn(pDC->prgnAPI, 0, 0, 0, 0); + } + + if (pDC->prgnRao) + { + REGION_FreeRgn(pDC->prgnRao); + pDC->prgnRao = REGION_AllocRgnWithHandle(1); + REGION_SetRectRgn(pDC->prgnRao, 0, 0, 0, 0); + } + + if (pDC->DcLevel.prgnMeta && pDC->DcLevel.prgnClip) + { + IntGdiCombineRgn( pDC->prgnAPI, + pDC->DcLevel.prgnClip, + pDC->DcLevel.prgnMeta, + RGN_AND); + } + else + { + if (pDC->DcLevel.prgnClip) + IntGdiCombineRgn( pDC->prgnAPI, + pDC->DcLevel.prgnClip, + NULL, + RGN_COPY); + else if (pDC->DcLevel.prgnMeta) + IntGdiCombineRgn( pDC->prgnAPI, + pDC->DcLevel.prgnMeta, + NULL, + RGN_COPY); + } + + IntGdiCombineRgn( pDC->prgnRao, + pDC->prgnVis, + pDC->prgnAPI, + RGN_AND); + + RtlCopyMemory(&pDC->erclClip, &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound , sizeof(RECTL)); + pDC->DC_Flags &= ~DC_FLAG_DIRTY_RAO; + +// if (Dc->CombinedClip != NULL) IntEngDeleteClipRegion(Dc->CombinedClip); + + co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount, + (PRECTL)((PROSRGNDATA)pDC->prgnRao)->Buffer, + (PRECTL)&pDC->erclClip); + + return REGION_Complexity(pDC->prgnRao); } /* EOF */ diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 2601f4af2e2..c9d86c41f90 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -107,7 +107,7 @@ NtGdiCreateCompatibleDC(HDC hDC) if(!nDc_Attr) nDc_Attr = &NewDC->Dc_Attr; /* Copy information from original DC to new DC */ - NewDC->hSelf = hNewDC; + NewDC->DcLevel.hdcSave = hNewDC; NewDC->PDev = OrigDC->PDev; @@ -1001,7 +1001,7 @@ IntGdiDeleteDC(HDC hDC, BOOL Force) } /* First delete all saved DCs */ - while (DCToDelete->saveLevel) + while (DCToDelete->DcLevel.lSaveDepth) { PDC savedDC; HDC savedHDC; @@ -1013,7 +1013,7 @@ IntGdiDeleteDC(HDC hDC, BOOL Force) break; } DC_SetNextDC (DCToDelete, DC_GetNextDC (savedDC)); - DCToDelete->saveLevel--; + DCToDelete->DcLevel.lSaveDepth--; DC_UnlockDc( savedDC ); IntGdiDeleteDC(savedHDC, Force); } @@ -1376,7 +1376,7 @@ IntGdiCopyToSaveState(PDC dc, PDC newdc) nDc_Attr->ptlViewportOrg = Dc_Attr->ptlViewportOrg; nDc_Attr->szlViewportExt = Dc_Attr->szlViewportExt; - newdc->saveLevel = 0; + newdc->DcLevel.lSaveDepth = 0; newdc->DC_Type = dc->DC_Type; #if 0 @@ -1518,7 +1518,7 @@ IntGdiGetDCState(HDC hDC) /* FIXME - newdc can be NULL!!!! Don't assert here!!! */ ASSERT( newdc ); - newdc->hSelf = hnewdc; + newdc->DcLevel.hdcSave = hnewdc; IntGdiCopyToSaveState( dc, newdc); DC_UnlockDc( newdc ); @@ -1541,7 +1541,7 @@ IntGdiSetDCState ( HDC hDC, HDC hDCSave ) { if ( dcs->w.flags & DC_SAVED ) { - IntGdiCopyFromSaveState( dc, dcs, dc->hSelf); + IntGdiCopyFromSaveState( dc, dcs, dc->DcLevel.hdcSave); } else { @@ -1805,16 +1805,16 @@ NtGdiRestoreDC(HDC hDC, INT SaveLevel) } if (SaveLevel < 0) - SaveLevel = dc->saveLevel + SaveLevel + 1; + SaveLevel = dc->DcLevel.lSaveDepth + SaveLevel + 1; - if(SaveLevel < 0 || dc->saveLevelDcLevel.lSaveDepthsaveLevel >= SaveLevel) + while (dc->DcLevel.lSaveDepth >= SaveLevel) { HDC hdcs = DC_GetNextDC (dc); @@ -1828,7 +1828,7 @@ NtGdiRestoreDC(HDC hDC, INT SaveLevel) DC_SetNextDC (dc, DC_GetNextDC (dcs)); dcs->hNext = 0; - if (--dc->saveLevel < SaveLevel) + if (--dc->DcLevel.lSaveDepth < SaveLevel) { DC_UnlockDc( dc ); DC_UnlockDc( dcs ); @@ -1903,7 +1903,7 @@ NtGdiSaveDC(HDC hDC) DC_SetNextDC (dcs, DC_GetNextDC (dc)); DC_SetNextDC (dc, hdcs); - ret = ++dc->saveLevel; + ret = ++dc->DcLevel.lSaveDepth; DC_UnlockDc( dcs ); DC_UnlockDc( dc ); diff --git a/reactos/subsystems/win32/win32k/objects/region.c b/reactos/subsystems/win32/win32k/objects/region.c index 72aac3afdf4..033cf2588e5 100644 --- a/reactos/subsystems/win32/win32k/objects/region.c +++ b/reactos/subsystems/win32/win32k/objects/region.c @@ -138,7 +138,7 @@ SOFTWARE. (pReg)->rdh.nCount = 0; \ (pReg)->rdh.rcBound.left = (pReg)->rdh.rcBound.top = 0; \ (pReg)->rdh.rcBound.right = (pReg)->rdh.rcBound.bottom = 0; \ - (pReg)->rdh.iType = NULLREGION; \ + (pReg)->rdh.iType = RDH_RECTANGLES; \ } #define REGION_NOT_EMPTY(pReg) pReg->rdh.nCount @@ -542,7 +542,7 @@ REGION_SetExtents(ROSRGNDATA *pReg) pReg->rdh.rcBound.top = 0; pReg->rdh.rcBound.right = 0; pReg->rdh.rcBound.bottom = 0; - pReg->rdh.iType = NULLREGION; + pReg->rdh.iType = RDH_RECTANGLES; return; } @@ -570,7 +570,7 @@ REGION_SetExtents(ROSRGNDATA *pReg) pExtents->right = pRect->right; pRect++; } - pReg->rdh.iType = (1 == pReg->rdh.nCount ? SIMPLEREGION : COMPLEXREGION); + pReg->rdh.iType = RDH_RECTANGLES; } // FIXME: This seems to be wrong @@ -724,7 +724,7 @@ REGION_CropAndOffsetRegion( rgnDst->rdh.rcBound.top = ((PRECT)rgnDst->Buffer)->top; rgnDst->rdh.rcBound.bottom = ((PRECT)rgnDst->Buffer + j)->bottom; - rgnDst->rdh.iType = (j >= 1) ? COMPLEXREGION : SIMPLEREGION; + rgnDst->rdh.iType = RDH_RECTANGLES; } return TRUE; @@ -1182,11 +1182,6 @@ REGION_RegionOp( } } - if (newReg->rdh.nCount == 0) - newReg->rdh.iType = NULLREGION; - else - newReg->rdh.iType = (newReg->rdh.nCount > 1)? COMPLEXREGION : SIMPLEREGION; - if (oldRects != &newReg->rdh.rcBound) ExFreePool(oldRects); return; @@ -1886,7 +1881,7 @@ REGION_CreateFrameRgn( return FALSE; } - if (srcObj->rdh.iType == SIMPLEREGION) + if (REGION_Complexity(srcObj) == SIMPLEREGION) { if (!REGION_CreateSimpleFrameRgn(destObj, x, y)) { @@ -2096,7 +2091,7 @@ IntGdiCombineRgn(PROSRGNDATA destRgn, { if ( !REGION_CopyRegion(destRgn, src1Rgn) ) return ERROR; - result = destRgn->rdh.iType; + result = REGION_Complexity(destRgn); } else { @@ -2117,7 +2112,7 @@ IntGdiCombineRgn(PROSRGNDATA destRgn, REGION_SubtractRegion(destRgn, src1Rgn, src2Rgn); break; } - result = destRgn->rdh.iType; + result = REGION_Complexity(destRgn); } else if (src2Rgn == NULL) { @@ -2156,7 +2151,7 @@ NtGdiCombineRgn(HRGN hDest, { if ( !REGION_CopyRegion(destRgn, src1Rgn) ) return ERROR; - result = destRgn->rdh.iType; + result = REGION_Complexity(destRgn); } else { @@ -2179,7 +2174,7 @@ NtGdiCombineRgn(HRGN hDest, break; } REGION_UnlockRgn(src2Rgn); - result = destRgn->rdh.iType; + result = REGION_Complexity(destRgn); } else if (hSrc2 == NULL) { @@ -2554,7 +2549,7 @@ REGION_GetRgnBox( if (Rgn) { *pRect = Rgn->rdh.rcBound; - ret = Rgn->rdh.iType; + ret = REGION_Complexity(Rgn); return ret; } @@ -2562,7 +2557,21 @@ REGION_GetRgnBox( } -/* See wine, msdn, osr and Feng Yuan - Windows Graphics Programming Win32 Gdi And Directdraw */ +/* See wine, msdn, osr and Feng Yuan - Windows Graphics Programming Win32 Gdi And Directdraw + + 1st: http://www.codeproject.com/gdi/cliprgnguide.asp is wrong! + + The intersection of the clip with the meta region is not Rao it's API! + Go back and read 7.2 Clipping pages 418-19: + Rao = API & Vis: + 1) The Rao region is the intersection of the API region and the system region, + named after the Microsoft engineer who initially proposed it. + 2) The Rao region can be calculated from the API region and the system region. + + API: + API region is the intersection of the meta region and the clipping region, + clearly named after the fact that it is controlled by GDI API calls. +*/ INT STDCALL NtGdiGetRandomRgn( HDC hDC, @@ -2584,16 +2593,14 @@ NtGdiGetRandomRgn( switch (iCode) { - case 1: + case CLIPRGN: hSrc = pDC->w.hClipRgn; +// if (dc->DcLevel.prgnClip) hSrc = ((PROSRGNDATA)dc->DcLevel.prgnClip)->BaseObject.hHmgr; break; - case 2: - //hSrc = dc->hMetaRgn; - DPRINT1("hMetaRgn not implemented\n"); - DC_UnlockDc(pDC); - return -1; + case METARGN: + if (pDC->DcLevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->DcLevel.prgnMeta)->BaseObject.hHmgr; break; - case 3: + case APIRGN: DPRINT1("hMetaRgn not implemented\n"); //hSrc = dc->hMetaClipRgn; if (!hSrc) @@ -2601,9 +2608,11 @@ NtGdiGetRandomRgn( hSrc = pDC->w.hClipRgn; } //if (!hSrc) rgn = dc->hMetaRgn; +// if (dc->prgnAPI) hSrc = ((PROSRGNDATA)dc->prgnAPI)->BaseObject.hHmgr; break; - case 4: + case SYSRGN: hSrc = pDC->w.hVisRgn; +// if (dc->prgnVis) hSrc = ((PROSRGNDATA)dc->prgnVis)->BaseObject.hHmgr; break; default: hSrc = 0; @@ -2768,7 +2777,7 @@ NtGdiOffsetRgn( } } } - ret = rgn->rdh.iType; + ret = REGION_Complexity(rgn); REGION_UnlockRgn(rgn); return ret; } @@ -2984,7 +2993,7 @@ REGION_SetRectRgn( firstRect->right = rgn->rdh.rcBound.right = RightRect; firstRect->bottom = rgn->rdh.rcBound.bottom = BottomRect; rgn->rdh.nCount = 1; - rgn->rdh.iType = SIMPLEREGION; + rgn->rdh.iType = RDH_RECTANGLES; } else EMPTY_REGION(rgn);