Exemple #1
0
        /// <summary>
        /// Draws multiple lines. Every two points define a separate line.
        /// </summary>
        /// <param name="points">The points.</param>
        /// <param name="style">The style.</param>
        public void Segments(IEnumerable <Vector2> points, string classes = null)
        {
            var sb = new StringBuilder(128);
            var it = points.GetEnumerator();

            while (it.MoveNext())
            {
                var first = it.Current;
                if (!it.MoveNext())
                {
                    return;
                }
                var second = it.Current;

                first  = CurrentTransform.Apply(first);
                second = CurrentTransform.Apply(second);
                _bounds.Expand(first);
                _bounds.Expand(second);
                if (sb.Length > 0)
                {
                    sb.Append(" ");
                }
                sb.Append($"M {Convert(first.X)} {Convert(first.Y)} L {Convert(second.X)} {Convert(second.Y)}");
            }

            var path = _document.CreateElement("path", Namespace);

            path.SetAttribute("d", sb.ToString());
            if (!string.IsNullOrWhiteSpace(classes))
            {
                path.SetAttribute("class", classes);
            }
            _current.AppendChild(path);
        }
Exemple #2
0
        /// <summary>
        /// Draws a polygon (a closed shape of straight lines).
        /// </summary>
        /// <param name="points">The points.</param>
        /// <param name="classes">The classes.</param>
        public void Polygon(IEnumerable <Vector2> points, string classes = null, string id = null)
        {
            var  sb      = new StringBuilder(32);
            bool isFirst = true;

            foreach (var point in points)
            {
                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    sb.Append(" ");
                }
                var pt = CurrentTransform.Apply(point);
                _bounds.Expand(pt.X, pt.Y);
                sb.Append($"{Convert(pt.X)},{Convert(pt.Y)}");
            }

            var poly = _document.CreateElement("polygon", Namespace);

            poly.SetAttribute("points", sb.ToString());
            if (!string.IsNullOrWhiteSpace(classes))
            {
                poly.SetAttribute("class", classes);
            }
            if (!string.IsNullOrWhiteSpace(id))
            {
                poly.SetAttribute("id", id);
            }

            _current.AppendChild(poly);
        }
Exemple #3
0
        /// <summary>
        /// Draws a line.
        /// </summary>
        /// <param name="start">The start.</param>
        /// <param name="end">The end.</param>
        /// <param name="style">The style.</param>
        public void Line(Vector2 start, Vector2 end, string classes = null, string id = null)
        {
            start = CurrentTransform.Apply(start);
            end   = CurrentTransform.Apply(end);

            // Expand the bounds
            _bounds.Expand(start.X, start.Y);
            _bounds.Expand(end.X, end.Y);

            var line = _document.CreateElement("line", Namespace);

            line.SetAttribute("x1", Convert(start.X));
            line.SetAttribute("y1", Convert(start.Y));
            line.SetAttribute("x2", Convert(end.X));
            line.SetAttribute("y2", Convert(end.Y));
            if (!string.IsNullOrWhiteSpace(classes))
            {
                line.SetAttribute("class", classes);
            }
            if (!string.IsNullOrWhiteSpace(id))
            {
                line.SetAttribute("id", id);
            }

            _current.AppendChild(line);
        }
Exemple #4
0
        /// <summary>
        /// Closed bezier curve.
        /// </summary>
        /// <param name="pointsAndHandles">The points and handles.</param>
        /// <param name="classes">The classes.</param>
        /// <param name="id">The identifier.</param>
        public void ClosedBezier(IEnumerable <Vector2> pointsAndHandles, string classes = null, string id = null)
        {
            var  sb      = new StringBuilder(128);
            var  it      = pointsAndHandles.GetEnumerator();
            bool isFirst = true;

            while (it.MoveNext())
            {
                if (isFirst)
                {
                    var m = CurrentTransform.Apply(it.Current);
                    sb.Append($"M{Convert(m.X)} {Convert(m.Y)} ");
                    _bounds.Expand(m);
                    isFirst = false;
                }
                else
                {
                    var h1 = CurrentTransform.Apply(it.Current);
                    if (!it.MoveNext())
                    {
                        break;
                    }
                    var h2 = CurrentTransform.Apply(it.Current);
                    if (!it.MoveNext())
                    {
                        break;
                    }
                    var end = CurrentTransform.Apply(it.Current);
                    sb.Append($"C{Convert(h1.X)} {Convert(h1.Y)}, {Convert(h2.X)} {Convert(h2.Y)}, {Convert(end.X)} {Convert(end.Y)} ");
                    _bounds.Expand(h1);
                    _bounds.Expand(h2);
                    _bounds.Expand(end);
                }
            }

            // Close the path
            sb.Append("Z");

            var path = _document.CreateElement("path", Namespace);

            path.SetAttribute("d", sb.ToString());
            if (!string.IsNullOrWhiteSpace(classes))
            {
                path.SetAttribute("class", classes);
            }
            if (!string.IsNullOrWhiteSpace(id))
            {
                path.SetAttribute("id", id);
            }
            _current.AppendChild(path);
        }
Exemple #5
0
        /// <summary>
        /// Draws a circle.
        /// </summary>
        /// <param name="position">The position.</param>
        /// <param name="radius">The radius.</param>
        /// <param name="style">The style.</param>
        public void Circle(Vector2 position, double radius, string classes = null, string id = null)
        {
            position = CurrentTransform.Apply(position);

            // Expand the bounds
            _bounds.Expand(position.X - radius, position.Y - radius);
            _bounds.Expand(position.X + radius, position.Y + radius);

            var circle = _document.CreateElement("circle", Namespace);

            circle.SetAttribute("cx", Convert(position.X));
            circle.SetAttribute("cy", Convert(position.Y));
            circle.SetAttribute("r", Convert(radius));
            if (!string.IsNullOrWhiteSpace(classes))
            {
                circle.SetAttribute("class", classes);
            }
            if (!string.IsNullOrWhiteSpace(id))
            {
                circle.SetAttribute("id", id);
            }

            _current.AppendChild(circle);
        }
Exemple #6
0
        /// <summary>
        /// Draws text.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="location">The location.</param>
        /// <param name="expand">The direction of the quadrant that the text can expand to.</param>
        /// <param name="classes">The classes.</param>
        public void Text(string value, Vector2 location, Vector2 expand, double fontSize = 4, double midLineFactor = 0.33, string classes = null, string id = null)
        {
            location = CurrentTransform.Apply(location);
            expand   = CurrentTransform.ApplyDirection(expand);

            if (string.IsNullOrWhiteSpace(value))
            {
                return;
            }
            var lines = value.Split(new char[] { '\r', '\n', '\\' });
            var width = 0.0;

            foreach (var l in lines)
            {
                var w = 0.0;
                foreach (var c in l)
                {
                    w += char.IsLower(c) ? LowerCharacterWidth : UpperCharacterWidth;
                }
                width = Math.Max(width, w);
            }
            var height = lines.Length * LineHeight;

            // Create the text element
            var text = _document.CreateElement("text", Namespace);

            // Expand the X-direction
            if (expand.X.IsZero())
            {
                text.SetAttribute("text-anchor", "middle");
                _bounds.Expand(location - new Vector2(width / 2, 0));
                _bounds.Expand(location + new Vector2(width / 2, 0));
            }
            else if (expand.X > 0)
            {
                text.SetAttribute("text-anchor", "start");
                _bounds.Expand(location);
                _bounds.Expand(location + new Vector2(width, 0));
            }
            else
            {
                text.SetAttribute("text-anchor", "end");
                _bounds.Expand(location - new Vector2(width, 0));
                _bounds.Expand(location);
            }

            // Draw the text with multiple lines
            if (expand.Y.IsZero())
            {
                _bounds.Expand(location - new Vector2(0, LineHeight * lines.Length / 2));
                _bounds.Expand(location + new Vector2(0, LineHeight * lines.Length / 2));

                // Center everything
                var dy = -(height - LineHeight) * 0.5;
                foreach (var l in lines)
                {
                    var tspan = _document.CreateElement("tspan", Namespace);
                    tspan.InnerText = l;
                    tspan.SetAttribute("y", Convert(location.Y + dy + fontSize * midLineFactor));
                    tspan.SetAttribute("x", Convert(location.X));
                    text.AppendChild(tspan);
                    dy += LineHeight;
                }
            }
            else if (expand.Y > 0)
            {
                _bounds.Expand(location);
                _bounds.Expand(location + new Vector2(0, LineHeight * lines.Length));

                // Make sure everything is below
                double dy = 0;
                foreach (var l in lines)
                {
                    var tspan = _document.CreateElement("tspan", Namespace);
                    tspan.InnerText = l;
                    tspan.SetAttribute("y", Convert(location.Y + dy + fontSize));
                    tspan.SetAttribute("x", Convert(location.X));
                    text.AppendChild(tspan);
                    dy += LineHeight;
                }
            }
            else
            {
                _bounds.Expand(location - new Vector2(0, LineHeight * lines.Length));
                _bounds.Expand(location);

                // Make sure everything is above
                double dy = -height + LineHeight;
                foreach (var l in lines)
                {
                    var tspan = _document.CreateElement("tspan", Namespace);
                    tspan.InnerText = l;
                    tspan.SetAttribute("y", Convert(location.Y + dy));
                    tspan.SetAttribute("x", Convert(location.X));
                    text.AppendChild(tspan);
                    dy += LineHeight;
                }
            }

            text.SetAttribute("x", Convert(location.X));
            text.SetAttribute("y", Convert(location.Y));
            text.SetAttribute("font-size", $"{Convert(fontSize)}pt");

            if (!string.IsNullOrWhiteSpace(classes))
            {
                text.SetAttribute("class", classes);
            }
            if (!string.IsNullOrWhiteSpace(id))
            {
                text.SetAttribute("id", id);
            }
            _current.AppendChild(text);
        }
Exemple #7
0
        /// <summary>
        /// Draws a smooth bezier curve.
        /// </summary>
        /// <param name="points">The points.</param>
        /// <param name="classes">The classes.</param>
        public void SmoothBezier(IEnumerable <Vector2> points, string classes = null, string id = null)
        {
            var     sb      = new StringBuilder(128);
            var     it      = points.GetEnumerator();
            bool    isFirst = true;
            Vector2 end;

            while (it.MoveNext())
            {
                if (isFirst)
                {
                    Vector2 first = CurrentTransform.Apply(it.Current);
                    if (!it.MoveNext())
                    {
                        return;
                    }

                    // Get the handles
                    var handle1 = CurrentTransform.Apply(it.Current);
                    if (!it.MoveNext())
                    {
                        return;
                    }
                    var handle2 = CurrentTransform.Apply(it.Current);
                    if (!it.MoveNext())
                    {
                        return;
                    }
                    end = CurrentTransform.Apply(it.Current);

                    // Expand bounds
                    _bounds.Expand(first);
                    _bounds.Expand(handle1);
                    _bounds.Expand(handle2);
                    _bounds.Expand(end);

                    // Add the data
                    sb.Append($"M{Convert(first.X)} {Convert(first.Y)} ");
                    sb.Append($"C{Convert(handle1.X)} {Convert(handle1.Y)}, ");
                    sb.Append($"{Convert(handle2.X)} {Convert(handle2.Y)}, ");
                    sb.Append($"{Convert(end.X)} {Convert(end.Y)}");

                    isFirst = false;
                }
                else
                {
                    var handle = CurrentTransform.Apply(it.Current);
                    if (!it.MoveNext())
                    {
                        return;
                    }
                    end = CurrentTransform.Apply(it.Current);

                    _bounds.Expand(handle);
                    _bounds.Expand(end);

                    // Add the data
                    sb.Append($" S{Convert(handle.X)} {Convert(handle.Y)} ");
                    sb.Append($"{Convert(end.X)} {Convert(end.Y)}");
                }
            }

            var path = _document.CreateElement("path", Namespace);

            path.SetAttribute("d", sb.ToString());
            if (!string.IsNullOrWhiteSpace(classes))
            {
                path.SetAttribute("class", classes);
            }
            if (!string.IsNullOrWhiteSpace(id))
            {
                path.SetAttribute("id", id);
            }
            _current.AppendChild(path);
        }