2008-08-19 191 views
2

GDI + DrawLines功能具有可以通过运行下面的C#代码被再现的限幅错误。运行代码时,出现两条线路径,它们应该是相同的,因为它们都在剪辑区域内。但是,当剪辑区域被设置时,线段中的一个未被绘制。净图裁剪错误

protected override void OnPaint(PaintEventArgs e) 
{ 
    PointF[] points = new PointF[] { new PointF(73.36f, 196), 
      new PointF(75.44f, 32), 
      new PointF(77.52f, 32), 
      new PointF(79.6f, 196), 
      new PointF(85.84f, 196) }; 

    Rectangle b = new Rectangle(70, 32, 20, 164);   
    e.Graphics.SetClip(b); 
    e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly 
    e.Graphics.TranslateTransform(80, 0); 
    e.Graphics.ResetClip(); 
    e.Graphics.DrawLines(Pens.Red, points); 
} 

在图形对象上设置反模式可以解决这个问题。但这不是一个真正的解决方案。

是否有人知道一种解决方法吗?

回答

0

什么似乎与代码回事?

OK,这个问题应该是...应该是什么的代码做它没有了。

当我运行的代码,我看到2红“尖峰”我不是彪?

你似乎加入德矩形的声明后,下面的验证裁剪矩形区域内绘制的第一个秒杀:

e.Graphics.FillRectangle(new SolidBrush(Color.Black), b);

然后你执行转换,重新剪辑所以在这个点我假设clientRectangle被用作适当的剪辑区域,然后尝试重新翻译翻译后的尖峰。错误在哪里?!?

0

该缺陷是,这两个线段应绘制相同,但它们不是因为所剪切区域内绘制的尖峰是完全剪切区域内,并且不应当以任何方式被限幅,但它是。这是一个非常烦人的事情,但是这会导致任何软件严重地使用绘图线或裁剪看起来不专业,因为可能出现在多边形中的间隙。

3

看来,这是一个已知的bug ......

下面的代码似乎功能与你的要求:

protected override void OnPaint(PaintEventArgs e) 
    { 
     PointF[] points = new PointF[] { new PointF(73.36f, 196), 
     new PointF(75.44f, 32), 
     new PointF(77.52f, 32), 
     new PointF(79.6f, 196), 
     new PointF(85.84f, 196) }; 

     e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
     Rectangle b = new Rectangle(70, 32, 20, 165); 
     e.Graphics.SetClip(b); 
     e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly 
     e.Graphics.TranslateTransform(80, 0); 
     e.Graphics.ResetClip();   
     e.Graphics.DrawLines(Pens.Red, points); 
    } 

注:我已经AntiAlias'ed线和扩展您的裁剪区域1

看来,以下变通可能帮助(虽然未测试):

  • 笔是多于一个像素厚
  • 该生产线是完全水平或垂直
  • 的修剪是针对窗口边界,而不是一个剪裁矩形

以下是文章的列表可能/或然后再可能无法帮助:

http://www.tech-archive.net/pdf/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0350.pdf http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.gdi/2004-08/0368.html

OR ...

以下也是可能的:

protected override void OnPaint (PaintEventArgs e) 
    { 
     PointF[] points = new PointF[] { new PointF(73.36f, 196), 
     new PointF(75.44f, 32), 
     new PointF(77.52f, 32), 
     new PointF(79.6f, 196), 
     new PointF(85.84f, 196) }; 

     Rectangle b = new Rectangle(70, 32, 20, 164); 
     Region reg = new Region(b); 
     e.Graphics.SetClip(reg, System.Drawing.Drawing2D.CombineMode.Union); 
     e.Graphics.DrawLines(Pens.Red, points); // clipped incorrectly 
     e.Graphics.TranslateTransform(80, 0); 
     e.Graphics.ResetClip(); 
     e.Graphics.DrawLines(Pens.Red, points); 
    } 

使用组合的/与画布/控制的ClientRectangle的区域联合在一起(我认为)这effecivly剪辑。由于区域与矩形不同,结果应该是预期的。此代码可以通过在调用setClip()之后添加

e.Graphics.FillRectangle(new SolidBrush(Color.Black), b); 

来工作。这清楚地显示了只出现在剪辑区域中的黑色矩形。

这可能是一个有效的解决方法,如果反锯齿行不是一个选项。

希望这会有所帮助