From 794e7aaf596c1a4b611768c99bf248c9c757b877 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 31 Dec 2007 17:26:57 +0000 Subject: [PATCH] Implement gdi ScaleViewport/WindowExtEx and mirror region support. Mirroring is not finished and is unplugged. svn path=/trunk/; revision=31523 --- reactos/dll/win32/gdi32/misc/stubs.c | 57 ----- reactos/dll/win32/gdi32/objects/coord.c | 80 +++++++ reactos/dll/win32/gdi32/objects/region.c | 264 ++++++++++++++++------- 3 files changed, 270 insertions(+), 131 deletions(-) diff --git a/reactos/dll/win32/gdi32/misc/stubs.c b/reactos/dll/win32/gdi32/misc/stubs.c index 674c810b7c0..52b341530c9 100644 --- a/reactos/dll/win32/gdi32/misc/stubs.c +++ b/reactos/dll/win32/gdi32/misc/stubs.c @@ -674,47 +674,6 @@ SetAbortProc( return 0; } - -/* - * @unimplemented - */ -BOOL -STDCALL -ScaleViewportExtEx( - HDC a0, - int a1, - int a2, - int a3, - int a4, - LPSIZE a5 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - -/* - * @unimplemented - */ -BOOL -STDCALL -ScaleWindowExtEx( - HDC a0, - int a1, - int a2, - int a3, - int a4, - LPSIZE a5 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - /* * @implemented */ @@ -1464,22 +1423,6 @@ GetTextFaceAliasW(HDC hdc, return retValue; } - - -/* - * @unimplemented - */ -BOOL -STDCALL -MirrorRgn(HWND hwnd,HRGN hrgn) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - - - /* * @unimplemented */ diff --git a/reactos/dll/win32/gdi32/objects/coord.c b/reactos/dll/win32/gdi32/objects/coord.c index 0fc267f8f6a..09ee67c3148 100644 --- a/reactos/dll/win32/gdi32/objects/coord.c +++ b/reactos/dll/win32/gdi32/objects/coord.c @@ -562,6 +562,86 @@ SetViewportOrgEx(HDC hdc, return NtGdiSetViewportOrgEx(hdc,X,Y,lpPoint); } +/* + * @implemented + */ +BOOL +STDCALL +ScaleViewportExtEx( + HDC a0, + int a1, + int a2, + int a3, + int a4, + LPSIZE a5 + ) +{ +#if 0 + if (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(a0) == GDI_OBJECT_TYPE_METADC) + return MFDRV_; + else + { + PLDC pLDC = GdiGetLDC(a0); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_; + } + } + } +#endif + if (!GdiIsHandleValid((HGDIOBJ) a0) || + (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC)) return FALSE; + + return NtGdiScaleViewportExtEx(a0, a1, a2, a3, a4, a5); +} + +/* + * @implemented + */ +BOOL +STDCALL +ScaleWindowExtEx( + HDC a0, + int a1, + int a2, + int a3, + int a4, + LPSIZE a5 + ) +{ +#if 0 + if (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC) + { + if (GDI_HANDLE_GET_TYPE(a0) == GDI_OBJECT_TYPE_METADC) + return MFDRV_; + else + { + PLDC pLDC = GdiGetLDC(a0); + if ( !pLDC ) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + if (pLDC->iType == LDC_EMFLDC) + { + return EMFDRV_; + } + } + } +#endif + if (!GdiIsHandleValid((HGDIOBJ) a0) || + (GDI_HANDLE_GET_TYPE(a0) != GDI_OBJECT_TYPE_DC)) return FALSE; + + return NtGdiScaleWindowExtEx(a0, a1, a2, a3, a4, a5); +} + /* * @implemented */ diff --git a/reactos/dll/win32/gdi32/objects/region.c b/reactos/dll/win32/gdi32/objects/region.c index 7f6c39e997c..60cfee470c2 100644 --- a/reactos/dll/win32/gdi32/objects/region.c +++ b/reactos/dll/win32/gdi32/objects/region.c @@ -1,80 +1,30 @@ #include "precomp.h" -/* - * @implemented - */ -int STDCALL -SelectClipRgn( - HDC hdc, - HRGN hrgn -) +static +VOID +FASTCALL +SortRects(PRECT pRect, INT nCount) { - return ExtSelectClipRgn(hdc, hrgn, RGN_COPY); -} - - -/* - * @implemented - */ -int -STDCALL -GetClipRgn( - HDC hdc, - HRGN hrgn - ) -{ - return NtGdiGetRandomRgn(hdc, hrgn, 1); -} - - -HRGN -WINAPI -CreatePolygonRgn( const POINT * lppt, int cPoints, int fnPolyFillMode) -{ - return (HRGN) NtGdiPolyPolyDraw( (HDC) fnPolyFillMode, (PPOINT) lppt, (PULONG) &cPoints, 1, GdiPolyPolyRgn); -} - - -HRGN -WINAPI -CreatePolyPolygonRgn( const POINT* lppt, - const INT* lpPolyCounts, - int nCount, - int fnPolyFillMode) -{ - return (HRGN) NtGdiPolyPolyDraw( (HDC) fnPolyFillMode, (PPOINT) lppt, (PULONG) lpPolyCounts, (ULONG) nCount, GdiPolyPolyRgn ); -} - -HRGN -WINAPI -CreateEllipticRgnIndirect( - const RECT *prc -) -{ - /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */ - return NtGdiCreateEllipticRgn(prc->left, prc->top, prc->right, prc->bottom); - -} - -HRGN -WINAPI -CreateRectRgn(int x1, int y1, int x2,int y2) -{ - /* FIXME Some part need be done in user mode */ - return NtGdiCreateRectRgn(x1,y1,x2,y2); -} - - -HRGN -WINAPI -CreateRectRgnIndirect( - const RECT *prc -) -{ - /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */ - return CreateRectRgn(prc->left, prc->top, prc->right, prc->bottom); + INT i = 0, a = 0, b = 0; + RECT sRect; + if (nCount > 0) + { + for(;;) + { + do + { + if(pRect[b].top != pRect[i].bottom) break; + if(pRect[b].left < pRect[a].left) + { + sRect = pRect[a]; + pRect[a] = pRect[b]; + pRect[b] = sRect; + } + } while(0); + } + } } /* @@ -85,7 +35,7 @@ FASTCALL DeleteRegion( HRGN hRgn ) { #if 0 - PREGION_ATTR Rgn_Attr; + PRGN_ATTR Rgn_Attr; if ((GdiGetHandleUserData((HGDIOBJ) hRgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) && ( Rgn_Attr != NULL )) @@ -112,6 +62,131 @@ DeleteRegion( HRGN hRgn ) return NtGdiDeleteObjectApp((HGDIOBJ) hRgn); } +INT +FASTCALL +MirrorRgnByWidth(HRGN hRgn, INT Width, HRGN *phRgn) +{ + INT cRgnDSize, Ret = 0; + PRGNDATA pRgnData; + + cRgnDSize = NtGdiGetRegionData(hRgn, 0, NULL); + + if (cRgnDSize) + { + pRgnData = LocalAlloc(LMEM_FIXED, cRgnDSize * sizeof(LONG)); + if (pRgnData) + { + if ( GetRegionData(hRgn, cRgnDSize, pRgnData) ) + { + HRGN hRgnex; + INT i, SaveL = pRgnData->rdh.rcBound.left; + pRgnData->rdh.rcBound.left = Width - pRgnData->rdh.rcBound.right; + pRgnData->rdh.rcBound.right = Width - SaveL; + if (pRgnData->rdh.nCount > 0) + { + PRECT pRect = (PRECT)&pRgnData->Buffer; + for (i = 0; i < pRgnData->rdh.nCount; i++) + { + SaveL = pRect[i].left; + pRect[i].left = Width - pRect[i].right; + pRect[i].right = Width - SaveL; + } + } + SortRects((PRECT)&pRgnData->Buffer, pRgnData->rdh.nCount); + hRgnex = ExtCreateRegion(NULL, cRgnDSize , pRgnData); + if (hRgnex) + { + if (phRgn) phRgn = (HRGN *)hRgnex; + else + { + CombineRgn(hRgn, hRgnex, *phRgn, RGN_COPY); + DeleteObject(hRgnex); + } + Ret = 1; + } + } + LocalFree(pRgnData); + } + } + return Ret; +} + +INT +STDCALL +MirrorRgnDC(HDC hdc, HRGN hRgn, HRGN *phRgn) +{ + if (!GdiIsHandleValid((HGDIOBJ) hdc) || + (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)) return 0; + + return MirrorRgnByWidth(hRgn, NtGdiGetDeviceWidth(hdc), phRgn); +} + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +HRGN +WINAPI +CreatePolygonRgn( const POINT * lppt, int cPoints, int fnPolyFillMode) +{ + return (HRGN) NtGdiPolyPolyDraw( (HDC) fnPolyFillMode, (PPOINT) lppt, (PULONG) &cPoints, 1, GdiPolyPolyRgn); +} + + +/* + * @implemented + */ +HRGN +WINAPI +CreatePolyPolygonRgn( const POINT* lppt, + const INT* lpPolyCounts, + int nCount, + int fnPolyFillMode) +{ + return (HRGN) NtGdiPolyPolyDraw( (HDC) fnPolyFillMode, (PPOINT) lppt, (PULONG) lpPolyCounts, (ULONG) nCount, GdiPolyPolyRgn ); +} + + +/* + * @implemented + */ +HRGN +WINAPI +CreateEllipticRgnIndirect( + const RECT *prc +) +{ + /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */ + return NtGdiCreateEllipticRgn(prc->left, prc->top, prc->right, prc->bottom); + +} + +/* + * @implemented + */ +HRGN +WINAPI +CreateRectRgn(int x1, int y1, int x2,int y2) +{ + /* FIXME Some part need be done in user mode */ + return NtGdiCreateRectRgn(x1,y1,x2,y2); +} + +/* + * @implemented + */ +HRGN +WINAPI +CreateRectRgnIndirect( + const RECT *prc +) +{ + /* Notes if prc is NULL it will crash on All Windows NT I checked 2000/XP/VISTA */ + return CreateRectRgn(prc->left, prc->top, prc->right, prc->bottom); + +} + /* * @implemented */ @@ -136,6 +211,47 @@ ExtCreateRegion( return NULL; } +/* + * @implemented + */ +int +STDCALL +GetClipRgn( + HDC hdc, + HRGN hrgn + ) +{ + INT Ret = NtGdiGetRandomRgn(hdc, hrgn, 1); +// if (Ret) + // { + // if(GetLayout(hdc) & LAYOUT_RTL) MirrorRgnDC(hdc,(HRGN)Ret, NULL); + // } + return Ret; +} + +/* + * @implemented + */ +BOOL +STDCALL +MirrorRgn(HWND hwnd, HRGN hrgn) +{ + RECT Rect; + GetWindowRect(hwnd, &Rect); + return MirrorRgnByWidth(hrgn, Rect.right - Rect.left, NULL); +} + +/* + * @implemented + */ +int STDCALL +SelectClipRgn( + HDC hdc, + HRGN hrgn +) +{ + return ExtSelectClipRgn(hdc, hrgn, RGN_COPY); +} /* * @implemented @@ -149,7 +265,7 @@ SetRectRgn(HRGN hrgn, int nBottomRect) { #if 0 - PREGION_ATTR Rgn_Attr; + PRGN_ATTR Rgn_Attr; if (!GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &Rgn_Attr)) #endif