GDI +破折号模式是否被窃听?
我正在使用Embarcadero RAD Studio XE7创建一个C ++图形应用程序,其中我正尝试使用GDI +和一些破折号图案属性为循环进度设置动画。
这个想法非常简单:通过配置一个模式,其中短划线足够长以填充圆的周长,并且空白部分足够长以防止两个短划线在圆上一起可见,则可以显示循环进度,其中可以使用破折号偏移属性来显示当前进度位置。
但是,我无法使用GDI +实现我的目标,因为几个图形工件是可见的,我无法找到解决这些问题的解决方案。 我很确定我使用的值是正确的,因为Direct2D处理的图形完全相同。
以下是显示问题的示例代码。 一个圆圈用GDI +绘制,另一个用Direct2D绘制。 两个圆圈的绘图配置完全相同。
// 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-> Position属性只是一个可以在0到100之间移动的跟踪栏控件光标。
使用上面的代码,我注意到了2绘图之间的几个区别:
当tb1-> Position = 0时,GDI +圆圈完全可见,而Direct2D圆圈不可见(这是我想达到的正确效果)。
当tb1-> Position位于1到99之间时,GDI +圆圈末端绘制不正确。
当tb1-> Position = 100时,图形工件在GDI +圆上可见
不幸的是,使用其他库如Direct2D而不是GDI +不是我的选择。 我的问题是:为什么当我用GDI +绘制我的虚线圆时发生上述差异? 我做错了什么,或者它是一个GDI +错误?
重要编辑 :在上面的图像上,Direct2D图形上启用了抗锯齿,而在GDI +图形上禁用了抗锯齿。 这不是问题 。 上面提到的问题是关于像GDI +和Direct2D之间明显不同的段结尾方向的图形工件,或者圆圈满了时出现的空白工件。 这些问题发生在有或没有抗锯齿的情况下 。
链接地址: http://www.djcxy.com/p/66241.html