예제 #1
0
    //??? doesn't always check/limit values for Parameter1/Parameter2
    internal Geometry GetGeometry(Size size) {
      double w = size.Width;
      if (Double.IsNaN(w) || Double.IsPositiveInfinity(w) || w < 0.5) w = 100;

      double h = size.Height;
      if (Double.IsNaN(h) || Double.IsPositiveInfinity(h) || h < 0.5) h = 100;

      Geometry geo = null;
      switch (this.Figure) {  // most common cases first

        case NodeFigure.None: // none a rectangle too, to make sure we don't return null
        case NodeFigure.Square:
        //?? s.Reshapable = false;    // maintain aspect ratio
        case NodeFigure.Rectangle: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        case NodeFigure.Circle:
        //?? s.Reshapable = false;    // maintain aspect ratio
        case NodeFigure.Ellipse:
        case NodeFigure.Connector: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0.156, 0.156);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(0.844, 0.844);
            geo = new EllipseGeometry() { Center = new Point(.5 * w, .5 * h), RadiusX = .5 * w, RadiusY = .5 * h };
            break;
          }

        case NodeFigure.TriangleRight:
          if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
          if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5, .75);

          return new PathGeometry() {
            Figures = new PathFigureCollection() {
                new PathFigure() {
                  StartPoint = new Point(0, 0),
                    Segments = new PathSegmentCollection() {
                      new LineSegment() { Point = new Point(w, 0.5*h) },
                      new LineSegment() { Point = new Point(0, h) }
                    },
                  IsClosed = true
                }
              }
          };
        case NodeFigure.TriangleDown:
          if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, 0);
          if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .5);
          return new PathGeometry() {
            Figures = new PathFigureCollection() {
                new PathFigure() {
                  StartPoint = new Point(0, 0),
                    Segments = new PathSegmentCollection() {
                      new LineSegment() { Point = new Point(w, 0) },
                      new LineSegment() { Point = new Point(0.5*w, h) }
                    },
                  IsClosed = true
                }
              }
          };
        case NodeFigure.TriangleLeft:
          if (this.Spot1.IsDefault) this.Spot1 = new Spot(.5, .25);
          if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, .75);
          return new PathGeometry() {
            Figures = new PathFigureCollection() {
                new PathFigure() {
                  StartPoint = new Point(w, h),
                    Segments = new PathSegmentCollection() {
                      new LineSegment() { Point = new Point(0, 0.5*h) },
                      new LineSegment() { Point = new Point(w, 0) }
                    },
                  IsClosed = true
                }
              }
          };
        case NodeFigure.TriangleUp:
          if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, .50);
          if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, 1);
          return new PathGeometry() {
            Figures = new PathFigureCollection() {
                new PathFigure() {
                  StartPoint = new Point(w, h),
                    Segments = new PathSegmentCollection() {
                      new LineSegment() { Point = new Point(0, h) },
                      new LineSegment() { Point = new Point(0.5*w, 0) }
                    },
                  IsClosed = true
                }
              }
          };

        // Lines
        case NodeFigure.Line1:
          geo = new LineGeometry() { StartPoint = new Point(0, 0), EndPoint = new Point(w, h) };
          break;
        case NodeFigure.Line2:
          geo = new LineGeometry() { StartPoint = new Point(w, 0), EndPoint = new Point(0, h) };
          break;

        // Curves
        case NodeFigure.Curve1: {
            double factor = Geo.MagicBezierFactor;
            GeoStream sg1 = new GeoStream();
            using (StreamGeometryContext context = sg1.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.BezierTo(new Point(factor * w, 0), new Point(1 * w, (1 - factor) * h), new Point(w, h), true, true);
            }
            geo = sg1.Geometry;
            break;
          }
        case NodeFigure.Curve2: {
            double factor = Geo.MagicBezierFactor;
            GeoStream sg2 = new GeoStream();
            using (StreamGeometryContext context = sg2.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.BezierTo(new Point(0, factor * h), new Point((1 - factor) * w, h), new Point(w, h), true, true);
            }
            geo = sg2.Geometry;
            break;
          }
        case NodeFigure.Curve3: {
            double factor = Geo.MagicBezierFactor;
            GeoStream sg3 = new GeoStream();
            using (StreamGeometryContext context = sg3.Open()) {
              context.BeginFigure(new Point(1 * w, 0), false, false);
              context.BezierTo(new Point(1 * w, factor * h), new Point(factor * w, 1 * h), new Point(0, 1 * h), true, true);
            }
            geo = sg3.Geometry;
            break;
          }
        case NodeFigure.Curve4: {
            double factor = Geo.MagicBezierFactor;
            GeoStream sg4 = new GeoStream();
            using (StreamGeometryContext context = sg4.Open()) {
              context.BeginFigure(new Point(1 * w, 0), false, false);
              context.BezierTo(new Point((1 - factor) * w, 0), new Point(0, (1 - factor) * h), new Point(0, 1 * h), true, true);
            }
            geo = sg4.Geometry;
            break;
          }

        // Polygons
        case NodeFigure.Triangle:
        case NodeFigure.Alternative:
        case NodeFigure.Merge:
          if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, .5);
          if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, 1);

          GeoStream sg5 = new GeoStream();
          using (StreamGeometryContext context = sg5.Open()) {
            context.BeginFigure(new Point(.5 * w, 0 * h), true, true);
            context.LineTo(new Point(0 * w, 1 * h), true, false);
            context.LineTo(new Point(1 * w, 1 * h), true, false);
          }
          geo = sg5.Geometry;
          break;
        case NodeFigure.Diamond:
        case NodeFigure.Decision:
          if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, .25);
          if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .75);

          GeoStream sg6 = new GeoStream();
          using (StreamGeometryContext context = sg6.Open()) {
            context.BeginFigure(new Point(.5 * w, 0), true, true);
            context.LineTo(new Point(0, .5 * h), true, false);
            context.LineTo(new Point(.5 * w, 1 * h), true, false);
            context.LineTo(new Point(1 * w, .5 * h), true, false);
          }
          geo = sg6.Geometry;
          break;
        case NodeFigure.Pentagon: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, .22);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8, .9);

            Point[] points = CreatePolygon(5);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 5; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Hexagon:
        case NodeFigure.DataTransmission: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.07, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.93, .75);

            Point[] points = CreatePolygon(6);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 6; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Heptagon: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, .15);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8, .85);

            Point[] points = CreatePolygon(7);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 7; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Octagon: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.15, .15);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.85, .85);

            Point[] points = CreatePolygon(8);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 8; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Nonagon: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.17, .13);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.82, .82);

            Point[] points = CreatePolygon(9);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 9; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Decagon: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.16, .16);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.84, .84);

            Point[] points = CreatePolygon(10);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 10; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Dodecagon: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.16, .16);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.84, .84);

            Point[] points = CreatePolygon(12);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 12; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        // Stars
        case NodeFigure.FivePointedStar: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.312, .383);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.693, .765);

            Point[] points = CreateStar(5);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(points[0].X * w, points[0].Y * h), true, true);
              for (int i = 1; i < 10; i++)
                context.LineTo(new Point(points[i].X * w, points[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.SixPointedStar: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.170, .251);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.833, .755);

            Point[] starPoints = CreateStar(6);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(starPoints[0].X * w, starPoints[0].Y * h), true, true);
              for (int i = 1; i < 12; i++)
                context.LineTo(new Point(starPoints[i].X * w, starPoints[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.SevenPointedStar: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.363, .361);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.641, .709);

            Point[] starPoints = CreateStar(7);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(starPoints[0].X * w, starPoints[0].Y * h), true, true);
              for (int i = 1; i < 14; i++)
                context.LineTo(new Point(starPoints[i].X * w, starPoints[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.EightPointedStar: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.252, .255);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .75);

            Point[] starPoints = CreateStar(8);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(starPoints[0].X * w, starPoints[0].Y * h), true, true);
              for (int i = 1; i < 16; i++)
                context.LineTo(new Point(starPoints[i].X * w, starPoints[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.NinePointedStar: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.355, .361);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.645, .651);

            Point[] starPoints = CreateStar(9);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(starPoints[0].X * w, starPoints[0].Y * h), true, true);
              for (int i = 1; i < 18; i++)
                context.LineTo(new Point(starPoints[i].X * w, starPoints[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.TenPointedStar: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.281, .261);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.723, .748);

            Point[] starPoints = CreateStar(10);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(starPoints[0].X * w, starPoints[0].Y * h), true, true);
              for (int i = 1; i < 20; i++)
                context.LineTo(new Point(starPoints[i].X * w, starPoints[i].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        // Bursts
        case NodeFigure.FivePointedBurst: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.312, .383);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.693, .765);

            Point[] burstPoints = CreateBurst(5);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(burstPoints[0].X * w, burstPoints[0].Y * h), true, true);
              for (int i = 1; i < burstPoints.Length; i += 3)
                context.BezierTo(new Point(burstPoints[i].X * w, burstPoints[i].Y * h), new Point(burstPoints[i + 1].X * w, burstPoints[i + 1].Y * h), new Point(burstPoints[i + 2].X * w, burstPoints[i + 2].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.SixPointedBurst: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.170, .251);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.833, .755);

            Point[] burstPoints = CreateBurst(6);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(burstPoints[0].X * w, burstPoints[0].Y * h), true, true);
              for (int i = 1; i < burstPoints.Length; i += 3)
                context.BezierTo(new Point(burstPoints[i].X * w, burstPoints[i].Y * h), new Point(burstPoints[i + 1].X * w, burstPoints[i + 1].Y * h), new Point(burstPoints[i + 2].X * w, burstPoints[i + 2].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.SevenPointedBurst: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.363, .361);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.641, .709);

            Point[] burstPoints = CreateBurst(7);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(burstPoints[0].X * w, burstPoints[0].Y * h), true, true);
              for (int i = 1; i < burstPoints.Length; i += 3)
                context.BezierTo(new Point(burstPoints[i].X * w, burstPoints[i].Y * h), new Point(burstPoints[i + 1].X * w, burstPoints[i + 1].Y * h), new Point(burstPoints[i + 2].X * w, burstPoints[i + 2].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.EightPointedBurst: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.252, .255);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .75);

            Point[] burstPoints = CreateBurst(8);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(burstPoints[0].X * w, burstPoints[0].Y * h), true, true);
              for (int i = 1; i < burstPoints.Length; i += 3)
                context.BezierTo(new Point(burstPoints[i].X * w, burstPoints[i].Y * h), new Point(burstPoints[i + 1].X * w, burstPoints[i + 1].Y * h), new Point(burstPoints[i + 2].X * w, burstPoints[i + 2].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.NinePointedBurst: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.355, .361);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.645, .651);

            Point[] burstPoints = CreateBurst(9);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(burstPoints[0].X * w, burstPoints[0].Y * h), true, true);
              for (int i = 1; i < burstPoints.Length; i += 3)
                context.BezierTo(new Point(burstPoints[i].X * w, burstPoints[i].Y * h), new Point(burstPoints[i + 1].X * w, burstPoints[i + 1].Y * h), new Point(burstPoints[i + 2].X * w, burstPoints[i + 2].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.TenPointedBurst: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.281, .261);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.723, .748);

            Point[] burstPoints = CreateBurst(10);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(burstPoints[0].X * w, burstPoints[0].Y * h), true, true);
              for (int i = 1; i < burstPoints.Length; i += 3)
                context.BezierTo(new Point(burstPoints[i].X * w, burstPoints[i].Y * h), new Point(burstPoints[i + 1].X * w, burstPoints[i + 1].Y * h), new Point(burstPoints[i + 2].X * w, burstPoints[i + 2].Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        // Basic Shapes
        case NodeFigure.Cloud:
          if (this.Spot1.IsDefault) this.Spot1 = new Spot(.1, .1);
          if (this.Spot2.IsDefault) this.Spot2 = new Spot(.9, .9);

          GeoStream sg26 = new GeoStream();
          using (StreamGeometryContext context = sg26.Open()) {
            context.BeginFigure(new Point(.08034461 * w, .1944299 * h), true, true);
            context.BezierTo(new Point(-.09239631 * w, .07836421 * h), new Point(.1406031 * w, -.0542823 * h), new Point(.2008615 * w, .05349299 * h), true, false);
            context.BezierTo(new Point(.2450511 * w, -.01697547 * h), new Point(.3776197 * w, -.02112067 * h), new Point(.4338609 * w, .074219 * h), true, false);
            context.BezierTo(new Point(.4539471 * w, 0), new Point(.6066018 * w, -.02526587 * h), new Point(.6558228 * w, .07004196 * h), true, false);
            context.BezierTo(new Point(.6914277 * w, -.02904177 * h), new Point(.8921095 * w, -.02220843 * h), new Point(.8921095 * w, .08370865 * h), true, false);
            context.BezierTo(new Point(1.036446 * w, .04105738 * h), new Point(1.020377 * w, .3022052 * h), new Point(.9147671 * w, .3194596 * h), true, false);
            context.BezierTo(new Point(1.04448 * w, .360238 * h), new Point(.992256 * w, .5219009 * h), new Point(.9082935 * w, .562044 * h), true, false);
            context.BezierTo(new Point(1.042337 * w, .5771781 * h), new Point(1.028411 * w, .8120651 * h), new Point(.9212406 * w, .8217117 * h), true, false);
            context.BezierTo(new Point(1.028411 * w, .9571472 * h), new Point(.8556702 * w, 1.052487 * h), new Point(.7592566 * w, .9156953 * h), true, false);
            context.BezierTo(new Point(.7431877 * w, 1.019325 * h), new Point(.5624123 * w, 1.031761 * h), new Point(.5101666 * w, .9310455 * h), true, false);
            context.BezierTo(new Point(.4820677 * w, 1.031761 * h), new Point(.3030112 * w, 1.002796 * h), new Point(.2609328 * w, .9344623 * h), true, false);
            context.BezierTo(new Point(.2329994 * w, 1.01518 * h), new Point(.03213784 * w, 1.01518 * h), new Point(.08034461 * w, .870098 * h), true, false);
            context.BezierTo(new Point(-.02812061 * w, .9032597 * h), new Point(-.01205169 * w, .6835638 * h), new Point(.06829292 * w, .6545475 * h), true, false);
            context.BezierTo(new Point(-.02812061 * w, .6089503 * h), new Point(-.01606892 * w, .4555777 * h), new Point(.06427569 * w, .4265613 * h), true, false);
            context.BezierTo(new Point(-.01606892 * w, .3892545 * h), new Point(-.01205169 * w, .1944299 * h), new Point(.08034461 * w, .1944299 * h), true, false);
          }
          geo = sg26.Geometry;
          break;
        case NodeFigure.Crescent:
        case NodeFigure.Gate: {              // Flowchart
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.511, .19);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.776, .76);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.BezierTo(new Point(1 * w, 0), new Point(1 * w, 1 * h), new Point(0, 1 * h), true, false);
              context.BezierTo(new Point(.5 * w, .75 * h), new Point(.5 * w, .25 * h), new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.FramedRectangle: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              double param1 = this.FigureParameter1;
              double param2 = this.FigureParameter2;
              // Set defaults for parameters if they aren't set already
              if (param1 == 0) param1 = .1; // Distance between left and inner rect
              if (param2 == 0) param2 = .1; // Distance between top and inner rect
              // Set valid text area
              if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, param2);
              if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param1, 1 - param2);

              // Outside rectangle
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);

              // Inside Rectangle
              context.BeginFigure(new Point(param1 * w, param2 * h), false, true);
              context.LineTo(new Point((1 - param1) * w, param2 * h), true, false);
              context.LineTo(new Point((1 - param1) * w, (1 - param2) * h), true, false);
              context.LineTo(new Point(param1 * w, (1 - param2) * h), true, false);
              context.LineTo(new Point(param1 * w, param2 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.HalfEllipse:
        case NodeFigure.Delay: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .20);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .80);

            double factor = Geo.MagicBezierFactor;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.BezierTo(new Point(factor * w, 0), new Point(1 * w, (.5 - factor / 2) * h), new Point(1 * w, .5 * h), true, false);
              context.BezierTo(new Point(1 * w, (.5 + factor / 2) * h), new Point(factor * w, 1 * h), new Point(0, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Heart: {
            // Set default params
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .25; // y value of the middle
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.15, .29);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.86, .68);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.5 * w, 1 * h), true, true);
              context.BezierTo(new Point(.1 * w,.8 * h), new Point(0, .5 * h), new Point(0 * w, .3 * h), true, false);
              context.BezierTo(new Point(0 * w, 0), new Point(.45 * w, 0), new Point(.5 * w, .3 * h), true, false);
              context.BezierTo(new Point(.55 * w, 0), new Point(1 * w, 0), new Point(1 * w, .3 * h), true, false);
              context.BezierTo(new Point(w, .5 * h), new Point(.9 * w, .8 * h), new Point(.5 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Spade: {
            // Set default params
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .7; // y value of the center

            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.19, .26);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.80, .68);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              // Begin at the top middle
              context.BeginFigure(new Point(.5 * w, 0), true, true);
              context.LineTo(new Point(.51 * w, .01 * h), true, false);
              context.BezierTo(new Point(.6 * w, .2 * h), new Point(w, .25 * h), new Point(w, .5 * h), true, false);
              context.BezierTo(new Point(w, .8 * h), new Point(.6 * w, .8 * h), new Point(.55 * w, .7 * h), true, false);

              // start the base
              context.BezierTo(new Point(.5 * w, .75 * h), new Point(.55 * w, .95 * h), new Point(.75 * w, h), true, false);
              context.LineTo(new Point(.25 * w, h), true, false);
              context.BezierTo(new Point(.45 * w, .95 * h), new Point(.5 * w, .75 * h), new Point(.45 * w, .7 * h), true, false);

              // Finish the other side of the top
              context.BezierTo(new Point(.4 * w, .8 * h), new Point(0, .8 * h), new Point(0, .5 * h), true, false);
              context.BezierTo(new Point(0, .25 * h), new Point(.4 * w, .2 * h), new Point(.49 * w, .01 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Club: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.06, .39);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.93, .58);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              // start the base
              context.BeginFigure(new Point(.4 * w, .6 * h), true, true);
              context.BezierTo(new Point(.5 * w, .75 * h), new Point(.45 * w, .95 * h), new Point(.15 * w, 1 * h), true, false);              
              context.LineTo(new Point(.85 * w, h), true, false);
              context.BezierTo(new Point(.55 * w, .95 * h), new Point(.5 * w, .75 * h), new Point(.6 * w, .6 * h), true, false);
              // First circle:
              float r = .2f; // radius
              float cx = .3f; // offset from Center x
              float cy = 0; // offset from Center y
              float d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
              context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.5 + cx) * w, (.5 + r + cy) * h), true, false);
              context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((1 - .5 + r + cx) * w, (.5 - d + cy) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
              context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx + .05) * w, (.5 - d + cy - .02) * h), new Point((.65) * w, (0.36771243) * h), true, false);
              r = .2f; // radius
              cx = 0; // offset from Center x
              cy = -.3f; // offset from Center y
              d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
              context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((1 - .5 + r + cx) * w, (.5 - d + cy) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
              context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.35) * w, (0.36771243) * h), true, false);
              r = .2f; // radius
              cx = -.3f; // offset from Center x
              cy = 0; // offset from Center y
              d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
              context.BezierTo(new Point((1 - .5 + r + cx - .05) * w, (.5 - d + cy - .02) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
              context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.5 + cx) * w, (.5 + r + cy) * h), true, false);
              context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point(.4 * w, .6 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.YinYang: {
            double factor = Geo.MagicBezierFactor;
            double cpOffset = factor * .5;
            double radius = .5;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              // Right side
              context.BeginFigure(new Point(radius * w, 0), true, true);
              context.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
              context.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
              context.BezierTo(new Point(1 * w, radius * h), new Point(0, radius * h), new Point(radius * w, 0), true, false);

              // left side
              context.BeginFigure(new Point(radius * w, 1 * h), false, false);
              context.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              context.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);

              Point center = new Point(.5, .75);
              radius = .1;
              cpOffset = factor * .1;
              // bottom circle
              context.BeginFigure(new Point(center.X * w, (center.Y - radius) * h), true, true);
              context.BezierTo(new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false); //UL TL
              context.BezierTo(new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false); //BL TB
              context.BezierTo(new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false); //BR TR
              context.BezierTo(new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false); //UR TT

              center = new Point(.5, .25);

              // top circle
              context.BeginFigure(new Point(center.X * w, (center.Y - radius) * h), true, true);
              context.BezierTo(new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false); //UL TL
              context.BezierTo(new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false); //BL TB
              context.BezierTo(new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false); //BR TR
              context.BezierTo(new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false); //UR TT
              context.LineTo(new Point(center.X * w, (center.Y - radius) * h), false, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Peace: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.146, .146);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.853, .853);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              float d1 = .5f * (float)(4 * (Math.Sqrt(2) - 1) / 3);

              // First circle:
              context.BeginFigure(new Point(w, .5 * h), true, true);
              context.BezierTo(new Point(w, (.5 - d1) * h), new Point((.5 + d1) * w, 0), new Point(.5 * w, 0), true, false);
              context.BezierTo(new Point((.5 - d1) * w, 0), new Point(0, (.5 - d1) * h), new Point(0, .5 * h), true, false);
              context.BezierTo(new Point(0, (.5 + d1) * h), new Point((.5 - d1) * w, h), new Point(.5 * w, h), true, false);
              context.BezierTo(new Point((.5 + d1) * w, h), new Point(w, (.5 + d1) * h), new Point(w, .5 * h), true, false);
              // Second Circle
              float d2 = .4f * (float)(4 * (Math.Sqrt(2) - 1) / 3);
              context.BeginFigure(new Point(.9 * w, .5 * h), true, true);
              context.BezierTo(new Point(.9 * w, (.5 - d2) * h), new Point((.5 + d2) * w, .1 * h), new Point(.5 * w, .1 * h), true, false);
              context.BezierTo(new Point((.5 - d2) * w, .1 * h), new Point(.1 * w, (.5 - d2) * h), new Point(.1 * w, .5 * h), true, false);
              context.BezierTo(new Point(.1 * w, (.5 + d2) * h), new Point((.5 - d2) * w, .9 * h), new Point(.5 * w, .9 * h), true, false);
              context.BezierTo(new Point((.5 + d2) * w, .9 * h), new Point(.9 * w, (.5 + d2) * h), new Point(.9 * w, .5 * h), true, false);
              // Inner Circles
              { // #1
                float r = .07f; // radius
                float cx = 0; // offset from Center x
                float cy = -.707f * .11f; // offset from Center y
                float d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
                context.BeginFigure(new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, true);
                context.BezierTo(new Point((1 - .5 + r + cx) * w, (.5 - d + cy) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
                context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
                context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.5 + cx) * w, (.5 + r + cy) * h), true, false);
                context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
              }
              { // #2
                float r = .07f; // radius
                float cx = -0.707f * .11f; // offset from Center x
                float cy = 0.707f * .11f; // offset from Center y
                float d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
                context.BeginFigure(new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, true);
                context.BezierTo(new Point((1 - .5 + r + cx) * w, (.5 - d + cy) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
                context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
                context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.5 + cx) * w, (.5 + r + cy) * h), true, false);
                context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
              }
              { // #3
                float r = .07f; // radius
                float cx = 0.707f * .11f; // offset from Center x
                float cy = 0.707f * .11f; // offset from Center y
                float d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
                context.BeginFigure(new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, true);
                context.BezierTo(new Point((1 - .5 + r + cx) * w, (.5 - d + cy) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
                context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
                context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.5 + cx) * w, (.5 + r + cy) * h), true, false);
                context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
              }
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.NotAllowed: {
            double factor = Geo.MagicBezierFactor;
            double cpOffset = factor * .5;
            double radius = .5;
            Point center = new Point(.5, .5);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Outer circle
              s.BeginFigure(new Point(center.X * w, (center.Y - radius) * h), true, true);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false); //UL TL
              s.BezierTo(new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false); //BL TB
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false); //BR TR
              s.BezierTo(new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false); //UR TT

              // Inner circle, composed of two parts, separated by
              // a beam across going from top-right to bottom-left.
              radius = .40;
              cpOffset = factor * .40;
              // First we cut up the top right 90 degree curve into two smaller curves.
              // Since its clockwise, StartOfArrow is the first of the two points on the circle. EndOfArrow is the other one.
              Point startOfArrowc1;
              Point startOfArrowc2;
              Point startOfArrow;
              Point unused;
              BreakUpBezier(new Point(center.X, center.Y - radius), new Point(center.X + cpOffset, center.Y - radius),
                new Point(center.X + radius, center.Y - cpOffset), new Point(center.X + radius, center.Y), .42, out startOfArrowc1,
                out startOfArrowc2, out startOfArrow, out unused, out unused);

              Point endOfArrowc1;
              Point endOfArrowc2;
              Point endOfArrow;
              BreakUpBezier(new Point(center.X, center.Y - radius), new Point(center.X + cpOffset, center.Y - radius),
                new Point(center.X + radius, center.Y - cpOffset), new Point(center.X + radius, center.Y), .58, out unused,
                out unused, out endOfArrow, out endOfArrowc1, out endOfArrowc2);

              // Cut up the bottom left 90 degree curve into two smaller curves.
              Point startOfArrow2c1;
              Point startOfArrow2c2;
              Point startOfArrow2;
              BreakUpBezier(new Point(center.X, center.Y + radius), new Point(center.X - cpOffset, center.Y + radius),
                new Point(center.X - radius, center.Y + cpOffset), new Point(center.X - radius, center.Y), .42, out startOfArrow2c1,
                out startOfArrow2c2, out startOfArrow2, out unused, out unused);
              Point endOfArrow2c1;
              Point endOfArrow2c2;
              Point endOfArrow2;
              BreakUpBezier(new Point(center.X, center.Y + radius), new Point(center.X - cpOffset, center.Y + radius),
                new Point(center.X - radius, center.Y + cpOffset), new Point(center.X - radius, center.Y), .58, out unused,
                out unused, out endOfArrow2, out endOfArrow2c1, out endOfArrow2c2);

              // Take all the parts made and make the two separate inner circle parts.
              s.BeginFigure(new Point(endOfArrow2.X * w, endOfArrow2.Y * h), true, true);
              s.BezierTo(new Point(endOfArrow2c1.X * w, endOfArrow2c1.Y * h), new Point(endOfArrow2c2.X * w, endOfArrow2c2.Y * h), new Point((center.X - radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              s.BezierTo(new Point(startOfArrowc1.X * w, startOfArrowc1.Y * h), new Point(startOfArrowc2.X * w, startOfArrowc2.Y * h), new Point(startOfArrow.X * w, startOfArrow.Y * h), true, false);
              s.LineTo(new Point(endOfArrow2.X * w, endOfArrow2.Y * h), true, false);

              s.BeginFigure(new Point(startOfArrow2.X * w, startOfArrow2.Y * h), true, true);
              s.LineTo(new Point(endOfArrow.X * w, endOfArrow.Y * h), true, false);
              s.BezierTo(new Point(endOfArrowc1.X * w, endOfArrowc1.Y * h), new Point(endOfArrowc2.X * w, endOfArrowc2.Y * h), new Point((center.X + radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point(startOfArrow2c1.X * w, startOfArrow2c1.Y * h), new Point(startOfArrow2c2.X * w, startOfArrow2c2.Y * h), new Point(startOfArrow2.X * w, startOfArrow2.Y * h), true, false);

              sg.FillRule = FillRule.EvenOdd;
            }

            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Fragile: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .4);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              //Top and crack
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(.25 * w, 0), true, false);
              context.LineTo(new Point(.2 * w, .15 * h), true, false);
              context.LineTo(new Point(.3 * w, .25 * h), true, false);
              context.LineTo(new Point(.29 * w, .33 * h), true, false);
              context.LineTo(new Point(.35 * w, .25 * h), true, false);
              context.LineTo(new Point(.3 * w, .15 * h), true, false);
              context.LineTo(new Point(.4 * w, 0), true, false);
              context.LineTo(new Point(1 * w, 0), true, false);

              // Left side
              context.BezierTo(new Point(1 * w, .25 * h), new Point(.75 * w, .5 * h), new Point(.55 * w, .5 * h), true, false);
              context.LineTo(new Point(.55 * w, .9 * h), true, false);

              // The base
              context.LineTo(new Point(.7 * w, .9 * h), true, false);
              context.LineTo(new Point(.7 * w, 1 * h), true, false);
              context.LineTo(new Point(.3 * w, 1 * h), true, false);
              context.LineTo(new Point(.3 * w, .9 * h), true, false);

              // Right side
              context.LineTo(new Point(.45 * w, .9 * h), true, false);
              context.LineTo(new Point(.45 * w, .5 * h), true, false);
              context.BezierTo(new Point(.25 * w, .5 * h), new Point(0, .25 * h), new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        case NodeFigure.HourGlass: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.65 * w, .5 * h), true, true);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(.35 * w, .5 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(.65 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Lightning: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0 * w, .55 * h), true, true);
              context.LineTo(new Point(.38 * w, 0), true, false);
              context.LineTo(new Point(.75 * w, 0), true, false);
              context.LineTo(new Point(.25 * w, .45 * h), true, false);
              context.LineTo(new Point(.9 * w, .48 * h), true, false);
              context.LineTo(new Point(.4 * w, 1 * h), true, false);
              context.LineTo(new Point(.65 * w, .55 * h), true, false);
              context.LineTo(new Point(0, .55 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Parallelogram1: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .1; // Topleft corner's x distance from leftmost point
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param1, 1);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(param1 * w, 0), true, true);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point((1 - param1) * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Input:            // Flowchart
        case NodeFigure.Output: {
            GeoStream sg = new GeoStream();
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.9, 1);
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 1 * h), true, true);
              context.LineTo(new Point(.1 * w, 0), true, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(.9 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Parallelogram2: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .25; // Topleft corner's x distance from leftmost point
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param1, 1);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(param1 * w, 0), true, true);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point((1 - param1) * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ThickCross: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .25; // Thickness of the cross
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.5 - param1 / 2, .5 - param1 / 2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5 + param1 / 2, .5 + param1 / 2);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point((.5 - param1 / 2) * w, 0), true, true);
              context.LineTo(new Point((.5 + param1 / 2) * w, 0), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, (.5 - param1 / 2) * h), true, false);
              context.LineTo(new Point(1 * w, (.5 - param1 / 2) * h), true, false);
              context.LineTo(new Point(1 * w, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, 1 * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, 1 * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point(0, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point(0, (.5 - param1 / 2) * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, (.5 - param1 / 2) * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ThickX: {
            double spotPlace = .25 / Math.Sqrt(2);
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.5 - spotPlace, .5 - spotPlace);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5 + spotPlace, .5 + spotPlace);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.3 * w, 0), true, true);
              s.LineTo(new Point(.5 * w, .2 * h), true, false);
              s.LineTo(new Point(.7 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .3 * h), true, false);
              s.LineTo(new Point(.8 * w, .5 * h), true, false);
              s.LineTo(new Point(1 * w, .7 * h), true, false);
              s.LineTo(new Point(.7 * w, 1 * h), true, false);
              s.LineTo(new Point(.5 * w, .8 * h), true, false);
              s.LineTo(new Point(.3 * w, 1 * h), true, false);
              s.LineTo(new Point(0, .7 * h), true, false);
              s.LineTo(new Point(.2 * w, .5 * h), true, false);
              s.LineTo(new Point(0, .3 * h), true, false);
              s.LineTo(new Point(.3 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ThinCross: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .1; // Thickness of the cross
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point((.5 - param1 / 2) * w, 0), true, true);
              context.LineTo(new Point((.5 + param1 / 2) * w, 0), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, (.5 - param1 / 2) * h), true, false);
              context.LineTo(new Point(1 * w, (.5 - param1 / 2) * h), true, false);
              context.LineTo(new Point(1 * w, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, 1 * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, 1 * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point(0, (.5 + param1 / 2) * h), true, false);
              context.LineTo(new Point(0, (.5 - param1 / 2) * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, (.5 - param1 / 2) * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ThinX: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.1 * w, 0), true, true);
              s.LineTo(new Point(.5 * w, .4 * h), true, false);
              s.LineTo(new Point(.9 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .1 * h), true, false);
              s.LineTo(new Point(.6 * w, .5 * h), true, false);
              s.LineTo(new Point(1 * w, .9 * h), true, false);
              s.LineTo(new Point(.9 * w, 1 * h), true, false);
              s.LineTo(new Point(.5 * w, .6 * h), true, false);
              s.LineTo(new Point(.1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, .9 * h), true, false);
              s.LineTo(new Point(.4 * w, .5 * h), true, false);
              s.LineTo(new Point(0, .1 * h), true, false);
              s.LineTo(new Point(.1 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.RightTriangle: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .5);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.RoundedIBeam: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.BezierTo(new Point(.5 * w, .25 * h), new Point(.5 * w, .75 * h), new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.BezierTo(new Point(.5 * w, .75 * h), new Point(.5 * w, .25 * h), new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.RoundedRectangle: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.1, .1);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.9, .9);

            double factor = Geo.MagicBezierFactor;
            double cpOffset = factor * .3;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.3 * w, 0), true, true);
              context.LineTo(new Point(.7 * w, 0), true, false);
              context.BezierTo(new Point((.7 + cpOffset) * w, 0), new Point(1 * w, (.3 - cpOffset) * h), new Point(1 * w, .3 * h), true, false);
              context.LineTo(new Point(1 * w, .7 * h), true, false);
              context.BezierTo(new Point(1 * w, (.7 + cpOffset) * h), new Point((.7 + cpOffset) * w, 1 * h), new Point(.7 * w, 1 * h), true, false);
              context.LineTo(new Point(.3 * w, 1 * h), true, false);
              context.BezierTo(new Point((.3 - cpOffset) * w, 1 * h), new Point(0, (.7 + cpOffset) * h), new Point(0, .7 * h), true, false);
              context.LineTo(new Point(0, .3 * h), true, false);
              context.BezierTo(new Point(0, (.3 - cpOffset) * h), new Point((.3 - cpOffset) * w, 0), new Point(.3 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.SquareIBeam: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .2; // Width of the ibeam in % of the total width
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(1 * w, param1 * h), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, param1 * h), true, false);
              context.LineTo(new Point((.5 + param1 / 2) * w, (1 - param1) * h), true, false);
              context.LineTo(new Point(1 * w, (1 - param1) * h), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(0, (1 - param1) * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, (1 - param1) * h), true, false);
              context.LineTo(new Point((.5 - param1 / 2) * w, param1 * h), true, false);
              context.LineTo(new Point(0, param1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Trapezoid: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .2; // Distance from topleft of bounding rectangle, in % of the total width, of the topleft corner
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(param1 * w, 0), true, true);
              context.LineTo(new Point((1 - param1) * w, 0), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(param1 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ManualLoop:
        case NodeFigure.ManualOperation: {
            double param1 = this.FigureParameter1;
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.9, 1);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(param1, 0), true, true);
              context.LineTo(new Point(0, 0), true, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(.9 * w, 1 * h), true, false);
              context.LineTo(new Point(.1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.GenderMale: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.202, .257);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.692, .839);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .4;
              double radius = .4;
              Point center = new Point(.5, .5);
              Point unused;
              Point mid;
              Point c1;
              Point c2;

              // Outer circle
              s.BeginFigure(new Point((center.X - radius) * w, center.Y * h), true, true);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              BreakUpBezier(new Point(center.X, center.Y - radius), new Point(center.X + cpOffset, center.Y - radius),
                 new Point(center.X + radius, center.Y - cpOffset), new Point(center.X + radius, center.Y), .44, out c1,
                 out c2, out mid, out unused, out unused);
              s.BezierTo(new Point(c1.X * w, c1.Y * h), new Point(c2.X * w, c2.Y * h), new Point(mid.X * w, mid.Y * h), true, false);
              Point startOfArrow = new Point(mid.X, mid.Y);
              BreakUpBezier(new Point(center.X, center.Y - radius), new Point(center.X + cpOffset, center.Y - radius),
                new Point(center.X + radius, center.Y - cpOffset), new Point(center.X + radius, center.Y), .56, out unused,
                out unused, out mid, out c1, out c2);
              Point endOfArrow = new Point(mid.X, mid.Y);

              s.LineTo(new Point((startOfArrow.X * .1 + .95 * .9) * w, (startOfArrow.Y * .1) * h), true, false);
              s.LineTo(new Point(.85 * w, (startOfArrow.Y * .1) * h), true, false);
              s.LineTo(new Point(.85 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .15 * h), true, false);
              s.LineTo(new Point((endOfArrow.X * .1 + .9) * w, .15 * h), true, false);
              s.LineTo(new Point((endOfArrow.X * .1 + .9) * w, (endOfArrow.Y * .1 + .05 * .9) * h), true, false);
              s.LineTo(new Point(endOfArrow.X * w, endOfArrow.Y * h), true, false);

              s.BezierTo(new Point(c1.X * w, c1.Y * h), new Point(c2.X * w, c2.Y * h), new Point((center.X + radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);

              // Inner circle
              radius = .35;
              cpOffset = factor * .35;
              s.BeginFigure(new Point(center.X * w, (center.Y - radius) * h), true, true);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false); //UL TL
              s.BezierTo(new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false); //BL TB
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false); //BR TR
              s.BezierTo(new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.GenderFemale: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.232, .136);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.782, .611);
            // First, the circle:
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              // Head:
               // Outer Circle
              float r = .375f; // radius
              float cx = 0; // offset from Center x
              float cy = -.125f; // offset from Center y
              float d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
              context.BeginFigure(new Point((.525 + cx) * w, (.5 + r + cy) * h), true, true);
              context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((1 - .5 + r + cx) * w, (.5 - d + cy) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
              context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.475 + cx) * w, (.5 + r + cy) * h), true, false);
              // Legs
              context.LineTo(new Point(.475 * w, .85 * h), true, false);
              context.LineTo(new Point(.425 * w, .85 * h), true, false);
              context.LineTo(new Point(.425 * w, .9 * h), true, false);
              context.LineTo(new Point(.475 * w, .9 * h), true, false);
              context.LineTo(new Point(.475 * w, 1 * h), true, false);
              context.LineTo(new Point(.525 * w, 1 * h), true, false);
              context.LineTo(new Point(.525 * w, .9 * h), true, false);
              context.LineTo(new Point(.575 * w, .9 * h), true, false);
              context.LineTo(new Point(.575 * w, .85 * h), true, false);
              context.LineTo(new Point(.525 * w, .85 * h), true, false);

              // Inner circle
              r = .325f; // radius
              cx = 0; // offset from Center x
              cy = -.125f; // offset from Center y
              d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
              context.BeginFigure(new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, true);
              context.BezierTo(new Point((1 - .5 + r + cx) * w, (.5 - d + cy) * h), new Point((.5 + d + cx) * w, (.5 - r + cy) * h), new Point((.5 + cx) * w, (.5 - r + cy) * h), true, false);
              context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.5 + cx) * w, (.5 + r + cy) * h), true, false);
              context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.PlusLine: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, .5 * h), false, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);

              context.BeginFigure(new Point(.5 * w, 0), false, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.XLine: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 1 * h), false, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.BeginFigure(new Point(0, 0), false, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.AsteriskLine: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              double offset = .2 / Math.Sqrt(2);
              context.BeginFigure(new Point(offset * w, (1 - offset) * h), false, false);
              context.LineTo(new Point((1 - offset) * w, offset * h), true, false);
              context.BeginFigure(new Point(offset * w, offset * h), false, false);
              context.LineTo(new Point((1 - offset) * w, (1 - offset) * h), true, false);
              context.BeginFigure(new Point(0 * w, .5 * h), false, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
              context.BeginFigure(new Point(.5 * w, 0 * h), false, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.CircleLine: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.146, .146);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.853, .853);

            double factor = Geo.MagicBezierFactor;
            double cpOffset = factor * .5;
            double radius = .5;
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, radius * h), false, false);
              context.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
              context.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              context.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
              context.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Pie: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              float r = .5f;
              float cx = 0; // offset from Center x
              float cy = 0; // offset from Center y
              float d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);

              double x1 = (.5 * Math.Sqrt(2) / 2 + .5);
              double y1 = (.5 - .5 * Math.Sqrt(2) / 2);
              double x4 = .5;
              double y4 = 0;
              double x2 = .7;
              double y2 = 0;
              double x3 = .5;
              double y3 = 0;

              context.BeginFigure(new Point(x1 * w, (y1) * h), true, true);
              context.BezierTo(new Point(x2 * w, y2 * h), new Point(x3 * w, y3 * h), new Point(x4 * w, y4 * h), true, false);
              context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false);
              context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.5 + cx) * w, (.5 + r + cy) * h), true, false);
              context.BezierTo(new Point((.5 + d + cx) * w, (.5 + r + cy) * h), new Point((.5 + r + cx) * w, (.5 + d + cy) * h), new Point((1 - .5 + r + cx) * w, (.5 + cy) * h), true, false);
              context.LineTo(new Point(.5 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.PiePiece: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(w, h), true, true);
              s.BezierTo(new Point(.99 * w, .75 * h), new Point(.94 * w, .25 * h), new Point(w * (.5 + Math.Sqrt(2) / 4), 0), true, false);
              s.LineTo(new Point(0, h), true, false);
              s.LineTo(new Point(w, h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.StopSign: {
            double part = 1 / (Math.Sqrt(2) + 2);
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(part / 2, part / 2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - part / 2, 1 - part / 2);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(part * w, 0), true, true);
              context.LineTo(new Point((1 - part) * w, 0), true, false);
              context.LineTo(new Point(1 * w, part * h), true, false);
              context.LineTo(new Point(1 * w, (1 - part) * h), true, false);
              context.LineTo(new Point((1 - part) * w, 1 * h), true, false);
              context.LineTo(new Point(part * w, 1 * h), true, false);
              context.LineTo(new Point(0, (1 - part) * h), true, false);
              context.LineTo(new Point(0, part * h), true, false);
              context.LineTo(new Point(part * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicImplies: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0,0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8,.5);

            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .2; // Distance the arrow folds from the right
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point((1 - param1) * w, 0 * h), false, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
              context.LineTo(new Point((1 - param1) * w, h), true, false);

              context.BeginFigure(new Point(0, .5 * h), false, false);
              context.LineTo(new Point(w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicIff: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8, .5);

            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .2; // Distance the arrow folds from the right
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point((1 - param1) * w, 0 * h), false, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
              context.LineTo(new Point((1 - param1) * w, h), true, false);

              context.BeginFigure(new Point(0, .5 * h), false, false);
              context.LineTo(new Point(w, .5 * h), true, false);

              context.BeginFigure(new Point(param1 * w, 0), false, false);
              context.LineTo(new Point(0, .5 * h), true, false);
              context.LineTo(new Point(param1 * w, h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicNot: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicAnd: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25,.5);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75,1);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 1 * h), false, false);
              context.LineTo(new Point(.5 * w, 0), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicOr: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.219, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.78, .409);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
              context.LineTo(new Point(1 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicXor: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.5 * w, 0), false, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
              context.BeginFigure(new Point(0, .5 * h), false, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);

              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .5;
              double radius = .5;
              context.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
              context.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              context.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
              context.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicTruth: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.BeginFigure(new Point(.5 * w, 0), false, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicFalsity: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 1 * h), false, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.BeginFigure(new Point(.5 * w, 1 * h), false, false);
              context.LineTo(new Point(.5 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicThereExists: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
              context.LineTo(new Point(0, .5 * h), true, false);
              context.BeginFigure(new Point(1 * w, .5 * h), false, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicForAll: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .5);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.BeginFigure(new Point(.25 * w, .5 * h), false, false);
              context.LineTo(new Point(.75 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicIsDefinedAs: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.01, .01);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.99, .49);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), false, false);
              context.LineTo(new Point(w, 0), true, false);

              context.BeginFigure(new Point(0, .5 * h), false, false);
              context.LineTo(new Point(w, .5 * h), true, false);

              context.BeginFigure(new Point(0, h), false, false);
              context.LineTo(new Point(w, h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicIntersect: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0,.5);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1,1);

            // upside down U
            double factor = Geo.MagicBezierFactor;
            double cpOffset = factor * .5;
            double radius = .5;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 1 * h), false, false);
              context.LineTo(new Point(0, radius * h), true, false);
              context.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
              context.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LogicUnion: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0,0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1,.5);

            // upside down U
            double factor = Geo.MagicBezierFactor;
            double cpOffset = factor * .5;
            double radius = .5;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, 0), false, false);
              context.LineTo(new Point(1 * w, radius * h), true, false);
              context.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
              context.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Arrow: {
            double param1 = this.FigureParameter1;
            double param2 = this.FigureParameter2;
            if (param1 == 0) param1 = .3; // % from the edge the ends of the arrow are
            if (param2 == 0) param2 = .3; // Arrow width
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .5 - param2 / 2);
            Point temp = GetIntersection(new Point(0, .5 + param2 / 2), new Point(1, .5 + param2 / 2), new Point(1 - param1, 1), new Point(1, .5));
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(temp.X, temp.Y);
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, (.5 - param2 / 2) * h), true, true);
              context.LineTo(new Point((1 - param1) * w, (.5 - param2 / 2) * h), true, false);
              context.LineTo(new Point((1 - param1) * w, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
              context.LineTo(new Point((1 - param1) * w, 1 * h), true, false);
              context.LineTo(new Point((1 - param1) * w, (.5 + param2 / 2) * h), true, false);
              context.LineTo(new Point(0, (.5 + param2 / 2) * h), true, false);
              context.LineTo(new Point(0, (.5 - param2 / 2) * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Chevron:
        case NodeFigure.ISOProcess: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(.5 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(.5 * w, .5 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.DoubleArrow: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(.3 * w, 0.214 * h), true, false);
              context.LineTo(new Point(.3 * w, 0), true, false);
              context.LineTo(new Point(1.0 * w, .5 * h), true, false);
              context.LineTo(new Point(.3 * w, 1.0 * h), true, false);
              context.LineTo(new Point(.3 * w, 0.786 * h), true, false);
              context.LineTo(new Point(0, 1.0 * h), true, false);

              context.BeginFigure(new Point(.3 * w, .214 * h), false, false);
              context.LineTo(new Point(.3 * w, .786 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.DoubleEndArrow: {
            Point temp1 = GetIntersection(new Point(0, .5), new Point(.3, 0), new Point(0, .3), new Point(.3, .3));
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(temp1.X, temp1.Y);
            Point temp2 = GetIntersection(new Point(.7, 1), new Point(1, .5), new Point(.7, .7), new Point(1, .7));
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(temp2.X, temp2.Y);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, .5 * h), true, true);
              context.LineTo(new Point(.7 * w, 1 * h), true, false);
              context.LineTo(new Point(.7 * w, .7 * h), true, false);
              context.LineTo(new Point(.3 * w, .7 * h), true, false);
              context.LineTo(new Point(.3 * w, 1 * h), true, false);
              context.LineTo(new Point(0, .5 * h), true, false);
              context.LineTo(new Point(.3 * w, 0), true, false);
              context.LineTo(new Point(.3 * w, .3 * h), true, false);
              context.LineTo(new Point(.7 * w, .3 * h), true, false);
              context.LineTo(new Point(.7 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.IBeamArrow: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .3);
            Point temp = GetIntersection(new Point(.7, 1), new Point(1, .5), new Point(.7, .7), new Point(1, .7));
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(temp.X, temp.Y);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, .5 * h), true, true);
              context.LineTo(new Point(.7 * w, 1 * h), true, false);
              context.LineTo(new Point(.7 * w, .7 * h), true, false);
              context.LineTo(new Point(.2 * w, .7 * h), true, false);
              context.LineTo(new Point(.2 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
              context.LineTo(new Point(.2 * w, 0), true, false);
              context.LineTo(new Point(.2 * w, .3 * h), true, false);
              context.LineTo(new Point(.7 * w, .3 * h), true, false);
              context.LineTo(new Point(.7 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Pointer: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, .35);
            Point temp = GetIntersection(new Point(.2, .65), new Point(1, .65), new Point(0, 1), new Point(1, .5));
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(temp.X, temp.Y);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, .5 * h), true, true);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(.2 * w, .5 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.RoundedPointer: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.4, .35);
            Point temp = GetIntersection(new Point(.2, .65), new Point(1, .65), new Point(0, 1), new Point(1, .5));
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(temp.X, temp.Y);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, .5 * h), true, true);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.BezierTo(new Point(.5 * w, .75 * h), new Point(.5 * w, .25 * h), new Point(0, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.SplitEndArrow: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, .3);
            Point temp = GetIntersection(new Point(.7, 1), new Point(1, .5), new Point(.7, .7), new Point(1, .7));
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(temp.X, temp.Y);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, .5 * h), true, true);
              context.LineTo(new Point(.7 * w, 1 * h), true, false);
              context.LineTo(new Point(.7 * w, .7 * h), true, false);
              context.LineTo(new Point(0, .7 * h), true, false);
              context.LineTo(new Point(.2 * w, .5 * h), true, false);
              context.LineTo(new Point(0, .3 * h), true, false);
              context.LineTo(new Point(.7 * w, .3 * h), true, false);
              context.LineTo(new Point(.7 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.SquareArrow:
        case NodeFigure.MessageToUser: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.7, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, .5 * h), true, true);
              context.LineTo(new Point(.7 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
              context.LineTo(new Point(.7 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cone1: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, .5);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .97);

            double factor = Geo.MagicBezierFactor;
            double cpxOffset = factor * .5;
            double cpyOffset = factor * .1;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, .9 * h), true, true);
              context.LineTo(new Point(.5 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .9 * h), true, false);
              context.BezierTo(new Point(1 * w, (.9 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, 1 * h), new Point(.5 * w, 1 * h), true, false);
              context.BezierTo(new Point((.5 - cpxOffset) * w, 1 * h), new Point(0, (.9 + cpyOffset) * h), new Point(0, .9 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cone2: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, .5);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .82);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, .9 * h), true, true);
              context.BezierTo(new Point((1 - .85 / .9) * w, 1 * h), new Point((.85 / .9) * w, 1 * h), new Point(1 * w, .9 * h), true, false);

              context.LineTo(new Point(.5 * w, 0), true, false);
              context.LineTo(new Point(0, .9 * h), true, false);

              context.BeginFigure(new Point(0, .9 * h), false, false);
              context.BezierTo(new Point((1 - .85 / .9) * w, .8 * h), new Point((.85 / .9) * w, .8 * h), new Point(1 * w, .9 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cube1: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0,.3);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5,.85);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.5 * w, 1 * h), true, true);
              context.LineTo(new Point(1 * w, .85 * h), true, false);
              context.LineTo(new Point(1 * w, .15 * h), true, false);
              context.LineTo(new Point(.5 * w, 0 * h), true, false);
              context.LineTo(new Point(0 * w, .15 * h), true, false);
              context.LineTo(new Point(0 * w, .85 * h), true, false);

              context.BeginFigure(new Point(.5 * w, 1 * h), false, false);
              context.LineTo(new Point(.5 * w, .3 * h), true, false);
              context.LineTo(new Point(0, .15 * h), true, false);

              context.BeginFigure(new Point(.5 * w, .3 * h), false, false);
              context.LineTo(new Point(1 * w, .15 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cube2: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0,.3);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.7,1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, .3 * h), true, true);
              context.LineTo(new Point(0 * w, 1 * h), true, false);
              context.LineTo(new Point(.7 * w, h), true, false);
              context.LineTo(new Point(1 * w, .7 * h), true, false);
              context.LineTo(new Point(1 * w, 0 * h), true, false);
              context.LineTo(new Point(.3 * w, 0 * h), true, false);

              context.BeginFigure(new Point(0, .3 * h), false, false);
              context.LineTo(new Point(.7 * w, .3 * h), true, false);
              context.LineTo(new Point(1 * w, 0 * h), true, false);
              context.BeginFigure(new Point(.7 * w, .3 * h), false, false);
              context.LineTo(new Point(.7 * w, 1 * h), true, false);


            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cylinder1:
        case NodeFigure.MagneticData: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0,.2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1,.9);

            double factor = Geo.MagicBezierFactor;
            double cpxOffset = factor * .5;
            double cpyOffset = factor * .1;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              // The base (top)
              context.BeginFigure(new Point(0, .1 * h), true, true);
              context.BezierTo(new Point(0, (.1 - cpyOffset) * h), new Point((.5 - cpxOffset) * w, 0), new Point(.5 * w, 0), true, true);
              context.BezierTo(new Point((.5 + cpxOffset) * w, 0), new Point(1.0 * w, (.1 - cpyOffset) * h), new Point(1.0 * w, .1 * h), true, true);
              context.LineTo(new Point(w, .9 * h), true, false);

              //// Bottom curve
              context.BezierTo(new Point(1.0 * w, (.9 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, 1.0 * h), new Point(.5 * w, 1.0 * h), true, true);
              context.BezierTo(new Point((.5 - cpxOffset) * w, 1.0 * h), new Point(0, (.9 + cpyOffset) * h), new Point(0, .9 * h), true, true);
              context.LineTo(new Point(0, .1 * h), true, false);

              context.BeginFigure(new Point(0, .1 * h), false, false);
              context.BezierTo(new Point(0, (.1 + cpyOffset) * h), new Point((.5 - cpxOffset) * w, .2 * h), new Point(.5 * w, .2 * h), true, true);
              context.BezierTo(new Point((.5 + cpxOffset) * w, .2 * h), new Point(1.0 * w, (.1 + cpyOffset) * h), new Point(1.0 * w, .1 * h), true, true);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cylinder2: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0,.1);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1,.8);

            double factor = Geo.MagicBezierFactor;
            double cpxOffset = factor * .5;
            double cpyOffset = factor * .1;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // The base (bottom)
              s.BeginFigure(new Point(0, .9 * h), false, false);
              s.BezierTo(new Point(0, (.9 - cpyOffset) * h), new Point((.5 - cpxOffset) * w, .8 * h), new Point(.5 * w, .8 * h), true, false);
              s.BezierTo(new Point((.5 + cpxOffset) * w, .8 * h), new Point(1 * w, (.9 - cpyOffset) * h), new Point(1 * w, .9 * h), true, false);

              // The body, starting and ending bottom left
              s.BeginFigure(new Point(0, .9 * h), true, true);
              s.LineTo(new Point(0, .1 * h), true, false);
              s.BezierTo(new Point(0, (.1 - cpyOffset) * h), new Point((.5 - cpxOffset) * w, 0), new Point(.5 * w, 0), true, false);
              s.BezierTo(new Point((.5 + cpxOffset) * w, 0), new Point(1 * w, (.1 - cpyOffset) * h), new Point(1 * w, .1 * h), true, false);
              s.LineTo(new Point(1 * w, .9 * h), true, false);
              s.BezierTo(new Point(1 * w, (.9 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, 1 * h), new Point(.5 * w, 1 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, 1 * h), new Point(0, (.9 + cpyOffset) * h), new Point(0, .9 * h), true, false);

              sg.FillRule = FillRule.Nonzero;
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cylinder3: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2,0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.9,1);

            double factor = Geo.MagicBezierFactor;
            double cpxOffset = factor * .1;
            double cpyOffset = factor * .5;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              //cylinder line (left)
              s.BeginFigure(new Point(.1 * w, 0), false, false);
              s.BezierTo(new Point((.1 + cpxOffset) * w, 0), new Point(.2 * w, (.5 - cpyOffset) * h), new Point(.2 * w, .5 * h), true, false);
              s.BezierTo(new Point(.2 * w, (.5 + cpyOffset) * h), new Point((.1 + cpxOffset) * w, 1 * h), new Point(.1 * w, 1 * h), true, false);

              // The body, starting and ending top left
              s.BeginFigure(new Point(.1 * w, 0), true, true);
              s.LineTo(new Point(.9 * w, 0), true, false);
              s.BezierTo(new Point((.9 + cpxOffset) * w, 0), new Point(1 * w, (.5 - cpyOffset) * h), new Point(1 * w, .5 * h), true, false);
              s.BezierTo(new Point(1 * w, (.5 + cpyOffset) * h), new Point((.9 + cpxOffset) * w, 1 * h), new Point(.9 * w, 1 * h), true, false); //other side down
              s.LineTo(new Point(.1 * w, 1 * h), true, false);
              s.BezierTo(new Point((.1 - cpxOffset) * w, 1 * h), new Point(0, (.5 + cpyOffset) * h), new Point(0, .5 * h), true, false);
              s.BezierTo(new Point(0, (.5 - cpyOffset) * h), new Point((.1 - cpxOffset) * w, 0), new Point(.1 * w, 0), true, false);

              sg.FillRule = FillRule.Nonzero;
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Cylinder4:
        case NodeFigure.DirectData: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.1,0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8,1);

            double factor = Geo.MagicBezierFactor;
            double cpxOffset = factor * .1;
            double cpyOffset = factor * .5;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Cylinder line (right)
              s.BeginFigure(new Point(.9 * w, 0), false, false);
              s.BezierTo(new Point((.9 - cpxOffset) * w, 0), new Point(.8 * w, (.5 - cpyOffset) * h), new Point(.8 * w, .5 * h), true, false);
              s.BezierTo(new Point(.8 * w, (.5 + cpyOffset) * h), new Point((.9 - cpxOffset) * w, 1 * h), new Point(.9 * w, 1 * h), true, false);

              // The body, starting and ending top right
              s.BeginFigure(new Point(.9 * w, 0), true, false);
              s.BezierTo(new Point((.9 + cpxOffset) * w, 0), new Point(1 * w, (.5 - cpyOffset) * h), new Point(1 * w, .5 * h), true, false);
              s.BezierTo(new Point(1 * w, (.5 + cpyOffset) * h), new Point((.9 + cpxOffset) * w, 1 * h), new Point(.9 * w, 1 * h), true, false);
              s.LineTo(new Point(.1 * w, 1 * h), true, false);
              s.BezierTo(new Point((.1 - cpxOffset) * w, 1 * h), new Point(0, (.5 + cpyOffset) * h), new Point(0, .5 * h), true, false);
              s.BezierTo(new Point(0, (.5 - cpyOffset) * h), new Point((.1 - cpxOffset) * w, 0), new Point(.1 * w, 0), true, false);
              s.LineTo(new Point(.9 * w, 0), true, false);

              sg.FillRule = FillRule.Nonzero;
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Prism1: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.408,.172);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.833,.662);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.25 * w, .25 * h), true, true);
              context.LineTo(new Point(.75 * w, 0), true, false);
              context.LineTo(new Point(w, .5 * h), true, false);
              context.LineTo(new Point(.5 * w, h), true, false);
              context.LineTo(new Point(0, h), true, false);

              context.BeginFigure(new Point(.25 * w, .25 * h), false, false);
              context.LineTo(new Point(.5 * w, h), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        case NodeFigure.Prism2: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25,.5);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75,.75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(0, .25 * h), true, true);
              context.LineTo(new Point(.75 * w, 0), true, false);
              context.LineTo(new Point(1 * w, .25 * h), true, false);
              context.LineTo(new Point(.75 * w, .75 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);

              context.BeginFigure(new Point(0, h), false, false);
              context.LineTo(new Point(.25 * w, .5 * h), true, false);
              context.LineTo(new Point(w, .25 * h), true, false);

              context.BeginFigure(new Point(0, .25 * h), false, false);
              context.LineTo(new Point(.25 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Pyramid1: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25,.367);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75,.875);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.5 * w, 0), true, true);
              context.LineTo(new Point(w, .75 * h), true, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
              context.LineTo(new Point(0, .75 * h), true, false);

              context.BeginFigure(new Point(.5 * w, 0), false, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Pyramid2: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, .367);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .875);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.5 * w, 0), true, true);
              context.LineTo(new Point(w, .85 * h), true, false);
              context.LineTo(new Point(.5 * w, 1 * h), true, false);
              context.LineTo(new Point(0, .85 * h), true, false);

              context.BeginFigure(new Point(.5 * w, 0), false, false);
              context.LineTo(new Point(.5 * w, .7 * h), true, false);
              context.LineTo(new Point(0, .85 * h), true, false);

              context.BeginFigure(new Point(.5 * w, .7 * h), false, false);
              context.LineTo(new Point(1 * w, .85 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Actor: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, .2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8, .65);

            double factor = Geo.MagicBezierFactor;
            Size radius = new Size(.2, .1);
            Size offset = new Size(factor * radius.Width, factor * radius.Height);
            Point center = new Point(.5, .1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Head
              s.BeginFigure(new Point(center.X * w, (center.Y + radius.Height) * h), true, true);
              s.BezierTo(new Point((center.X - offset.Width) * w, (center.Y + radius.Height) * h),
                new Point((center.X - radius.Width) * w, (center.Y + offset.Height) * h), new Point((center.X - radius.Width) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X - radius.Width) * w, (center.Y - offset.Height) * h),
                new Point((center.X - offset.Width) * w, (center.Y - radius.Height) * h), new Point(center.X * w, (center.Y - radius.Height) * h), true, false);
              s.BezierTo(new Point((center.X + offset.Width) * w, (center.Y - radius.Height) * h),
                new Point((center.X + radius.Width) * w, (center.Y - offset.Height) * h), new Point((center.X + radius.Width) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius.Width) * w, (center.Y + offset.Height) * h),
                new Point((center.X + offset.Width) * w, (center.Y + radius.Height) * h), new Point(center.X * w, (center.Y + radius.Height) * h), true, false);

              // Body
              double r = .05;
              double cpOffset = factor * r;
              center = new Point(.05, .25);

              s.BeginFigure(new Point(.5 * w, .2 * h), true, false);
              s.LineTo(new Point(.95 * w, .2 * h), true, false);
              center = new Point(.95, .25);
              // Right shoulder
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - r) * h), new Point((center.X + r) * w, (center.Y - cpOffset) * h), new Point((center.X + r) * w, center.Y * h), true, false);
              // Right arm
              s.LineTo(new Point(1 * w, .6 * h), true, false);
              s.LineTo(new Point(.85 * w, .6 * h), true, false);
              s.LineTo(new Point(.85 * w, .35 * h), true, false);

              // Under right arm
              r = .025;
              cpOffset = factor * r;
              center = new Point(.825, .35);
              s.BezierTo(new Point((center.X + r) * w, (center.Y - cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y - r) * h), new Point(center.X * w, (center.Y - r) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y - r) * h), new Point((center.X - r) * w, (center.Y - cpOffset) * h), new Point((center.X - r) * w, center.Y * h), true, false);

              // Right side/leg
              s.LineTo(new Point(.8 * w, 1 * h), true, false);
              s.LineTo(new Point(.55 * w, 1 * h), true, false);
              s.LineTo(new Point(.55 * w, .7 * h), true, false);

              // Right in between
              r = .05;
              cpOffset = factor * r;
              center = new Point(.5, .7);
              s.BezierTo(new Point((center.X + r) * w, (center.Y - cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y - r) * h), new Point(center.X * w, (center.Y - r) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y - r) * h), new Point((center.X - r) * w, (center.Y - cpOffset) * h), new Point((center.X - r) * w, center.Y * h), true, false);

              // Left side/leg
              s.LineTo(new Point(.45 * w, 1 * h), true, false);
              s.LineTo(new Point(.2 * w, 1 * h), true, false);
              s.LineTo(new Point(.2 * w, .35 * h), true, false);

              // Left under arm
              r = .025;
              cpOffset = factor * r;
              center = new Point(.175, .35);
              s.BezierTo(new Point((center.X + r) * w, (center.Y - cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y - r) * h), new Point(center.X * w, (center.Y - r) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y - r) * h), new Point((center.X - r) * w, (center.Y - cpOffset) * h), new Point((center.X - r) * w, center.Y * h), true, false);

              // Left arm
              s.LineTo(new Point(.15 * w, .6 * h), true, false);
              s.LineTo(new Point(0 * w, .6 * h), true, false);
              s.LineTo(new Point(0 * w, .25 * h), true, false);

              r = .05;
              cpOffset = factor * r;
              center = new Point(.05, .25);
              // Left shoulder
              s.BezierTo(new Point((center.X - r) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - r) * h), new Point(center.X * w, (center.Y - r) * h), true, false);
              s.LineTo(new Point(.5 * w, .2 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Card: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(1 * w, 0 * h), true, true);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0 * w, 1 * h), true, false);
              context.LineTo(new Point(0 * w, .2 * h), true, false);
              context.LineTo(new Point(.2 * w, 0 * h), true, false);
              context.LineTo(new Point(1 * w, 0 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Collate: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25,0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75,.25);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              context.BeginFigure(new Point(.5 * w, .5 * h), true, true);
              context.LineTo(new Point(0, 0), true, false);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(.5 * w, .5 * h), true, false);

              context.BeginFigure(new Point(.5 * w, .5 * h), true, true);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(.5 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.CreateRequest: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .1;
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, param1);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1 - param1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext context = sg.Open()) {
              // Inside lines
              context.BeginFigure(new Point(0, param1 * h), false, false);
              context.LineTo(new Point(1 * w, param1 * h), true, false);
              context.BeginFigure(new Point(0, (1 - param1) * h), false, false);
              context.LineTo(new Point(1 * w, (1 - param1) * h), true, false);

              // Body
              context.BeginFigure(new Point(0, 0), true, true);
              context.LineTo(new Point(1 * w, 0), true, false);
              context.LineTo(new Point(1 * w, 1 * h), true, false);
              context.LineTo(new Point(0, 1 * h), true, false);
              context.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Database: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .4);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, .9);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpxOffset = factor * .5;
              double cpyOffset = factor * .1;
              // Rings
              s.BeginFigure(new Point(1 * w, .1 * h), false, false);
              s.BezierTo(new Point(1 * w, (.1 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, .2 * h), new Point(.5 * w, .2 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, .2 * h), new Point(0, (.1 + cpyOffset) * h), new Point(0, .1 * h), true, false);
              s.BeginFigure(new Point(1 * w, .2 * h), false, false);
              s.BezierTo(new Point(1 * w, (.2 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, .3 * h), new Point(.5 * w, .3 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, .3 * h), new Point(0, (.2 + cpyOffset) * h), new Point(0, .2 * h), true, false);
              s.BeginFigure(new Point(1 * w, .3 * h), false, false);
              s.BezierTo(new Point(1 * w, (.3 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, .4 * h), new Point(.5 * w, .4 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, .4 * h), new Point(0, (.3 + cpyOffset) * h), new Point(0, .3 * h), true, false);

              // Body
              s.BeginFigure(new Point(1 * w, .1 * h), true, false);
              s.LineTo(new Point(1 * w, .9 * h), true, false);
              s.BezierTo(new Point(1 * w, (.9 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, 1 * h), new Point(.5 * w, 1 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, 1 * h), new Point(0, (.9 + cpyOffset) * h), new Point(0, .9 * h), true, false);
              s.LineTo(new Point(0, .1 * h), true, false);
              s.BezierTo(new Point(0, (.1 - cpyOffset) * h), new Point((.5 - cpxOffset) * w, 0), new Point(.5 * w, 0), true, false);
              s.BezierTo(new Point((.5 + cpxOffset) * w, 0), new Point(1 * w, (.1 - cpyOffset) * h), new Point(1 * w, .1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.DataStorage: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.226, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.81, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.BezierTo(new Point(1 * w, 0), new Point(1 * w, 1 * h), new Point(.75 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.BezierTo(new Point(.25 * w, .9 * h), new Point(.25 * w, .1 * h), new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.DiskStorage: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .3);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, .9);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpxOffset = factor * .5;
              double cpyOffset = factor * .1;
              // Rings
              s.BeginFigure(new Point(1 * w, .1 * h), false, false);
              s.BezierTo(new Point(1 * w, (.1 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, .2 * h), new Point(.5 * w, .2 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, .2 * h), new Point(0, (.1 + cpyOffset) * h), new Point(0, .1 * h), true, false);
              s.BeginFigure(new Point(1 * w, .2 * h), false, false);
              s.BezierTo(new Point(1 * w, (.2 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, .3 * h), new Point(.5 * w, .3 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, .3 * h), new Point(0, (.2 + cpyOffset) * h), new Point(0, .2 * h), true, false);

              // Body
              s.BeginFigure(new Point(1 * w, .1 * h), true, false);
              s.LineTo(new Point(1 * w, .9 * h), true, false);
              s.BezierTo(new Point(1 * w, (.9 + cpyOffset) * h), new Point((.5 + cpxOffset) * w, 1 * h), new Point(.5 * w, 1 * h), true, false);
              s.BezierTo(new Point((.5 - cpxOffset) * w, 1 * h), new Point(0, (.9 + cpyOffset) * h), new Point(0, .9 * h), true, false);
              s.LineTo(new Point(0, .1 * h), true, false);
              s.BezierTo(new Point(0, (.1 - cpyOffset) * h), new Point((.5 - cpxOffset) * w, 0), new Point(.5 * w, 0), true, false);
              s.BezierTo(new Point((.5 + cpxOffset) * w, 0), new Point(1 * w, (.1 - cpyOffset) * h), new Point(1 * w, .1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Display: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.25 * w, 0), true, true);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.BezierTo(new Point(1 * w, 0), new Point(1 * w, 1 * h), new Point(.75 * w, 1 * h), true, false);
              s.LineTo(new Point(.25 * w, 1 * h), true, false);
              s.LineTo(new Point(0, .5 * h), true, false);
              s.LineTo(new Point(.25 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.DividedEvent: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .2;
            else if (param1 < .15) param1 = .15; // Minimum
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, param1);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1 - param1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .2;
              s.BeginFigure(new Point(0, param1 * h), false, false);
              s.LineTo(new Point(1 * w, param1 * h), true, false);

              s.BeginFigure(new Point(0, .2 * h), true, true);
              s.BezierTo(new Point(0, (.2 - cpOffset) * h), new Point((.2 - cpOffset) * w, 0), new Point(.2 * w, 0), true, false);
              s.LineTo(new Point(.8 * w, 0), true, false);
              s.BezierTo(new Point((.8 + cpOffset) * w, 0), new Point(1 * w, (.2 - cpOffset) * h), new Point(1 * w, .2 * h), true, false);
              s.LineTo(new Point(1 * w, .8 * h), true, false);
              s.BezierTo(new Point(1 * w, (.8 + cpOffset) * h), new Point((.8 + cpOffset) * w, 1 * h), new Point(.8 * w, 1 * h), true, false);
              s.LineTo(new Point(.2 * w, 1 * h), true, false);
              s.BezierTo(new Point((.2 - cpOffset) * w, 1 * h), new Point(0, (.8 + cpOffset) * h), new Point(0, .8 * h), true, false);
              s.LineTo(new Point(0, .2 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.DividedProcess: {
            double param1 = this.FigureParameter1;
            if (param1 < .1) param1 = .1; // Minimum
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, param1);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, param1 * h), false, false);
              s.LineTo(new Point(1 * w, param1 * h), true, false);

              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Document: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, .6);

            h = h / .8;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, .7 * h), true, true);
              s.LineTo(new Point(0, 0), true, false);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .7 * h), true, false);
              s.BezierTo(new Point(.5 * w, .4 * h), new Point(.5 * w, 1 * h), new Point(0, .7 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ExternalOrganization: {
            double param1 = this.FigureParameter1;
            if (param1 < .2) param1 = .2; // Minimum

            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1 / 2, param1 / 2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param1 / 2, 1 - param1 / 2);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Top left triangle
              s.BeginFigure(new Point(param1 * w, 0), false, false);
              s.LineTo(new Point(0, param1 * h), true, false);
              // Top right triangle
              s.BeginFigure(new Point(1 * w, param1 * h), false, false);
              s.LineTo(new Point((1 - param1) * w, 0), true, false);
              // Bottom left triangle
              s.BeginFigure(new Point(0, (1 - param1) * h), false, false);
              s.LineTo(new Point(param1 * w, 1 * h), true, false);
              // Bottom Right triangle
              s.BeginFigure(new Point((1 - param1) * w, 1 * h), false, false);
              s.LineTo(new Point(1 * w, (1 - param1) * h), true, false);
              // Body
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ExternalProcess: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Top left triangle
              s.BeginFigure(new Point(.1 * w, .4 * h), false, false);
              s.LineTo(new Point(.1 * w, .6 * h), true, false);
              // Top right triangle
              s.BeginFigure(new Point(.9 * w, .6 * h), false, false);
              s.LineTo(new Point(.9 * w, .4 * h), true, false);
              // Bottom left triangle
              s.BeginFigure(new Point(.6 * w, .1 * h), false, false);
              s.LineTo(new Point(.4 * w, .1 * h), true, false);
              // Bottom Right triangle
              s.BeginFigure(new Point(.4 * w, .9 * h), false, false);
              s.LineTo(new Point(.6 * w, .9 * h), true, false);
              // Body
              s.BeginFigure(new Point(.5 * w, 0), true, true);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
              s.LineTo(new Point(.5 * w, 1 * h), true, false);
              s.LineTo(new Point(0, .5 * h), true, false);
              s.LineTo(new Point(.5 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.File: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // The fold
              s.BeginFigure(new Point(.75 * w, 0), false, false);
              s.LineTo(new Point(.75 * w, .25 * h), true, false);
              s.LineTo(new Point(1 * w, .25 * h), true, false);

              // Body
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .25 * h), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Interupt: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(1 * w, .5 * h), false, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.BeginFigure(new Point(1 * w, .5 * h), false, false);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.BeginFigure(new Point(1 * w, .5 * h), true, true);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.InternalStorage: {
            double param1 = this.FigureParameter1;
            double param2 = this.FigureParameter2;
            if (param1 == 0) param1 = .1; // Distance from left
            if (param2 == 0) param2 = .1; // Distance from top
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, param2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Two lines
              s.BeginFigure(new Point(param1 * w, 0), false, false);
              s.LineTo(new Point(param1 * w, 1 * h), true, false);
              s.BeginFigure(new Point(0, param2 * h), false, false);
              s.LineTo(new Point(1 * w, param2 * h), true, false);

              // The main body
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Junction: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // X in circle
              double factor = Geo.MagicBezierFactor;
              double dist = (double)(1 / Math.Sqrt(2));
              double small = (double)((1 - 1 / Math.Sqrt(2)) / 2);
              double cpOffset = factor * .5;
              double radius = .5;
              // X
              s.BeginFigure(new Point((small + dist) * w, (small + dist) * h), false, false);
              s.LineTo(new Point(small * w, small * h), true, false);
              s.BeginFigure(new Point(small * w, (small + dist) * h), false, false);
              s.LineTo(new Point((small + dist) * w, small * h), true, false);

              // Circle
              s.BeginFigure(new Point(1 * w, radius * h), true, true);
              s.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
              s.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              s.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
              s.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LinedDocument: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, .6);

            h = h / .8;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.1 * w, 0), false, false);
              s.LineTo(new Point(.1 * w, .75 * h), true, false);

              s.BeginFigure(new Point(0, .7 * h), true, true);
              s.LineTo(new Point(0, 0), true, false);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .7 * h), true, false);
              s.BezierTo(new Point(.5 * w, .4 * h), new Point(.5 * w, 1 * h), new Point(0, .7 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.LoopLimit: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 1 * h), true, true);
              s.LineTo(new Point(0, .25 * h), true, false);
              s.LineTo(new Point(.25 * w, 0), true, false);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .25 * h), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.MagneticTape:
        case NodeFigure.SequentialData: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.15, .15);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.85, .8);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .5;
              double radius = .5;

              s.BeginFigure(new Point(.5 * w, 1 * h), true, true);
              s.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              s.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
              s.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
              s.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, .9 * h), new Point((radius + .1) * w, .9 * h), true, false);
              s.LineTo(new Point(1 * w, .9 * h), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(.5 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ManualInput: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(1 * w, 0), true, true);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, .25 * h), true, false);
              s.LineTo(new Point(1 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.MessageFromUser: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .7; // How far from the right the point is
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(param1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(param1 * w, .5 * h), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.MicroformProcessing: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .25; // How far from the top/bottom the points are
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, param1);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1 - param1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(.5 * w, param1 * h), true, false);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(.5 * w, (1 - param1) * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.MicroformRecording: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(.75 * w, .25 * h), true, false);
              s.LineTo(new Point(1 * w, .15 * h), true, false);
              s.LineTo(new Point(1 * w, .85 * h), true, false);
              s.LineTo(new Point(.75 * w, .75 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.MultiDocument: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8, .77);

            h = h / .8;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Outline
              s.BeginFigure(new Point(w, 0), true, true);
              s.LineTo(new Point(w, .5 * h), true, false);
              s.BezierTo(new Point(.96 * w, .47 * h), new Point(.93 * w, .45 * h), new Point(.9 * w, .44 * h), true, false);
              s.LineTo(new Point(.9 * w, .6 * h), true, false);
              s.BezierTo(new Point(.86 * w, .57 * h), new Point(.83 * w, .55 * h), new Point(.8 * w, .54 * h), true, false);
              s.LineTo(new Point(.8 * w, .7 * h), true, false);
              s.BezierTo(new Point(.4 * w, .4 * h), new Point(.4 * w, 1 * h), new Point(0, .7 * h), true, false);
              s.LineTo(new Point(0, .2 * h), true, false);
              s.LineTo(new Point(.1 * w, .2 * h), true, false);
              s.LineTo(new Point(.1 * w, .1 * h), true, false);
              s.LineTo(new Point(.2 * w, .1 * h), true, false);
              s.LineTo(new Point(.2 * w, 0), true, false);
              s.LineTo(new Point(w, .0), true, false);

              // Inside lines
              s.BeginFigure(new Point(.1 * w, .2 * h), false, false);
              s.LineTo(new Point(.8 * w, .2 * h), true, false);
              s.LineTo(new Point(.8 * w, .54 * h), true, false);

              s.BeginFigure(new Point(.2 * w, .1 * h), false, false);
              s.LineTo(new Point(.9 * w, .1 * h), true, false);
              s.LineTo(new Point(.9 * w, .44 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.MultiProcess: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .2);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.2 * w, .1 * h), false, false);
              s.LineTo(new Point(.9 * w, .1 * h), true, false);
              s.LineTo(new Point(.9 * w, .8 * h), true, false);
              s.BeginFigure(new Point(.1 * w, .2 * h), false, false);
              s.LineTo(new Point(.8 * w, .2 * h), true, false);
              s.LineTo(new Point(.8 * w, .9 * h), true, false);

              s.BeginFigure(new Point(.1 * w, .1 * h), true, true);
              s.LineTo(new Point(.2 * w, .1 * h), true, false);
              s.LineTo(new Point(.2 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .8 * h), true, false);
              s.LineTo(new Point(.9 * w, .8 * h), true, false);
              s.LineTo(new Point(.9 * w, .9 * h), true, false);
              s.LineTo(new Point(.8 * w, .9 * h), true, false);
              s.LineTo(new Point(.8 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, .2 * h), true, false);
              s.LineTo(new Point(.1 * w, .2 * h), true, false);
              s.LineTo(new Point(.1 * w, .1 * h), true, false);

              sg.FillRule = FillRule.Nonzero;
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.OfflineStorage: {
            if (FigureParameter1 == 0) FigureParameter1 = .1; // Distance between 2 top lines
            double l = 1 - FigureParameter1; // Length of the top line
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(l / 4 + .5 * FigureParameter1, FigureParameter1);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(3 * l / 4 + .5 * FigureParameter1, FigureParameter1 + .5 * l);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.5 * FigureParameter1 * w, FigureParameter1 * h), false, false);
              s.LineTo(new Point((1 - .5 * FigureParameter1) * w, FigureParameter1 * h), true, false);

              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(.5 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.OffPageConnector: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
              s.LineTo(new Point(.75 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Or: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // + in circle
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .5;
              double radius = .5;
              // +
              s.BeginFigure(new Point(1 * w, .5 * h), false, false);
              s.LineTo(new Point(0, .5 * h), true, false);
              s.BeginFigure(new Point(.5 * w, 1 * h), false, false);
              s.LineTo(new Point(.5 * w, 0), true, false);

              // Circle
              s.BeginFigure(new Point(1 * w, radius * h), true, true);
              s.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
              s.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              s.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
              s.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.PaperTape: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .49);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, .75);

            h = h / .8;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, .7 * h), true, true);
              s.LineTo(new Point(0, .3 * h), true, false);
              s.BezierTo(new Point(.5 * w, .6 * h), new Point(.5 * w, 0), new Point(1 * w, .3), true, false);
              s.LineTo(new Point(1 * w, .7 * h), true, false);
              s.BezierTo(new Point(.5 * w, .4 * h), new Point(.5 * w, 1 * h), new Point(0, .7 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.PrimitiveFromCall: {
            double param1 = this.FigureParameter1;
            double param2 = this.FigureParameter2;
            if (param1 == 0) param1 = .1; // Distance of left line from left
            if (param2 == 0) param2 = .3; // Distance of point from right
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param2, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Left Rectangle
              s.BeginFigure(new Point(param1 * w, 0), false, false);
              s.LineTo(new Point(param1 * w, 1 * h), true, false);

              // Body
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point((1 - param2) * w, .5 * h), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.PrimitiveToCall: {
            double param1 = this.FigureParameter1;
            double param2 = this.FigureParameter2;
            if (param1 == 0) param1 = .1; // Distance of left line from left
            if (param2 == 0) param2 = .3; // Distance of top and bottom right corners from right
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param2, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Left Rectangle
              s.BeginFigure(new Point(param1 * w, 0), false, false);
              s.LineTo(new Point(param1 * w, 1 * h), true, false);

              // Body
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point((1 - param2) * w, 0), true, false);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
              s.LineTo(new Point((1 - param2) * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Procedure:
        case NodeFigure.Subroutine: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .1; // Distance of left  and right lines from edge
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1 - param1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point((1 - param1) * w, 0), false, false);
              s.LineTo(new Point((1 - param1) * w, 1 * h), true, false);
              s.BeginFigure(new Point(param1 * w, 0), false, false);
              s.LineTo(new Point(param1 * w, 1 * h), true, false);

              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Process: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .1; // Distance of left  line from left edge
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(param1, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(param1 * w, 0), false, false);
              s.LineTo(new Point(param1 * w, 1 * h), true, false);

              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Sort: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25,.25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75,.5);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, .5 * h), false, false);
              s.LineTo(new Point(1 * w, .5 * h), true, false);

              s.BeginFigure(new Point(.5 * w, 0), true, true);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
              s.LineTo(new Point(.5 * w, 1 * h), true, false);
              s.LineTo(new Point(0, .5 * h), true, false);
              s.LineTo(new Point(.5 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Start: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.25 * w, 0), false, false);
              s.LineTo(new Point(.25 * w, 1 * h), true, false);
              s.BeginFigure(new Point(.75 * w, 0), false, false);
              s.LineTo(new Point(.75 * w, 1 * h), true, false);

              s.BeginFigure(new Point(.25 * w, 0), true, true);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.BezierTo(new Point(1 * w, 0), new Point(1 * w, 1 * h), new Point(.75 * w, 1 * h), true, false);
              s.LineTo(new Point(.25 * w, 1 * h), true, false);
              s.BezierTo(new Point(0, 1 * h), new Point(0, 0), new Point(.25 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.StoredData: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.226, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.81, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.BezierTo(new Point(1 * w, 0), new Point(1 * w, 1 * h), new Point(.75 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.BezierTo(new Point(.25 * w, .9 * h), new Point(.25 * w, .1 * h), new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Terminator: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.23, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.77, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.25 * w, 0), true, false);
              s.LineTo(new Point(.75 * w, 0), true, false);
              s.BezierTo(new Point(1 * w, 0), new Point(1 * w, 1 * h), new Point(.75 * w, 1 * h), true, false);
              s.LineTo(new Point(.25 * w, 1 * h), true, false);
              s.BezierTo(new Point(0, 1 * h), new Point(0, 0), new Point(.25 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.TransmittalTape: {
            double param1 = this.FigureParameter1;
            if (param1 == 0) param1 = .1; // Bottom line's distance from the point on the triangle
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(1, 1 - param1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(.75 * w, (1 - param1) * h), true, false);
              s.LineTo(new Point(0, (1 - param1) * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        // Digital Circuits
        case NodeFigure.AndGate: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, 0);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.55, 1);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .5;

              // The gate body
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(.5 * w, 0), true, false);
              s.BezierTo(new Point((.5 + cpOffset) * w, 0), new Point(1 * w, (.5 - cpOffset) * h), new Point(1 * w, .5 * h), true, false);
              s.BezierTo(new Point(1 * w, (.5 + cpOffset) * h), new Point((.5 + cpOffset) * w, 1 * h), new Point(.5 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Buffer: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Clock: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .5;
              double radius = .5;
              // Inside clock
              // This first line solves a GDI+ graphical error with
              // more complex gradient brushes.
              s.BeginFigure(new Point(1 * w, radius * h), false, false);
              s.LineTo(new Point(1 * w, radius * h), true, false);

              s.BeginFigure(new Point(.8 * w, .75 * h), false, false);
              s.LineTo(new Point(.8 * w, .25 * h), true, false);
              s.LineTo(new Point(.6 * w, .25 * h), true, false);
              s.LineTo(new Point(.6 * w, .75 * h), true, false);
              s.LineTo(new Point(.4 * w, .75 * h), true, false);
              s.LineTo(new Point(.4 * w, .25 * h), true, false);
              s.LineTo(new Point(.2 * w, .25 * h), true, false);
              s.LineTo(new Point(.2 * w, .75 * h), true, false);

              // Ellipse
              s.BeginFigure(new Point(1 * w, radius * h), true, true);
              s.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
              s.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
              s.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
              s.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Ground: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.5 * w, 0), false, false);
              s.LineTo(new Point(.5 * w, .4 * h), true, false);
              s.BeginFigure(new Point(.2 * w, .6 * h), false, false);
              s.LineTo(new Point(.8 * w, .6 * h), true, false);
              s.BeginFigure(new Point(.3 * w, .8 * h), false, false);
              s.LineTo(new Point(.7 * w, .8 * h), true, false);
              s.BeginFigure(new Point(.4 * w, 1 * h), false, false);
              s.LineTo(new Point(.6 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Inverter: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.4, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Inversion
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .1;
              double radius = .1;
              Point center = new Point(.9, .5);

              s.BeginFigure(new Point((center.X + radius) * w, center.Y * h), true, true);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false);

              // Triangle
              s.BeginFigure(new Point(.8 * w, .5 * h), true, true);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
              s.LineTo(new Point(.8 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.NandGate: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .05);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.55, .95);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpxOffset = factor * .5;
              double cpyOffset = factor * .4;

              // Inversion
              double cpOffset = factor * .1;
              double radius = .1;
              Point center = new Point(.9, .5);

              s.BeginFigure(new Point((center.X + radius) * w, center.Y * h), true, true);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + radius) * w, (center.Y) * h), true, false);

              // The gate body
              s.BeginFigure(new Point(.8 * w, .5 * h), true, true);
              s.BezierTo(new Point(.8 * w, (.5 + cpyOffset) * h), new Point((.4 + cpxOffset) * w, 1 * h), new Point(.4 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
              s.LineTo(new Point(.4 * w, 0), true, false);
              s.BezierTo(new Point((.4 + cpxOffset) * w, 0), new Point(.8 * w, (.5 - cpyOffset) * h), new Point(.8 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.NorGate: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.6, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;

              // Inversion
              double cpOffset = factor * .1;
              double radius = .1;
              Point center = new Point(.9, .5);

              s.BeginFigure(new Point((center.X - radius) * w, center.Y * h), true, true);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);

              // Normal
              radius = .5;
              cpOffset = factor * radius;
              center = new Point(0, .5);
              s.BeginFigure(new Point(.8 * w, .5 * h), true, true);

              s.BezierTo(new Point(.7 * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(0, 1 * h), true, false);
              s.BezierTo(new Point(.25 * w, .75 * h), new Point(.25 * w, .25 * h), new Point(0, 0), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point(.7 * w, (center.Y - cpOffset) * h), new Point(.8 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.OrGate: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.2, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double radius = .5;
              double cpOffset = factor * radius;
              Point center = new Point(0, .5);

              s.BeginFigure(new Point(0, 0), true, true);
              s.BezierTo(new Point((center.X + cpOffset + cpOffset) * w, (center.Y - radius) * h), new Point(.8 * w, (center.Y - cpOffset) * h), new Point(1 * w, .5 * h), true, false);
              s.BezierTo(new Point(.8 * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset + cpOffset) * w, (center.Y + radius) * h), new Point(0, 1 * h), true, false);
              s.BezierTo(new Point(.25 * w, .75 * h), new Point(.25 * w, .25 * h), new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.XnorGate: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              if (this.Spot1.IsDefault) this.Spot1 = new Spot(.4, .25);
              if (this.Spot2.IsDefault) this.Spot2 = new Spot(.65, .75);

              double factor = Geo.MagicBezierFactor;

              // Inversion
              double cpOffset = factor * .1;
              double radius = .1;
              Point center = new Point(.9, .5);
              s.BeginFigure(new Point((center.X - radius) * w, center.Y * h), true, true);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);

              // Normal
              radius = .5;
              cpOffset = factor * radius;
              center = new Point(.2, .5);
              s.BeginFigure(new Point(.1 * w, 0), false, false);
              s.BezierTo(new Point(.35 * w, .25 * h), new Point(.35 * w, .75 * h), new Point(.1 * w, 1 * h), true, false);

              s.BeginFigure(new Point(.8 * w, .5 * h), true, true);
              s.BezierTo(new Point(.7 * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(.2 * w, 1 * h), true, false);
              s.BezierTo(new Point(.45 * w, .75 * h), new Point(.45 * w, .25 * h), new Point(.2 * w, 0), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point(.7 * w, (center.Y - cpOffset) * h), new Point(.8 * w, .5 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.XorGate: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.4, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.8, .75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double radius = .5;
              double cpOffset = factor * radius;
              Point center = new Point(.2, .5);

              s.BeginFigure(new Point(.1 * w, 0), false, false);
              s.BezierTo(new Point(.35 * w, .25 * h), new Point(.35 * w, .75 * h), new Point(.1 * w, 1 * h), true, false);

              s.BeginFigure(new Point(.2 * w, 0), true, true);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point(.9 * w, (center.Y - cpOffset) * h), new Point(1 * w, .5 * h), true, false);
              s.BezierTo(new Point(.9 * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(.2 * w, 1 * h), true, false);
              s.BezierTo(new Point(.45 * w, .75 * h), new Point(.45 * w, .25 * h), new Point(.2 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Capacitor: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Two vertical Lines
              s.BeginFigure(new Point(0, 0), false, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.BeginFigure(new Point(1 * w, 0), false, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Resistor: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, .5 * h), false, false);
              s.LineTo(new Point(.1 * w, 0), true, false);
              s.LineTo(new Point(.2 * w, 1 * h), true, false);
              s.LineTo(new Point(.3 * w, 0), true, false);
              s.LineTo(new Point(.4 * w, 1 * h), true, false);
              s.LineTo(new Point(.5 * w, 0), true, false);
              s.LineTo(new Point(.6 * w, 1 * h), true, false);
              s.LineTo(new Point(.7 * w, .5 * h), true, false); // I only go from 0 to .7f, letting bounds resize it accordingly
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Inductor: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // 3 loops and two ends
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .1;
              double radius = .1;
              Point center = new Point(.1, .5);
              s.BeginFigure(new Point((center.X - cpOffset * .5) * w, (center.Y + radius) * h), false, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), true, false);

              center = new Point(.3, .5);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), true, false);

              center = new Point(.5, .5);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), true, false);

              center = new Point(.7, .5);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), true, false);

              center = new Point(.9, .5);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point((center.X + cpOffset * .5) * w, (center.Y + radius) * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ACvoltageSource: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Circle with curve in middle
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .5;
              double radius = .5;
              Point center = new Point(.5, .5);

              s.BeginFigure(new Point((center.X - radius) * w, center.Y * h), false, true);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);

              s.BeginFigure(new Point((center.X - radius + .1) * w, center.Y * h), false, false);
              s.BezierTo(new Point(center.X * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y + radius) * h), new Point((center.X + radius - .1) * w, center.Y * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.DCvoltageSource: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Small vertical line and large vertical line
              s.BeginFigure(new Point(0, .75 * h), false, false);
              s.LineTo(new Point(0, .25 * h), true, false);
              s.BeginFigure(new Point(1 * w, 0), false, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Diode: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(0, .25);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.5,.75);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              // Small vertical line and large vertical line
              s.BeginFigure(new Point(0, 0), false, true);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);

              s.BeginFigure(new Point(1 * w, 0), false, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }

        // Computer Shapes
        case NodeFigure.Wifi: {
            double origw = w;
            double origh = h;
            w = w * .38;
            h = h * .6;

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .2;
              double radius = .2;
              Point center = new Point(.5, .5);
              double xOffset = (origw - w) / 2;
              double yOffset = (origh - h) / 2;

              s.BeginFigure(new Point((center.X - radius) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, true);
              s.BezierTo(new Point((center.X - radius) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - cpOffset) * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point((center.X + radius) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + radius) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X + radius) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + cpOffset) * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point((center.X - radius) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - radius) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);

              //Right curves
              cpOffset = factor * .4;
              radius = .4;
              center = new Point(.8, .5);
              s.BeginFigure(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), true, true);
              s.BezierTo(new Point((center.X + cpOffset) * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point((center.X + radius) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + radius) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X + radius) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + cpOffset) * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point((center.X + radius - cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + radius - cpOffset * .5) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X + radius - cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), true, false);

              cpOffset = factor * .8;
              radius = .8;
              center = new Point(1, .5);
              s.BeginFigure(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), true, true);
              s.BezierTo(new Point((center.X + cpOffset) * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point((center.X + radius) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + radius) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X + radius) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + cpOffset) * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point((center.X + radius - cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X + radius - cpOffset * .5) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X + radius - cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), true, false);

              //Left curves
              cpOffset = factor * .4;
              radius = .4;
              center = new Point(.2, .5);
              s.BeginFigure(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), true, true);
              s.BezierTo(new Point((center.X - cpOffset) * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point((center.X - radius) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - radius) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X - radius) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - cpOffset) * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point((center.X - radius + cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - radius + cpOffset * .5) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X - radius + cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), true, false);

              cpOffset = factor * .8;
              radius = .8;
              center = new Point(0, .5);
              s.BeginFigure(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), true, true);
              s.BezierTo(new Point((center.X - cpOffset) * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point((center.X - radius) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - radius) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X - radius) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - cpOffset) * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point(center.X * w /*xoffset*/+ xOffset, (center.Y - radius) * h /*yoffset*/+ yOffset), new Point((center.X - radius + cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y - cpOffset) * h /*yoffset*/+ yOffset), new Point((center.X - radius + cpOffset * .5) * w /*xoffset*/+ xOffset, center.Y * h /*yoffset*/+ yOffset), true, false);
              s.BezierTo(new Point((center.X - radius + cpOffset * .5) * w /*xoffset*/+ xOffset, (center.Y + cpOffset) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), new Point(center.X * w /*xoffset*/+ xOffset, (center.Y + radius) * h /*yoffset*/+ yOffset), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Email: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, 0), false, true);
              s.LineTo(new Point(.5 * w, .6 * h), true, false);
              s.LineTo(new Point(w, 0), true, false);
              s.BeginFigure(new Point(1 * w, 0), false, false);
              s.LineTo(new Point(.5 * w, .6 * h), true, false);
              s.BeginFigure(new Point(0, 1 * h), false, false);
              s.LineTo(new Point(.45 * w, .54 * h), true, false);
              s.BeginFigure(new Point(1 * w, 1 * h), false, false);
              s.LineTo(new Point(.55 * w, .54 * h), true, false);

              s.BeginFigure(new Point(0, 0), true, true);
              s.LineTo(new Point(1 * w, 0), true, false);
              s.LineTo(new Point(1 * w, 1 * h), true, false);
              s.LineTo(new Point(0, 1 * h), true, false);
              s.LineTo(new Point(0, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Ethernet: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(0, .5 * h), false, false);
              s.LineTo(new Point(1 * w, .5 * h), true, false);
              s.BeginFigure(new Point(.5 * w, .5 * h), false, false);
              s.LineTo(new Point(.5 * w, .4 * h), true, false);
              s.BeginFigure(new Point(.75 * w, .5 * h), false, false);
              s.LineTo(new Point(.75 * w, .6 * h), true, false);
              s.BeginFigure(new Point(.25 * w, .5 * h), false, false);
              s.LineTo(new Point(.25 * w, .6 * h), true, false);

              // Boxes at the end of the wires
              s.BeginFigure(new Point(.35 * w, 0), true, true);
              s.LineTo(new Point(.65 * w, 0), true, false);
              s.LineTo(new Point(.65 * w, .4 * h), true, false);
              s.LineTo(new Point(.35 * w, .4 * h), true, false);
              s.LineTo(new Point(.35 * w, 0), true, false);

              s.BeginFigure(new Point(.10 * w, 1 * h), true, true);
              s.LineTo(new Point(.40 * w, 1 * h), true, false);
              s.LineTo(new Point(.40 * w, .6 * h), true, false);
              s.LineTo(new Point(.10 * w, .6 * h), true, false);
              s.LineTo(new Point(.10 * w, 1 * h), true, false);

              s.BeginFigure(new Point(.60 * w, 1 * h), true, true);
              s.LineTo(new Point(.90 * w, 1 * h), true, false);
              s.LineTo(new Point(.90 * w, .6 * h), true, false);
              s.LineTo(new Point(.60 * w, .6 * h), true, false);
              s.LineTo(new Point(.60 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Power: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.25,.55);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.75,.8);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .4;
              double radius = .4;
              Point center = new Point(.5, .5);
              Point unused;
              Point mid;
              Point c1;
              Point c2;
              Point start;
              // Find the 45 degree midpoint for the first bezier
              BreakUpBezier(new Point(center.X, center.Y - radius), new Point(center.X + cpOffset, center.Y - radius),
                new Point(center.X + radius, center.Y - cpOffset), new Point(center.X + radius, center.Y), .5, out unused,
                out unused, out mid, out c1, out c2);
              start = new Point(mid.X, mid.Y);
              s.BeginFigure(new Point(mid.X * w, mid.Y * h), true, true);
              s.BezierTo(new Point(c1.X * w, c1.Y * h), new Point(c2.X * w, c2.Y * h), new Point((center.X + radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);

              // Find the 45 degree midpoint of for the fourth bezier
              BreakUpBezier(new Point(center.X - radius, center.Y), new Point(center.X - radius, center.Y - cpOffset),
                new Point(center.X - cpOffset, center.Y - radius), new Point(center.X, center.Y - radius), .5, out c1,
                out c2, out mid, out unused, out unused);
              s.BezierTo(new Point(c1.X * w, c1.Y * h), new Point(c2.X * w, c2.Y * h), new Point(mid.X * w, mid.Y * h), true, false);

              //now make a smaller circle
              cpOffset = factor * .3;
              radius = .3;

              // Find the 45 degree midpoint for the first bezier
              BreakUpBezier(new Point(center.X - radius, center.Y), new Point(center.X - radius, center.Y - cpOffset),
                new Point(center.X - cpOffset, center.Y - radius), new Point(center.X, center.Y - radius), .5, out c1,
                out c2, out mid, out unused, out unused);
              s.LineTo(new Point(mid.X * w, mid.Y * h), true, false);
              s.BezierTo(new Point(c2.X * w, c2.Y * h), new Point(c1.X * w, c1.Y * h), new Point((center.X - radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false);

              // Find the 45 degree midpoint for the fourth bezier
              BreakUpBezier(new Point(center.X, center.Y - radius), new Point(center.X + cpOffset, center.Y - radius),
                new Point(center.X + radius, center.Y - cpOffset), new Point(center.X + radius, center.Y), .5, out unused,
                out unused, out mid, out c1, out c2);
              s.BezierTo(new Point(c2.X * w, c2.Y * h), new Point(c1.X * w, c1.Y * h), new Point(mid.X * w, mid.Y * h), true, false);
              s.LineTo(new Point(start.X * w, start.Y * h), true, false);

              // The line
              s.BeginFigure(new Point(.45 * w, 0), true, true);
              s.LineTo(new Point(.45 * w, .5 * h), true, false);
              s.LineTo(new Point(.55 * w, .5 * h), true, false);
              s.LineTo(new Point(.55 * w, 0), true, false);
              s.LineTo(new Point(.45 * w, 0), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.Fallout: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              double factor = Geo.MagicBezierFactor;
              double cpOffset = factor * .5;
              double radius = .5;
              Point center = new Point(.5, .5);

              //Containing circle
              s.BeginFigure(new Point((center.X - radius) * w, center.Y * h), true, true);
              s.BezierTo(new Point((center.X - radius) * w, (center.Y - cpOffset) * h), new Point((center.X - cpOffset) * w, (center.Y - radius) * h), new Point(center.X * w, (center.Y - radius) * h), true, false);
              s.BezierTo(new Point((center.X + cpOffset) * w, (center.Y - radius) * h), new Point((center.X + radius) * w, (center.Y - cpOffset) * h), new Point((center.X + radius) * w, center.Y * h), true, false);
              s.BezierTo(new Point((center.X + radius) * w, (center.Y + cpOffset) * h), new Point((center.X + cpOffset) * w, (center.Y + radius) * h), new Point(center.X * w, (center.Y + radius) * h), true, false);
              s.BezierTo(new Point((center.X - cpOffset) * w, (center.Y + radius) * h), new Point((center.X - radius) * w, (center.Y + cpOffset) * h), new Point((center.X - radius) * w, center.Y * h), true, false);

              double offsetx = 0;
              double offsety = 0;
              //Triangles
              s.BeginFigure(new Point((.3 + offsetx) * w, (.8 + offsety) * h), true, true);
              s.LineTo(new Point((.5 + offsetx) * w, (.5 + offsety) * h), true, false);
              s.LineTo(new Point((.1 + offsetx) * w, (.5 + offsety) * h), true, false);
              s.LineTo(new Point((.3 + offsetx) * w, (.8 + offsety) * h), true, false);
              offsetx = .4;
              offsety = 0;
              //Triangles
              s.BeginFigure(new Point((.3 + offsetx) * w, (.8 + offsety) * h), true, true);
              s.LineTo(new Point((.5 + offsetx) * w, (.5 + offsety) * h), true, false);
              s.LineTo(new Point((.1 + offsetx) * w, (.5 + offsety) * h), true, false);
              s.LineTo(new Point((.3 + offsetx) * w, (.8 + offsety) * h), true, false);
              offsetx = .2;
              offsety = -.3;
              //Triangles
              s.BeginFigure(new Point((.3 + offsetx) * w, (.8 + offsety) * h), true, true);
              s.LineTo(new Point((.5 + offsetx) * w, (.5 + offsety) * h), true, false);
              s.LineTo(new Point((.1 + offsetx) * w, (.5 + offsety) * h), true, false);
              s.LineTo(new Point((.3 + offsetx) * w, (.8 + offsety) * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.IrritationHazard: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.3,.3);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.7,.7);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.2 * w, 0 * h), true, true);
              s.LineTo(new Point(.5 * w, .3 * h), true, false);
              s.LineTo(new Point(.8 * w, 0 * h), true, false);
              s.LineTo(new Point(1 * w, .2 * h), true, false);
              s.LineTo(new Point(.7 * w, .5 * h), true, false);
              s.LineTo(new Point(1 * w, .8 * h), true, false);
              s.LineTo(new Point(.8 * w, 1 * h), true, false);
              s.LineTo(new Point(.5 * w, .7 * h), true, false);
              s.LineTo(new Point(.2 * w, 1 * h), true, false);
              s.LineTo(new Point(0 * w, .8 * h), true, false);
              s.LineTo(new Point(.3 * w, .5 * h), true, false);
              s.LineTo(new Point(0 * w, .2 * h), true, false);
              s.LineTo(new Point(.2 * w, 0 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.ElectricalHazard: {
            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.37, 0 * h), true, true);
              s.LineTo(new Point(.5 * w, .11 * h), true, false);
              s.LineTo(new Point(.77 * w, .04 * h), true, false);
              s.LineTo(new Point(.33 * w, .49 * h), true, false);
              s.LineTo(new Point(1 * w, .37 * h), true, false);
              s.LineTo(new Point(.63 * w, .86 * h), true, false);
              s.LineTo(new Point(.77 * w, .91 * h), true, false);
              s.LineTo(new Point(.34 * w, 1 * h), true, false);
              s.LineTo(new Point(.34 * w, .78 * h), true, false);
              s.LineTo(new Point(.44 * w, .8 * h), true, false);
              s.LineTo(new Point(.65 * w, .56 * h), true, false);
              s.LineTo(new Point(0 * w, .68 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.FireHazard: {
            if (this.Spot1.IsDefault) this.Spot1 = new Spot(.05, .645);
            if (this.Spot2.IsDefault) this.Spot2 = new Spot(.884, .908);

            GeoStream sg = new GeoStream();
            using (StreamGeometryContext s = sg.Open()) {
              s.BeginFigure(new Point(.1 * w, 1 * h), true, true);
              s.BezierTo(new Point(-.26 * w, .63 * h), new Point(.45 * w, .44 * h), new Point(.29 * w, 0 * h), true, false);
              s.BezierTo(new Point(.48 * w, .17 * h), new Point(.54 * w, .35 * h), new Point(.51 * w, .42 * h), true, false);
              s.BezierTo(new Point(.59 * w, .29 * h), new Point(.58 * w, .28 * h), new Point(.59 * w, .18 * h), true, false);
              s.BezierTo(new Point(.8 * w, .34 * h), new Point(.88 * w, .43 * h), new Point(.75 * w, .6 * h), true, false);
              s.BezierTo(new Point(.87 * w, .48 * h), new Point(.88 * w, .43 * h), new Point(.88 * w, .31 * h), true, false);
              s.BezierTo(new Point(1.18 * w, .76 * h), new Point(.82 * w, .8 * h), new Point(.9 * w, 1 * h), true, false);
              s.LineTo(new Point(.1 * w, 1 * h), true, false);
            }
            geo = sg.Geometry;
            break;
          }
        case NodeFigure.BpmnActivityLoop: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            float r = .5f;
            float cx = 0; // offset from Center x
            float cy = 0; // offset from Center y
            float d = r * (float)(4 * (Math.Sqrt(2) - 1) / 3);
            double mx1 = (.5 * Math.Sqrt(2) / 2 + .5);
            double my1 = (.5 - .5 * Math.Sqrt(2) / 2);
            double x1 = 1;
            double y1 = .5;
            double x2 = .5;
            double y2 = 0;
            context.BeginFigure(new Point(mx1 * w, (1 - my1) * h), false, false);
            context.BezierTo(new Point(x1 * w, .7 * h), new Point(x1 * w, y1 * h), new Point(x1 * w, y1 * h), true, false);
            context.BezierTo(new Point((.5 + r + cx) * w, (.5 - d + cx) * h), new Point((.5 + d + cx) * w, (.5 - r + cx) * h), new Point((x2  + cx) * w, (y2 + cx) * h), true, false);
            context.BezierTo(new Point((.5 - d + cx) * w, (.5 - r + cy) * h), new Point((.5 - r + cx) * w, (.5 - d + cy) * h), new Point((.5 - r + cx) * w, (.5 + cy) * h), true, false); // ccw, topmiddle to middleleft
            context.BezierTo(new Point((.5 - r + cx) * w, (.5 + d + cy) * h), new Point((.5 - d + cx) * w, (.5 + r + cy) * h), new Point((.35 + cx) * w, (.5 + r -.02 + cy) * h), true, false);
            // draw arrowhead
            context.BeginFigure(new Point((.35 + cx) * w, (.5 + r + cy) * h), false, false);
            context.LineTo(new Point((.35 + cx) * w, (.5 + r - .2 + cy) * h), true, false);
            context.BeginFigure(new Point((.35 + cx) * w, (.5 + r + cy) * h), false, false);
            context.LineTo(new Point((.15 + cx) * w, (.5 + r + cy) * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnActivityParallel: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, 0), false, false);
            context.LineTo(new Point(0, 1 * h), true, false);
            context.BeginFigure(new Point(.5 * w, 0), false, false);
            context.LineTo(new Point(.5 * w, 1 * h), true, false);
            context.BeginFigure(new Point(1 * w, 0), false, false);
            context.LineTo(new Point(1 * w, 1 * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnActivitySequential: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, 0), false, false);
            context.LineTo(new Point(1 * w, 0), true, false);
            context.BeginFigure(new Point(0, .5 * h), false, false);
            context.LineTo(new Point(1 * w, .5 * h), true, false);
            context.BeginFigure(new Point(0, 1 * h), false, false);
            context.LineTo(new Point(1 * w, 1 * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnActivityAdHoc: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, 0), false, false);
            context.BeginFigure(new Point(1 * w, 1 * h), false, false);
            context.BeginFigure(new Point(0, .5 * h), false, false);
            context.BezierTo(new Point(.2 * w, .35 * h), new Point(.3 * w, .35 * h), new Point(.5 * w, .5 * h), true, false);
            context.BezierTo(new Point(.7 * w, .65 * h), new Point(.8 * w, .65 * h), new Point(1 * w, .5 * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnActivityCompensation: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, .5 * h), true, true);
            context.LineTo(new Point(.5 * w, 0), true, true);
            context.LineTo(new Point(.5 * w, 1 * h), true, true);
            context.LineTo(new Point(0, .5 * h), true, true);
            context.BeginFigure(new Point(.5 * w, .5 * h), true, true);
            context.LineTo(new Point(1 * w, 0), true, true);
            context.LineTo(new Point(1 * w, 1 * h), true, true);
            context.LineTo(new Point(.5 * w, .5 * h), true, true);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnTaskMessage: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, 0), false, false);
            context.BeginFigure(new Point(1 * w, 1 * h), false, false);
            context.BeginFigure(new Point(0, .2 * h), false, false);
            context.LineTo(new Point(.5 * w, .5 * h), true, false);
            context.LineTo(new Point(1 * w, .2 * h), true, true);
            context.BeginFigure(new Point(0, .2 * h), true, true);
            context.LineTo(new Point(1 * w, .2 * h), true, false);
            context.LineTo(new Point(1 * w, .8 * h), true, false);
            context.LineTo(new Point(0, .8 * h), true, false);
            context.LineTo(new Point(0, .8 * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnTaskScript: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(.7 * w, 1 * h), true, true);
            context.LineTo(new Point(.3 * w, 1 * h), true, false);
            context.BezierTo(new Point(.6 * w, .5 * h), new Point(0, .5 * h), new Point(0.3 * w, 0), true, false);
            context.LineTo(new Point(.7 * w, 0), true, false);
            context.BezierTo(new Point(.4 * w, .5 * h), new Point(1 * w, .5 * h), new Point(.7 * w, 1 * h), true, false);
            context.BeginFigure(new Point(.45 * w, .73 * h), false, false);
            context.LineTo(new Point(.7 * w, .73 * h), true, false);
            context.BeginFigure(new Point(.38 * w, .5 * h), false, false);
            context.LineTo(new Point(.63 * w, .5 * h), true, false);
            context.BeginFigure(new Point(.31 * w, .27 * h), false, false);
            context.LineTo(new Point(.56 * w, .27 * h), true, false);
          }   
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnTaskUser: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, 0), false, false);
            //shirt
            context.BeginFigure(new Point(.335 * w, (1 - .555) * h), true, true);
            context.LineTo(new Point(.335 * w, (1 - .405) * h), true, true);
            context.LineTo(new Point((1 - .335) * w, (1 - .405) * h), true, true);
            context.LineTo(new Point((1 - .335) * w, (1 - .555) * h), true, true);
            context.BezierTo(new Point((1 - .12) * w, .46 * h), new Point((1 - .02) * w, .54 * h), new Point(1 * w, .68 * h), true, true);
            context.LineTo(new Point(1 * w, 1 * h), true, true);
            context.LineTo(new Point(0, 1 * h), true, true);
            context.LineTo(new Point(0, .68 * h), true, true);
            context.BezierTo(new Point(.02 * w, .54 * h), new Point(.12 * w, .46 * h), new Point(.335 * w, (1 - .555) * h), true, true);
            //start of neck
            context.LineTo(new Point(.365 * w, (1 - .595) * h), true, true);
            double radiushead = .5 - .285;
            Point center = new Point(.5, radiushead);
            double alpha2 = Math.PI / 4;
            double factor = (float)((4 * (1 - Math.Cos(alpha2))) / (3 * Math.Sin(alpha2)));
            double cpOffset = factor * .5f;
            Size radius = new Size(radiushead, radiushead);
            Size offset = new Size(factor * radius.Width, factor * radius.Height);
            // Circle (head)
            context.BezierTo(new Point((center.X - ((offset.Width + radius.Width) / 2)) * w, (center.Y + ((radius.Height + offset.Height) / 2)) * h), new Point((center.X - radius.Width) * w, (center.Y + offset.Height) * h), new Point((center.X - radius.Width) * w, center.Y * h), true, true);
            context.BezierTo(new Point((center.X - radius.Width) * w, (center.Y - offset.Height) * h), new Point((center.X - offset.Width) * w, (center.Y - radius.Height) * h), new Point(center.X * w, (center.Y - radius.Height) * h), true, true);
            context.BezierTo(new Point((center.X + offset.Width) * w, (center.Y - radius.Height) * h), new Point((center.X + radius.Width) * w, (center.Y - offset.Height) * h), new Point((center.X + radius.Width) * w, center.Y * h), true, true);
            context.BezierTo(new Point((center.X + radius.Width) * w, (center.Y + offset.Height) * h), new Point((center.X + ((offset.Width + radius.Width) / 2)) * w, (center.Y + ((radius.Height + offset.Height) / 2)) * h), new Point((1 - .365f) * w, (1 - .595f) * h), true, true);
            context.LineTo(new Point((1 - .365) * w, (1 - .595) * h), true, true);
            //neckline
            context.LineTo(new Point((1 - .335) * w, (1 - .555) * h), true, true);
            context.LineTo(new Point((1 - .335) * w, (1 - .405) * h), true, true);
            context.LineTo(new Point(.335 * w, (1 - .405) * h), true, true);
            //arm lines
            context.BeginFigure(new Point(.2 * w, 1 * h), false, false);
            context.LineTo(new Point(.2 * w, .8 * h), true, true);
            context.BeginFigure(new Point(.8 * w, 1 * h), false, false);
            context.LineTo(new Point(.8 * w, .8 * h), true, true);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnEventConditional: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            // Inside lines
            context.BeginFigure(new Point(0, 0), false, false);
            context.BeginFigure(new Point(1, 1), false, false);
            context.BeginFigure(new Point(.2 * w, .2f * h), false, false);
            context.LineTo(new Point(.8 * w, .2f * h), true, false);
            context.BeginFigure(new Point(.2 * w, .4f * h), false, false);
            context.LineTo(new Point(.8 * w, .4f * h), true, false);
            context.BeginFigure(new Point(.2 * w, .6f * h), false, false);
            context.LineTo(new Point(.8 * w, .6f * h), true, false);
            context.BeginFigure(new Point(.2 * w, .8f * h), false, false);
            context.LineTo(new Point(.8 * w, .8f * h), true, false);
            // Body
            context.BeginFigure(new Point(.1 * w, 0), true, true);
            context.LineTo(new Point(.9 * w, 0), true, false);
            context.LineTo(new Point(.9 * w, 1 * h), true, false);
            context.LineTo(new Point(.1 * w, 1 * h), true, false);
            context.LineTo(new Point(.1 * w, 0), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnEventError: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, 1 * h), true, true);
            context.LineTo(new Point(.33 * w, 0), true, false);
            context.LineTo(new Point(.66 * w, .50 * h), true, false);
            context.LineTo(new Point(1 * w, 0), true, false);
            context.LineTo(new Point(.66 * w, 1 * h), true, false);
            context.LineTo(new Point(.33 * w, .50 * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnEventEscalation: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            context.BeginFigure(new Point(0, 0), false, false);
            context.BeginFigure(new Point(1 * w, 1 * h), false, false);  // set dimensions
            context.BeginFigure(new Point(.1 * w, 1 * h), true, true);
            context.LineTo(new Point(.5 * w, 0), true, false);
            context.LineTo(new Point(.9 * w, 1 * h), true, false);
            context.LineTo(new Point(.5 * w, .5 * h), true, false);
            context.LineTo(new Point(.1 * w, 1 * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }
        case NodeFigure.BpmnEventTimer: {
          GeoStream sg = new GeoStream();
          using (StreamGeometryContext context = sg.Open()) {
            double radius = .5;

            // now, draw the hour lines
            context.BeginFigure(new Point(radius * w, 0), false, false);
            context.LineTo(new Point(radius * w, .15 * h), true, false);
            context.BeginFigure(new Point(radius * w, 1 * h), false, false);
            context.LineTo(new Point(radius * w, .85 * h), true, false);
            context.BeginFigure(new Point(0, radius * h), false, false);
            context.LineTo(new Point(.15 * w, radius * h), true, false);
            context.BeginFigure(new Point(1 * w, radius * h), false, false);
            context.LineTo(new Point(.85 * w, radius * h), true, false);

            // now draw the hands
            context.BeginFigure(new Point(radius * w, radius * h), false, false);
            context.LineTo(new Point(.58 * w, 0.1 * h), true, false);
            context.BeginFigure(new Point(radius * w, radius * h), false, false);
            context.LineTo(new Point(.78 * w, .54 * h), true, false);

            double factor = Geo.MagicBezierFactor;
            double cpOffset = factor * .5;
            context.BeginFigure(new Point(1 * w, radius * h), true, true);
            context.BezierTo(new Point(1 * w, (radius + cpOffset) * h), new Point((radius + cpOffset) * w, 1 * h), new Point(radius * w, 1 * h), true, false);
            context.BezierTo(new Point((radius - cpOffset) * w, 1 * h), new Point(0, (radius + cpOffset) * h), new Point(0, radius * h), true, false);
            context.BezierTo(new Point(0, (radius - cpOffset) * h), new Point((radius - cpOffset) * w, 0), new Point(radius * w, 0), true, false);
            context.BezierTo(new Point((radius + cpOffset) * w, 0), new Point(1 * w, (radius - cpOffset) * h), new Point(1 * w, radius * h), true, false);
          }
          geo = sg.Geometry;
          break;
        }

      }  // End switch

      return geo;
    }
예제 #2
0
 private Geometry GetDefiningGeometry(GridFigure fig, double gw, double gh, int freq, int off, List<Interval> ints, int barmult) {
   double scale = this.RenderedScale;
   if (scale <= 0) scale = 1;
   Size csz = this.CellSize;
   double cw = csz.Width;
   double ch = csz.Height;
   int numx = (int)Math.Ceiling(gw/cw);
   int numy = (int)Math.Ceiling(gh/ch);
   Point cpt = this.Origin;
   GeoStream sg = new GeoStream();
   using (StreamGeometryContext context = sg.Open()) {
     if (fig == GridFigure.None) {
       context.BeginFigure(new Point(0, 0), true, true);
       return sg.Geometry;
     } else if (IsVertical(fig)) {  // vertical
       if (fig == GridFigure.VerticalBar) {
         // vertical lines
         int start = (int)Math.Floor(-cpt.X/cw);
         int i = start;
         for (; i < start+numx; i++) {
           double x = i*cw+cpt.X;
           double x2 = i*cw+cpt.X+barmult*cw;
           if (0 < x2 && x < gw && ShouldDraw(i, freq, off, ints)) {
             x = Math.Max(x, 0);
             x2 = Math.Min(x2, gw);
             context.BeginFigure(new Point(x, 0), true, true);
             context.LineTo(new Point(x, gh), true, false);
             context.LineTo(new Point(x2, gh), true, true);
             context.LineTo(new Point(x2, 0), true, true);
             if (cw*freq*scale < 2) break;
           }
         }
       } else {
         // background rectangle, for the optional Fill
         context.BeginFigure(new Point(0, 0), true, true);
         context.LineTo(new Point(gw, 0), false, false);
         context.LineTo(new Point(gw, gh), false, false);
         context.LineTo(new Point(0, gh), false, false);
         context.LineTo(new Point(0, 0), false, false);
         // vertical lines
         int start = (int)Math.Floor(-cpt.X/cw);
         for (int i = start; i <= start+numx; i++) {
           double x = i*cw+cpt.X;
           if (0 <= x && x <= gw && ShouldDraw(i, freq, off, ints)) {
             context.BeginFigure(new Point(x, 0), false, false);
             context.LineTo(new Point(x, gh), true, false);
             if (cw*freq*scale < 2) break;
           }
         }
       }
     } else {
       if (fig == GridFigure.HorizontalBar) {
         // horizontal lines
         int start = (int)Math.Floor(-cpt.Y/ch);
         int i = start;
         for (; i < start+numy; i++) {
           double y = i*ch+cpt.Y;
           double y2 = i*ch+cpt.Y+barmult*ch;
           if (0 < y2 && y < gh && ShouldDraw(i, freq, off, ints)) {
             y = Math.Max(y, 0);
             y2 = Math.Min(y2, gh);
             context.BeginFigure(new Point(0, y), true, true);
             context.LineTo(new Point(gw, y), true, false);
             context.LineTo(new Point(gw, y2), true, false);
             context.LineTo(new Point(0, y2), true, false);
             if (ch*freq*scale < 2) break;
           }
         }
       } else {
         // background rectangle, for the optional Fill
         context.BeginFigure(new Point(0, 0), true, true);
         context.LineTo(new Point(gw, 0), false, false);
         context.LineTo(new Point(gw, gh), false, false);
         context.LineTo(new Point(0, gh), false, false);
         context.LineTo(new Point(0, 0), false, false);
         // horizontal lines
         int start = (int)Math.Floor(-cpt.Y/ch);
         for (int i = start; i <= start+numy; i++) {
           double y = i*ch+cpt.Y;
           if (0 <= y && y <= gh && ShouldDraw(i, freq, off, ints)) {
             context.BeginFigure(new Point(0, y), false, false);
             context.LineTo(new Point(gw, y), true, false);
             if (ch*freq*scale < 2) break;  //??? NYI automatically calling InvalidateVisual on each GridPattern when the DiagramPanel.Scale changes
           }
         }
       }
     }
     return sg.Geometry;
   }
 }