【发布时间】:2014-10-28 18:27:39
【问题描述】:
背景
我正在使用一个使用 GDI 绘制其内容的旧版 MFC 应用程序。
我需要绘制圆角矩形,其中每个角都有(可能)不同的半径。
这意味着我不能再使用RoundRect 并且必须使用ArcTo 自己滚动。
我正在使用SetWindowExtEx、SetWindowOrgEx、SetViewportExtEx 和SetViewportOrgExt 来实现缩放。
这在大多数情况下都可以正常工作。
问题
在某些缩放级别上,我的代码无法构建正确的圆形轮廓路径。
以下屏幕截图是我的RoundRect 代码用于创建路径,然后用于剪切更大的矩形(以了解它的形状)。
此路径创建的剪切区域有时会丢失一个角、剪切所有内容(两个丢失的角?)或什么都不剪切。
我的猜测是由于舍入误差,圆弧太小,被 GDI 一起跳过。 我觉得这很难相信,因为它可以在比这里图片更小的缩放系数下正常工作。
正常工作:
缺角:
守则
我试图减少重现它所需的代码,并最终得到以下结果。请注意,屏幕截图中的数字是唯一变量zoomFactor 的值。
您应该可以将此代码粘贴到新创建的 Win32 应用程序项目的 OnPaint 函数中,并手动将 zoomFactor 声明为常量。
SetMapMode(hdc, MM_ISOTROPIC);
SetWindowOrgEx(hdc, 0, 40, nullptr);
SetWindowExtEx(hdc, 8000, 6000, nullptr);
SetViewportOrgEx(hdc, 16, 56, nullptr);
SetViewportExtEx(hdc, 16 + (396)*zoomFactor/1000,
48 + (279)*zoomFactor/1000, nullptr);
BeginPath(hdc);
MoveToEx(hdc, 70, 1250, nullptr);
ArcTo(hdc,
50, 1250, 90, 1290,
70, 1250,
50, 1270);
ArcTo(hdc,
50, 2311, 90, 2351,
50, 2331,
70, 2351);
ArcTo(hdc,
1068, 2311, 1108, 2351,
1088, 2351,
1108, 2331);
ArcTo(hdc,
1068, 1250, 1108, 1290,
1108, 1270,
1088, 1250);
CloseFigure(hdc);
EndPath(hdc);
SelectClipPath(hdc, RGN_AND);
HBRUSH br = CreateSolidBrush(RGB(255,0,255));
const RECT r = {0, 0, 8000, 6000};
FillRect(hdc, &r, br);
【问题讨论】:
-
你有没有考虑为每个角画一个单独的RoundRect,然后填充剩余的中心垂直和水平条纹?
-
@user1793036,是的。我有,但我需要为大纲生成一条路径,这是我遇到的问题。画的东西很好。