GDI - OffsetRgn() 函数的意外结果

GDI - Unexpected result for the OffsetRgn() function

我正在使用 Embarcadero RAD Studio C++ builder XE7。

对于使用 Windows GDI 的绘图函数,我需要将剪辑区域添加到 canvas 的设备上下文中。

通过测试我的代码,我注意到有时裁剪区域小于预期大小。我搜索了原因,发现 OffsetRgn() 函数的一个奇怪行为让我有点困惑。

为了应用剪辑区域,我使用了类似于以下的代码:

std::unique_ptr<TBitmap> pBitmap(new TBitmap());
pBitmap->PixelFormat = pf32bit;
pBitmap->AlphaFormat = afDefined;
pBitmap->SetSize(60, 7);

TCanvas* pCanvas = pBitmap->Canvas;

::SelectClipRgn(pCanvas->Handle, NULL);

const TRect sourceRect = pCanvas->ClipRect;

HRGN pClipRegion = ::CreateRectRgn(50, -2, 60, 8);

::SelectClipRgn(pCanvas->Handle, pClipRegion);

const TRect intermediateRect = pCanvas->ClipRect;

const int deltaX = pCanvas->ClipRect.Left - 50;
const int deltaY = pCanvas->ClipRect.Top  - (-2);

::OffsetRgn(pClipRegion, -deltaX, -deltaY);

::SelectClipRgn(pCanvas->Handle, pClipRegion);

const TRect finalRect = pCanvas->ClipRect;

NOTE 像这样写并且脱离了他的上下文,上面的代码没有真正意义,我知道这是不合逻辑的。请不要评判它的好坏,这不是我提问的目的。我收集了几个摘录,并将其归类为一个可执行代码,提出了问题。

硬编码值是出现问题时我在应用程序中获得的值的示例。如果我执行上面的代码,我测量:

然而,我预计 finalRect 中的底部值也应等于 7,这是 canvas 限制,因为我只移动了该区域,没有其他任何移动。那么为什么它的值突然变得比预期的要小呢?

于是我终于找到了案情。基于此 post:

Why does calling GetRgnBox on the result of GetClipRgn return a very different rect than GetClipRect?

剪辑区域以相对于 canvas 原点的逻辑单位应用,而我尝试应用的剪辑矩形是从 [0, 0] 原点以像素为单位测量的。

因为我 在我的代码中错误地认为两个系统的原点总是 [0, 0],在一些特殊情况下,结果区域可能不正确,导致这个奇怪的移动我有时会注意到实际应用的剪辑和我预期的剪辑之间。

使用 GetWindowOrgEx() 函数测量 canvas 原点突出显示了该问题。

然而,对于上面显示的情况,问题出现了,因为剪辑区域移动了 -2 的偏移量,因此顶部的值为 -4,底部的值为 6,然后将其裁剪以适合 canvas 在应用剪辑区域时边界,导致顶部值为 0 底部值为 6 的剪辑。