Copying Geometry objects in Silverlight

WPF supports the sharing of Geometry objects; Silverlight does not.

Usually this means that you need to make a copy of a Geometry object. Unfortunately, Silverlight doesn’t seem to provide a good way to do that. So here is some incomplete code that does that.

[code] public static class GeoHelper {
public static Geometry Copy(Geometry g) {
if (g == null) return null;

  RectangleGeometry rg = g as RectangleGeometry;
  if (rg != null) {
    return new RectangleGeometry() { Rect = rg.Bounds, RadiusX = rg.RadiusX, RadiusY = rg.RadiusY, Transform = rg.Transform };
  }
  EllipseGeometry eg = g as EllipseGeometry;
  if (eg != null) {
    return new EllipseGeometry() { Center = eg.Center, RadiusX = eg.RadiusX, RadiusY = eg.RadiusY, Transform = eg.Transform };
  }
  LineGeometry lg = g as LineGeometry;
  if (lg != null) {
    return new LineGeometry() { StartPoint = lg.StartPoint, EndPoint = lg.EndPoint, Transform = lg.Transform };
  }
  PathGeometry pg = g as PathGeometry;
  if (pg != null) {
    PathGeometry pg2 = new PathGeometry();
    pg2.FillRule = pg.FillRule;
    foreach (PathFigure pf in pg.Figures) {
      PathFigure pf2 = new PathFigure();
      pf2.StartPoint = pf.StartPoint;
      foreach (PathSegment ps in pf.Segments) {
        pf2.Segments.Add(Copy(ps));
      }
      pf2.IsClosed = pf.IsClosed;
      pf2.IsFilled = pf.IsFilled;
      pg2.Figures.Add(pf2);
    }
    pg2.Transform = pg.Transform;
    return pg2;
  }
  GeometryGroup gg = g as GeometryGroup;
  if (gg != null) {
    GeometryGroup gg2 = new GeometryGroup();
    gg2.FillRule = gg.FillRule;
    foreach (Geometry x in gg.Children) {
      gg2.Children.Add(Copy(x));
    }
    gg2.Transform = gg.Transform;
    return gg2;
  }
  throw new InvalidOperationException("Copying an unknown kind of Geometry: " + g.ToString());
}

private static PathSegment Copy(PathSegment s) {
  if (s == null) return null;

  LineSegment ls = s as LineSegment;
  if (ls != null) {
    return new LineSegment() { Point = ls.Point };
  }
  BezierSegment bs = s as BezierSegment;
  if (bs != null) {
    return new BezierSegment() { Point1 = bs.Point1, Point2 = bs.Point2, Point3 = bs.Point3 };
  }
  QuadraticBezierSegment qbs = s as QuadraticBezierSegment;
  if (qbs != null) {
    return new QuadraticBezierSegment() { Point1 = qbs.Point1, Point2 = qbs.Point2 };
  }
  ArcSegment arc = s as ArcSegment;
  if (arc != null) {
    return new ArcSegment() { Point = arc.Point, Size = arc.Size, SweepDirection = arc.SweepDirection, IsLargeArc = arc.IsLargeArc, RotationAngle = arc.RotationAngle };
  }
  PolyLineSegment pls = s as PolyLineSegment;
  if (pls != null) {
    return new PolyLineSegment() { Points = Copy(pls.Points) };
  }
  PolyBezierSegment pbs = s as PolyBezierSegment;
  if (pbs != null) {
    return new PolyBezierSegment() { Points = Copy(pbs.Points) };
  }
  PolyQuadraticBezierSegment pqbs = s as PolyQuadraticBezierSegment;
  if (pqbs != null) {
    return new PolyQuadraticBezierSegment() { Points = Copy(pqbs.Points) };
  }
  throw new InvalidOperationException("Copying an unknown kind of PathSegment: " + s.ToString());
}

private static PointCollection Copy(PointCollection coll) {
  PointCollection newcoll = new PointCollection();
  foreach (Point p in coll) newcoll.Add(p);
  return newcoll;
}

}[/code]