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

问题描述 投票:1回答:1

我正在使用Embarcadero RAD Studio C ++构建器XE7。

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

通过测试我的代码,我注意到有时裁剪区域小于预期的大小。我搜索了为什么,我发现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;

注意这样写的,在他的上下文之外,上面的代码并没有真正意义,我知道这是不合逻辑的。请不要判断它的质量,这不是我的问题的目的。我收集了几个摘录,我将这些摘录分组为一个可执行代码,以解决问题。

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

  • 在sourceRect值中,left = 0,top = 0,right = 60,bottom = 7
  • middle = 50,top = 0,right = 60,bottom = 7 in intermediateRect value
  • 在finalRect中,left = 50,top = 0,right = 60,bottom = 6

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

gdi region clip rad-studio
1个回答
0
投票

所以我终于找到了案件的实质内容。根据这篇文章:

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

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

由于我在我的代码中错误地认为两个系统的原点始终是[0,0],所以在几个特殊情况下得到的区域可能是不正确的,导致这种奇怪的移动我有时会注意到剪切真正应用和我期望的。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.