GDI +破折号模式是否被窃听? [英] Is GDI+ dash pattern bugged?

查看:84
本文介绍了GDI +破折号模式是否被窃听?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我正在使用Embarcadero RAD Studio XE7来创建一个C ++图形应用程序,我正在尝试使用GDI +和一些破折号模式属性为循环进度设置动画。

I'm using Embarcadero RAD Studio XE7 to create a C++ graphical application in which I'm trying to animate a circular progress using GDI+ and some dash pattern properties.

这个想法非常简单:通过配置一个模式,其中短划线足够长以填充圆的圆周,并且空白部分足够长以防止两个破折号在圆上一起可见,可以显示循环
进度,其中破折号偏移属性可用于显示当前进度位置。

The idea is very simple: by configuring a pattern where the dash is long enough to fill the circumference of a circle, and where the blank part is long enough to prevent that two dashes are visible together on the circle, it is possible to show a circular progress where the dash offset property may be used to display the current progress position.

但是,我无法达到我的目标GDI +,因为几个图形工件是可见的,我无法找到解决它们的解决方案。我很确定我使用的值是正确的,因为Direct2D
处理的完全相同的绘图工作正常。

However, I'm unable to reaching my goal with GDI+, because several graphical artifacts are visible, and I'm unable to find a solution to resolve them. I'm pretty sure that the values I use are correct, because the exactly same drawing processed by Direct2D works fine.

下面是一个显示问题的示例代码。一个圆圈用GDI +绘制,另一个圆圈用Direct2D绘制。 2个圆圈的绘图配置完全相同。

Here is a sample code showing the issue. One circle is drawn with GDI+, the other with Direct2D. The drawing configuration are exactly the same for the 2 circles.

// fill the background
TRect rect(0, 0, ClientWidth, ClientHeight);
Canvas->Brush->Color = clWhite;
Canvas->Brush->Style = bsSolid;
Canvas->FillRect(rect);

const float startY     =  100.0f;
const float penWidth   =  32.0f;
const float dashOffset = -559.0f + (float(tb1->Position) * 559.0f * 0.01f);

std::vector<float> dashPattern;
dashPattern.push_back(559.0f / penWidth);
dashPattern.push_back(559.0f / penWidth);

// --------------------------------- USING GDI+ --------------------------------------

// create a GDI+ path showing a circle
Gdiplus::GraphicsPath path;
path.StartFigure();
path.AddBezier(Gdiplus::PointF(99.99999, 11.05255 + startY),
               Gdiplus::PointF(51.31296, 11.05255 + startY),
               Gdiplus::PointF(11.05254, 51.31297 + startY),
               Gdiplus::PointF(11.05254, 100 + startY));
path.AddBezier(Gdiplus::PointF(11.05254, 100 + startY),
               Gdiplus::PointF(11.05254, 148.6871 + startY),
               Gdiplus::PointF(51.31297, 188.9475 + startY),
               Gdiplus::PointF(99.99999, 188.9475 + startY));
path.AddBezier(Gdiplus::PointF(99.99999, 188.9475 + startY),
               Gdiplus::PointF(148.687,  188.9475 + startY),
               Gdiplus::PointF(188.9474, 149.1552 + startY),
               Gdiplus::PointF(188.9474, 100 + startY));
path.AddBezier(Gdiplus::PointF(188.9474, 100 + startY),
               Gdiplus::PointF(188.9474, 50.84483 + startY),
               Gdiplus::PointF(149.1552, 11.05255 + startY),
               Gdiplus::PointF(99.99998, 11.05255 + startY));
path.CloseFigure();

// configure the GDI+ pen
Gdiplus::Pen pen(Gdiplus::Color(255, 0, 0, 0));
pen.SetWidth(penWidth);
pen.SetDashOffset(dashOffset / penWidth);

const Gdiplus::LineCap lineCapStart = Gdiplus::LineCapFlat;
const Gdiplus::LineCap lineCapEnd   = Gdiplus::LineCapFlat;
const Gdiplus::DashCap dashCap      = Gdiplus::DashCapFlat;

pen.SetLineCap(lineCapStart, lineCapEnd, dashCap);

const Gdiplus::LineJoin lineJoin = Gdiplus::LineJoinMiter;
pen.SetLineJoin(lineJoin);
pen.SetMiterLimit(4.0f);

// configure dash style to custom (meaning that dash pattern should be used)
pen.SetDashStyle(Gdiplus::DashStyleCustom);

// configure dash pattern
pen.SetDashPattern(&dashPattern[0], dashPattern.size());

// draw the path using GDI+
Gdiplus::Graphics graphics(Canvas->Handle);
graphics.DrawPath(&pen, &path);

// ------------------------------- USING DIRECT2D ------------------------------------

const float startX = 300.0f;

// get a Direct2D canvas
TRect canvasRect(0, 0, ClientWidth, ClientHeight);
TDirect2DCanvas* pCanvas = new TDirect2DCanvas(Canvas->Handle, canvasRect);

// begin draw
pCanvas->BeginDraw();

ID2D1Factory* pD2DFactory;

// get factory associated with canvas
pCanvas->RenderTarget->GetFactory(&pD2DFactory);

// create a Direct2D path showing a circle
ID2D1PathGeometry* pGeometry;
pD2DFactory->CreatePathGeometry(&pGeometry);

ID2D1GeometrySink* pSink;
pGeometry->Open(&pSink);
pSink->BeginFigure(D2D1::Point2F(99.99999 + startX, 11.05255 + startY), D2D1_FIGURE_BEGIN_FILLED);
pSink->AddBezier(D2D1::BezierSegment(D2D1::Point2F(51.31296 + startX, 11.05255 + startY),
                                     D2D1::Point2F(11.05254 + startX, 51.31297 + startY),
                                     D2D1::Point2F(11.05254 + startX, 100 + startY)));
pSink->AddBezier(D2D1::BezierSegment(D2D1::Point2F(11.05254 + startX, 148.6871 + startY),
                                     D2D1::Point2F(51.31297 + startX, 188.9475 + startY),
                                     D2D1::Point2F(99.99999 + startX, 188.9475 + startY)));
pSink->AddBezier(D2D1::BezierSegment(D2D1::Point2F(148.687 + startX,  188.9475 + startY),
                                     D2D1::Point2F(188.9474 + startX, 149.1552 + startY),
                                     D2D1::Point2F(188.9474 + startX, 100 + startY)));
pSink->AddBezier(D2D1::BezierSegment(D2D1::Point2F(188.9474 + startX, 50.84483 + startY),
                                     D2D1::Point2F(149.1552 + startX, 11.05255 + startY),
                                     D2D1::Point2F(99.99998 + startX, 11.05255 + startY)));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
pSink->Close();
pSink->Release();

// configure the Direct2D stroke properties
::D2D1_STROKE_STYLE_PROPERTIES strokeProps;
strokeProps.startCap   = D2D1_CAP_STYLE_FLAT;
strokeProps.endCap     = D2D1_CAP_STYLE_FLAT;
strokeProps.dashCap    = D2D1_CAP_STYLE_FLAT;
strokeProps.lineJoin   = D2D1_LINE_JOIN_MITER;
strokeProps.miterLimit = 4.0f;
strokeProps.dashStyle  = D2D1_DASH_STYLE_CUSTOM;
strokeProps.dashOffset = dashOffset / penWidth;

// get the stroke style to apply
ID2D1StrokeStyle* pStrokeStyle;
pD2DFactory->CreateStrokeStyle(strokeProps,
                               &dashPattern[0],
                               dashPattern.size(),
                               &pStrokeStyle);

::ID2D1SolidColorBrush* pSolidBrush;

::D2D1_COLOR_F color;
color.r = 0.0f;
color.g = 0.0f;
color.b = 0.0f;
color.a = 1.0f;

// create a solid color brush
pCanvas->RenderTarget->CreateSolidColorBrush(color, &pSolidBrush);

// draw the geometry
pCanvas->RenderTarget->DrawGeometry(pGeometry, pSolidBrush, penWidth, pStrokeStyle);

pCanvas->EndDraw();

delete pCanvas;


tb1->位置属性只是一个可在0到100之间移动的轨迹栏控制光标。

使用上面的代码,我注意到2个绘图之间存在一些差异:

The tb1->Position property is just a track bar control cursor that can be moved between 0 to 100.

Using the above code, I noticed several differences between the 2 drawing:



  1. 当tb1-> Position = 0时, GDI +圆圈是完全可见的,而Direct2D圆圈是不可见的(这是我想要达到的正确效果)。

  1. When tb1->Position = 0, the GDI+ circle is fully visible whereas the Direct2D circle isn't visible (that is the correct effect I wanted to reach).

当tb1 - >位置在1到99之间,GDI +圆圈结尾绘制不正确(它们的方向不同)。 

When tb1->Position is between 1 to 99, the GDI+ circle endings are drawn incorrectly (their orientations differ). 

当tb1- >位置= 100,在GDI +圈上可以看到图形工件 

When tb1->Position = 100, a graphical artifact is visible on the GDI+ circle 

不幸的是,使用其他库如Direct2D而不是GDI + isn对我来说是一个选择。我的问题是:为什么当我用GDI +绘制虚线圆圈时会发生上述差异?我做错了什么,或者它是一个GDI +错误?

Unfortunately, using another library like Direct2D instead of GDI+ isn't an option for me. My question is: Why the above mentioned differences happen when I draw my dashed circle with GDI+? Am I doing something wrong, or is it a GDI+ bug?

重要提示这不是一个抗锯齿问题。上述工件在有或没有抗锯齿的情况下出现。

IMPORTANT NOTE this is NOT an antialiasing issue. The above described artifacts appear with or without antialiasing.

推荐答案

您好Jeanmilost,

Hi Jeanmilost,

感谢在这里发布。

>>使用上面的代码,我注意到2幅图纸之间存在一些差异:



  1. 当tb1-> Position = 0时,GDI +圆圈完全可见,而Direct2D圆圈则不可见(这是我想达到的正确效果) )

当tb1->位置介于1到99之间时,GDI +圆圈结尾绘制不正确(他们的方向不同)。 

当tb1->位置= 100时,图形工件是在GDI +圈子上可见 

能否请您提供给我们演示项目,以便我们可以用我们的vs重现您的问题?您的项目类型是什么?

Could you please provide us a demo project so that we could reproduce your issue with our vs? What's the type of your project?

如果您想发布问题,请在以下论坛发帖。

If you want to post an issue, please post on this forum below.

https://developercommunity.visualstudio.com

您的理解与合作将不胜感激。

Your understanding and cooperation will be grateful.

最诚挚的问候,

Baron Bi


这篇关于GDI +破折号模式是否被窃听?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆