mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Fixed GDI clipping issues
This commit is contained in:
parent
c78c7c927f
commit
2d30ff6f94
@ -16,9 +16,7 @@ namespace
|
||||
CompatDc(const CachedDc& cachedDc = {}) : CachedDc(cachedDc) {}
|
||||
DWORD refCount;
|
||||
HDC origDc;
|
||||
HGDIOBJ origFont;
|
||||
HGDIOBJ origBrush;
|
||||
HGDIOBJ origPen;
|
||||
int savedState;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<HDC, CompatDc> CompatDcMap;
|
||||
@ -27,15 +25,14 @@ namespace
|
||||
struct ExcludeClipRectsData
|
||||
{
|
||||
HDC compatDc;
|
||||
POINT origin;
|
||||
HWND rootWnd;
|
||||
};
|
||||
|
||||
void copyDcAttributes(CompatDc& compatDc, HDC origDc, POINT& origin)
|
||||
{
|
||||
compatDc.origFont = SelectObject(compatDc.dc, GetCurrentObject(origDc, OBJ_FONT));
|
||||
compatDc.origBrush = SelectObject(compatDc.dc, GetCurrentObject(origDc, OBJ_BRUSH));
|
||||
compatDc.origPen = SelectObject(compatDc.dc, GetCurrentObject(origDc, OBJ_PEN));
|
||||
SelectObject(compatDc.dc, GetCurrentObject(origDc, OBJ_FONT));
|
||||
SelectObject(compatDc.dc, GetCurrentObject(origDc, OBJ_BRUSH));
|
||||
SelectObject(compatDc.dc, GetCurrentObject(origDc, OBJ_PEN));
|
||||
|
||||
if (GM_ADVANCED == GetGraphicsMode(origDc))
|
||||
{
|
||||
@ -44,11 +41,6 @@ namespace
|
||||
GetWorldTransform(origDc, &transform);
|
||||
SetWorldTransform(compatDc.dc, &transform);
|
||||
}
|
||||
else if (GM_COMPATIBLE != GetGraphicsMode(compatDc.dc))
|
||||
{
|
||||
ModifyWorldTransform(compatDc.dc, nullptr, MWT_IDENTITY);
|
||||
SetGraphicsMode(compatDc.dc, GM_COMPATIBLE);
|
||||
}
|
||||
|
||||
SetMapMode(compatDc.dc, GetMapMode(origDc));
|
||||
|
||||
@ -101,17 +93,19 @@ namespace
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
RECT rect = {};
|
||||
GetWindowRect(hwnd, &rect);
|
||||
OffsetRect(&rect, -excludeClipRectsData->origin.x, -excludeClipRectsData->origin.y);
|
||||
ExcludeClipRect(excludeClipRectsData->compatDc, rect.left, rect.top, rect.right, rect.bottom);
|
||||
RECT windowRect = {};
|
||||
GetWindowRect(hwnd, &windowRect);
|
||||
|
||||
HRGN windowRgn = CreateRectRgnIndirect(&windowRect);
|
||||
ExtSelectClipRgn(excludeClipRectsData->compatDc, windowRgn, RGN_DIFF);
|
||||
DeleteObject(windowRgn);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void excludeClipRectsForOverlappingWindows(
|
||||
HWND hwnd, bool isMenuWindow, HDC compatDc, const POINT& origin)
|
||||
void excludeClipRectsForOverlappingWindows(HWND hwnd, bool isMenuWindow, HDC compatDc)
|
||||
{
|
||||
ExcludeClipRectsData excludeClipRectsData = { compatDc, origin, GetAncestor(hwnd, GA_ROOT) };
|
||||
ExcludeClipRectsData excludeClipRectsData = { compatDc, GetAncestor(hwnd, GA_ROOT) };
|
||||
if (!isMenuWindow)
|
||||
{
|
||||
EnumWindows(&excludeClipRectForOverlappingWindow,
|
||||
@ -129,35 +123,28 @@ namespace
|
||||
|
||||
void setClippingRegion(HDC compatDc, HDC origDc, HWND hwnd, bool isMenuWindow, const POINT& origin)
|
||||
{
|
||||
if (isMenuWindow)
|
||||
HRGN clipRgn = CreateRectRgn(0, 0, 0, 0);
|
||||
if (1 == GetClipRgn(origDc, clipRgn))
|
||||
{
|
||||
RECT windowRect = {};
|
||||
GetWindowRect(hwnd, &windowRect);
|
||||
|
||||
HRGN windowRgn = CreateRectRgnIndirect(&windowRect);
|
||||
SelectClipRgn(compatDc, windowRgn);
|
||||
DeleteObject(windowRgn);
|
||||
}
|
||||
else
|
||||
{
|
||||
HRGN clipRgn = CreateRectRgn(0, 0, 0, 0);
|
||||
const bool isEmptyClipRgn = 1 != GetRandomRgn(origDc, clipRgn, SYSRGN);
|
||||
SelectClipRgn(compatDc, isEmptyClipRgn ? nullptr : clipRgn);
|
||||
DeleteObject(clipRgn);
|
||||
|
||||
HRGN origClipRgn = CreateRectRgn(0, 0, 0, 0);
|
||||
if (1 == GetClipRgn(origDc, origClipRgn))
|
||||
{
|
||||
OffsetRgn(origClipRgn, origin.x, origin.y);
|
||||
ExtSelectClipRgn(compatDc, origClipRgn, RGN_AND);
|
||||
}
|
||||
DeleteObject(origClipRgn);
|
||||
OffsetRgn(clipRgn, origin.x, origin.y);
|
||||
SelectClipRgn(compatDc, clipRgn);
|
||||
}
|
||||
|
||||
if (hwnd)
|
||||
{
|
||||
excludeClipRectsForOverlappingWindows(hwnd, isMenuWindow, compatDc, origin);
|
||||
if (isMenuWindow || 1 != GetRandomRgn(origDc, clipRgn, SYSRGN))
|
||||
{
|
||||
RECT rect = {};
|
||||
GetWindowRect(hwnd, &rect);
|
||||
SetRectRgn(clipRgn, rect.left, rect.top, rect.right, rect.bottom);
|
||||
}
|
||||
|
||||
excludeClipRectsForOverlappingWindows(hwnd, isMenuWindow, compatDc);
|
||||
ExtSelectClipRgn(compatDc, clipRgn, RGN_AND);
|
||||
}
|
||||
|
||||
DeleteObject(clipRgn);
|
||||
SetMetaRgn(compatDc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +182,7 @@ namespace CompatGdiDc
|
||||
POINT origin = {};
|
||||
GetDCOrgEx(origDc, &origin);
|
||||
|
||||
compatDc.savedState = SaveDC(compatDc.dc);
|
||||
copyDcAttributes(compatDc, origDc, origin);
|
||||
setClippingRegion(compatDc.dc, origDc, hwnd, isMenuWindow, origin);
|
||||
|
||||
@ -226,9 +214,7 @@ namespace CompatGdiDc
|
||||
--compatDc.refCount;
|
||||
if (0 == compatDc.refCount)
|
||||
{
|
||||
SelectObject(compatDc.dc, compatDc.origFont);
|
||||
SelectObject(compatDc.dc, compatDc.origBrush);
|
||||
SelectObject(compatDc.dc, compatDc.origPen);
|
||||
RestoreDC(compatDc.dc, compatDc.savedState);
|
||||
CompatGdiDcCache::releaseDc(compatDc);
|
||||
g_origDcToCompatDc.erase(origDc);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user