I have complex StreamGeometry
and I want to clip it. Unfortunately, it looks like StreamGeometry
doesn\'t supports combine.
Here is a
You can definitely combine StreamGeometry
objects. For this, you want to use a CombinedGeometry
object. Here's a simple extension method for drawing polygons with holes:
public static void DrawPolygon(this DrawingContext context, Brush brush, Pen pen, IEnumerable<Point> exteriorRing, IEnumerable<IEnumerable<Point>> interiorRings = null)
{
StreamGeometry geo = new StreamGeometry();
Geometry finalGeometry = geo;
using (StreamGeometryContext ctxExterior = geo.Open())
{
ctxExterior.BeginFigure(exteriorRing.First(), (brush != null), true);
ctxExterior.PolyLineTo(exteriorRing.Skip(1).ToArray(), (pen != null), false);
if (interiorRings != null)
{
foreach (var ring in interiorRings)
{
var interiorGeometry = new StreamGeometry();
using (var ctxInterior = interiorGeometry.Open())
{
ctxInterior.BeginFigure(ring.First(), true, true);
ctxInterior.PolyLineTo(ring.Skip(1).ToArray(), (pen != null), false);
}
finalGeometry = new CombinedGeometry(GeometryCombineMode.Exclude, finalGeometry, interiorGeometry);
}
}
}
context.DrawGeometry(brush, pen, finalGeometry);
}
Solution is simple: do not use StreamGeometry.
To example, this will work (using PathGeometry
instead):
var clip = new RectangleGeometry(new Rect(50, 50, 10, 10));
var geometry = new PathGeometry(new[] { new PathFigure(new Point(0, 0), new[] {
new LineSegment(new Point(0, 100), true),
new LineSegment(new Point(100, 100), true),
new LineSegment(new Point(100, 0), true),
}, true) });
path.Data = Geometry.Combine(clip, geometry, GeometryCombineMode.Intersect, null);
Result:
It looks like UIElement.Clip
still render invisible parts (mayhap only with StreamGeometry
) ! Never use it! Clip geometry before assigning it.