public bool Equals(ref OpenGLShapeInfo other)
        {
            if (ShapeType != other.ShapeType) return false;

            switch (ShapeType) {
            case OpenGLShapeType.Line:
                return Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < Tolerance && Math.Abs (C - other.C) < Tolerance;
            case OpenGLShapeType.Rect:
                if (Fill) {
                    return other.Fill && Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < Tolerance;
                }
                else {
                    return !other.Fill && Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < Tolerance && Math.Abs (C - other.C) < Tolerance;
                }
            case OpenGLShapeType.RoundedRect:
                if (Fill) {
                    return other.Fill && Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < Tolerance && Math.Abs (C - other.C) < Tolerance;
                }
                else {
                    return !other.Fill && Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < Tolerance && Math.Abs (C - other.C) < Tolerance && Math.Abs (D - other.D) < Tolerance;
                }
            case OpenGLShapeType.Oval:
                if (Fill) {
                    return other.Fill && Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < Tolerance;
                }
                else {
                    return !other.Fill && Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < Tolerance && Math.Abs (C - other.C) < Tolerance;
                }
            case OpenGLShapeType.Character:
                return Char == other.Char && Font.Size == other.Font.Size && Font.FontFamily == other.Font.FontFamily;
            case OpenGLShapeType.Polygon:
                if (Fill && !other.Fill) return false;
                if (!Fill && Math.Abs (A - other.A) >= Tolerance) return false;
                if (Poly.Points.Count != other.Poly.Points.Count) return false;
                for (var i = 1; i < Poly.Points.Count; i++) {
                    var dx = Poly.Points[i].X - Poly.Points[i - 1].X;
                    var odx = other.Poly.Points[i].X - other.Poly.Points[i - 1].X;
                    if (Math.Abs (dx - odx) >= Tolerance) return false;
                    var dy = Poly.Points[i].Y - Poly.Points[i - 1].Y;
                    var ody = other.Poly.Points[i].Y - other.Poly.Points[i - 1].Y;
                    if (Math.Abs (dy - ody) >= Tolerance) return false;
                }
                return true;
            case OpenGLShapeType.Arc:
                if (Fill && !other.Fill) return false;
                if (!Fill && Math.Abs (D - other.D) >= Tolerance) return false;
                return Math.Abs (A - other.A) < Tolerance && Math.Abs (B - other.B) < ArcAngleTolerance && Math.Abs (C - other.C) < ArcAngleTolerance;
            case OpenGLShapeType.Polyline:
                if (Math.Abs (A - other.A) >= Tolerance) return false;
                if (PolylineLength != other.PolylineLength) return false;
                for (var i = 1; i < PolylineLength; i++) {
                    var dx = PolylinePoints[i].X - PolylinePoints[i - 1].X;
                    var odx = other.PolylinePoints[i].X - other.PolylinePoints[i - 1].X;
                    if (Math.Abs (dx - odx) >= Tolerance) return false;
                    var dy = PolylinePoints[i].Y - PolylinePoints[i - 1].Y;
                    var ody = other.PolylinePoints[i].Y - other.PolylinePoints[i - 1].Y;
                    if (Math.Abs (dy - ody) >= Tolerance) return false;
                }
                return true;
            default:
                throw new NotImplementedException ();
            }
        }
        public static OpenGLShapeInfo ReadXml(System.Xml.XmlReader r)
        {
            var icult = System.Globalization.CultureInfo.InvariantCulture;

            var i = new OpenGLShapeInfo ();

            while (r.Read ()) {
                if (r.IsStartElement ("Info")) {
                    i.ShapeType = (OpenGLShapeType)Enum.Parse (typeof (OpenGLShapeType), r.GetAttribute ("ShapeType"));
                    i.A = float.Parse (r.GetAttribute ("A"), icult);
                    i.B = float.Parse (r.GetAttribute ("B"), icult);
                    i.C = float.Parse (r.GetAttribute ("C"), icult);
                    i.D = float.Parse (r.GetAttribute ("D"), icult);
                    i.Fill = r.GetAttribute ("Fill") == "true";
                    var ch = r.GetAttribute ("Char");
                    i.Char = string.IsNullOrEmpty (ch) ? (char)0 : ch[0];
                    var ff = r.GetAttribute ("FontFamily");
                    if (!string.IsNullOrWhiteSpace (ff)) {
                        var fw = r.GetAttribute ("FontWeight");
                        var fo = fw == "bold" ? FontOptions.Bold : FontOptions.None;
                        var fs = int.Parse (r.GetAttribute ("FontSize"), icult);
                        i.Font = new Font (ff, fo, fs);
                    }
                }
                else if (r.IsStartElement ("Polygon")) {
                    var parts = r.GetAttribute ("Points").Split (WS, StringSplitOptions.RemoveEmptyEntries);
                    var poly = new Polygon ();
                    for (var j = 0; j < parts.Length; j += 2) {
                        var p = new PointF (float.Parse (parts[j], icult), float.Parse (parts[j + 1], icult));
                        poly.AddPoint (p);
                    }
                    i.Poly = poly;
                }
                else if (r.IsStartElement ("Polyline")) {
                    var parts = r.GetAttribute ("Points").Split (WS, StringSplitOptions.RemoveEmptyEntries);
                    var poly = new List<PointF> ();
                    for (var j = 0; j < parts.Length; j += 2) {
                        var p = new PointF (float.Parse (parts[j], icult), float.Parse (parts[j + 1], icult));
                        poly.Add (p);
                    }
                    i.PolylinePoints = poly.ToArray ();
                    i.PolylineLength = i.PolylinePoints.Length;
                }
            }

            return i;
        }
        public OpenGLShape GetShape(ref OpenGLShapeInfo info)
        {
            //
            // Hopefully, we already have this shape
            //
            var ss = _shapesByType [(int)info.ShapeType];
            foreach (var s in ss) {
                if (s.Info.Equals (ref info)) {
                    return s;
                }
            }

            //
            // Uh oh, have to make it.
            //
            _needsSave = true;
            var shape = new OpenGLShape (info);
            ss.Add (shape);

            //
            // Find out its texture requirements
            //
            var r = shape.Info.GetTextureRequirements ();

            //
            // Try to find a texture that can meet those requirements
            //
            foreach (var t in _textures) {
                if (t.TryInsert (r)) {
                    break;
                }
            }

            //
            // If we couldn't find a texture that could take this reference,
            // we better get another texture
            //
            if (r.Texture == null) {
                //
                // Discover the largest texture we can handle.
                // It is the smaller of that supported by OpenGL
                // and whatever the renderer can handle.
                //
                var maxSize = 0;
                GL.GetInteger (All.MaxTextureSize, ref maxSize);
                maxSize = Math.Min (MaxTextureSize, maxSize);

                //
                // Create that texture if this shape will fit in it
                //
                if (r.Frame.Width <= maxSize && r.Frame.Height <= maxSize) {
                    var tex = CreateTexture (maxSize, maxSize);

                    tex.NeedsSave = true;
                    _textures.Add (tex);

                    tex.TryInsert (r);
                }
            }

            shape.TextureReference = r;

            return shape;
        }
        public OpenGLShape(System.Xml.XmlReader r, List<OpenGLTexture> textures)
        {
            while (r.Read ()) {
                if (r.IsStartElement ("Info")) {
                    Info = OpenGLShapeInfo.ReadXml (r.ReadSubtree ());
                }
                else if (r.IsStartElement ("Texture")) {
                    TextureReference = new OpenGLTextureReference (r.ReadSubtree (), textures);
                }
            }

            Rendered = true;
        }
 public OpenGLShape(OpenGLShapeInfo info)
 {
     Info = info;
     //
     // Clone the polyline array. This is a little hack so we can get
     // away with using the same array while drawing and avoid allocations.
     //
     if (info.PolylineLength > 0 && info.PolylinePoints != null) {
         var newPoints = new PointF[info.PolylineLength];
         Array.Copy (info.PolylinePoints, newPoints, newPoints.Length);
         Info.PolylinePoints = newPoints;
     }
 }
Example #6
0
 public OpenGLShape(OpenGLShapeInfo info)
 {
     Info = info;
 }