Exemplo n.º 1
0
        internal void DrawMarker(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pRefPoint, SKPoint pMarkerPoint1, SKPoint pMarkerPoint2, SKPoint pMarkerPoint3)
        {
            float xDiff   = pMarkerPoint2.X - pMarkerPoint1.X;
            float yDiff   = pMarkerPoint2.Y - pMarkerPoint1.Y;
            float fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);

            xDiff = pMarkerPoint3.X - pMarkerPoint2.X;
            yDiff = pMarkerPoint3.Y - pMarkerPoint2.Y;
            float fAngle2 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);

            DrawMarker(svgMarker, pOwner, pRefPoint, (fAngle1 + fAngle2) / 2);
        }
Exemplo n.º 2
0
        internal SvgVisualElement?GetMarkerElement(SvgMarker svgMarker)
        {
            SvgVisualElement?markerElement = null;

            foreach (var child in svgMarker.Children)
            {
                if (child is SvgVisualElement svgVisualElement)
                {
                    markerElement = svgVisualElement;
                    break;
                }
            }

            return(markerElement);
        }
Exemplo n.º 3
0
        internal void DrawMarker(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pRefPoint, SKPoint pMarkerPoint1, SKPoint pMarkerPoint2, bool isStartMarker)
        {
            float fAngle1 = 0f;

            if (svgMarker.Orient.IsAuto)
            {
                float xDiff = pMarkerPoint2.X - pMarkerPoint1.X;
                float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y;
                fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                if (isStartMarker && svgMarker.Orient.IsAutoStartReverse)
                {
                    fAngle1 += 180;
                }
            }
            DrawMarker(svgMarker, pOwner, pRefPoint, fAngle1);
        }
Exemplo n.º 4
0
        void CreateArrowEnd()
        {
            SvgMarker arrowEnd = this.doc.AddMarker();

            arrowEnd.RefX         = $"{this.ToPx(ArrowEndSize)}";
            arrowEnd.RefY         = $"{this.ToPx(ArrowEndSize / 2)}";
            arrowEnd.MarkerWidth  = $"{this.ToPx(ArrowEndSize)}";
            arrowEnd.MarkerHeight = $"{this.ToPx(ArrowEndSize)}";
            arrowEnd.MarkerUnits  = "px";
            arrowEnd.Id           = ArrowEnd;

            SvgPolygon p = this.doc.AddPolygon(arrowEnd);

            p.Class  = "connector";
            p.Points = $"0 0 {this.ToPx(ArrowEndSize)} {this.ToPx(ArrowEndSize / 2)} 0 {this.ToPx(ArrowEndSize)}";
        }
Exemplo n.º 5
0
        void CreateArrowEnd()
        {
            SvgMarker arrowEnd = this.doc.AddMarker();

            arrowEnd.RefX         = $"{this.ToPx(ArrowEndSize)}";
            arrowEnd.RefY         = $"{this.ToPx(ArrowEndSize / 2)}";
            arrowEnd.MarkerWidth  = $"{this.ToPx(ArrowEndSize)}";
            arrowEnd.MarkerHeight = $"{this.ToPx(ArrowEndSize)}";
            arrowEnd.MarkerUnits  = "px";
            arrowEnd.Id           = ArrowEnd;

            SvgPolygon p = this.doc.AddPolygon(arrowEnd);

            p.Points      = $"0 0 {this.ToPx(ArrowEndSize)} {this.ToPx(ArrowEndSize / 2)} 0 {this.ToPx(ArrowEndSize)}";
            p.StrokeWidth = "0";
            p.Fill        = Color.Black;
            p.StrokeWidth = "0";
        }
Exemplo n.º 6
0
        public static void CreateMarker(this SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pRefPoint, SKPoint pMarkerPoint1, SKPoint pMarkerPoint2, SKPoint pMarkerPoint3, SKRect skOwnerBounds, ref List <Drawable>?markerDrawables, CompositeDisposable disposable)
        {
            float xDiff   = pMarkerPoint2.X - pMarkerPoint1.X;
            float yDiff   = pMarkerPoint2.Y - pMarkerPoint1.Y;
            float fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);

            xDiff = pMarkerPoint3.X - pMarkerPoint2.X;
            yDiff = pMarkerPoint3.Y - pMarkerPoint2.Y;
            float fAngle2 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);

            var markerDrawable = new MarkerDrawable(svgMarker, pOwner, pRefPoint, (fAngle1 + fAngle2) / 2, skOwnerBounds, null, null);

            if (markerDrawables == null)
            {
                markerDrawables = new List <Drawable>();
            }
            markerDrawables.Add(markerDrawable);
            disposable.Add(markerDrawable);
        }
Exemplo n.º 7
0
        void CreateArrowStart()
        {
            float radius = 0.125f;

            SvgMarker arrowStart = this.doc.AddMarker();

            arrowStart.RefX         = $"{this.ToPx(radius)}";
            arrowStart.RefY         = $"{this.ToPx(radius)}";
            arrowStart.MarkerWidth  = $"{this.ToPx(2 * radius)}";
            arrowStart.MarkerHeight = $"{this.ToPx(2 * radius)}";
            arrowStart.MarkerUnits  = "px";
            arrowStart.Id           = ArrowStart;

            SvgCircle c = this.doc.AddCircle(arrowStart);

            c.Class = "connector";
            c.CX    = $"{this.ToPx(radius)}";
            c.CY    = $"{this.ToPx(radius)}";
            c.R     = $"{this.ToPx(radius)}";
        }
Exemplo n.º 8
0
        void CreateArrowStart()
        {
            float radius = 0.125f;

            SvgMarker arrowStart = this.doc.AddMarker();

            arrowStart.RefX         = $"{this.ToPx(radius)}";
            arrowStart.RefY         = $"{this.ToPx(radius)}";
            arrowStart.MarkerWidth  = $"{this.ToPx(2 * radius)}";
            arrowStart.MarkerHeight = $"{this.ToPx(2 * radius)}";
            arrowStart.MarkerUnits  = "px";
            arrowStart.Id           = ArrowStart;

            SvgCircle c = this.doc.AddCircle(arrowStart);

            c.CX          = $"{this.ToPx(radius)}";
            c.CY          = $"{this.ToPx(radius)}";
            c.R           = $"{this.ToPx(radius)}";
            c.Fill        = Color.Black;
            c.StrokeWidth = "0";
        }
Exemplo n.º 9
0
        public static void CreateMarker(this SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pRefPoint, SKPoint pMarkerPoint1, SKPoint pMarkerPoint2, bool isStartMarker, SKRect skOwnerBounds, ref List <Drawable>?markerDrawables, CompositeDisposable disposable, Attributes ignoreAttributes = Attributes.None)
        {
            float fAngle1 = 0f;

            if (svgMarker.Orient.IsAuto)
            {
                float xDiff = pMarkerPoint2.X - pMarkerPoint1.X;
                float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y;
                fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI);
                if (isStartMarker && svgMarker.Orient.IsAutoStartReverse)
                {
                    fAngle1 += 180;
                }
            }

            var markerDrawable = new MarkerDrawable(svgMarker, pOwner, pRefPoint, fAngle1, skOwnerBounds, null, null, ignoreAttributes);

            if (markerDrawables == null)
            {
                markerDrawables = new List <Drawable>();
            }
            markerDrawables.Add(markerDrawable);
            disposable.Add(markerDrawable);
        }
Exemplo n.º 10
0
        public static MarkerDrawable Create(SvgMarker svgMarker, SvgVisualElement pOwner, Point pMarkerPoint, float fAngle, Rect skOwnerBounds, DrawableBase?parent, IAssetLoader assetLoader, Attributes ignoreAttributes = Attributes.None)
        {
            var drawable = new MarkerDrawable(assetLoader)
            {
                Element          = svgMarker,
                Parent           = parent,
                IgnoreAttributes = Attributes.Display | ignoreAttributes,
                IsDrawable       = true
            };

            if (!drawable.IsDrawable)
            {
                return(drawable);
            }

            var markerElement = drawable.GetMarkerElement(svgMarker);

            if (markerElement is null)
            {
                drawable.IsDrawable = false;
                return(drawable);
            }

            var skMarkerMatrix = Matrix.CreateIdentity();

            var skMatrixMarkerPoint = Matrix.CreateTranslation(pMarkerPoint.X, pMarkerPoint.Y);

            skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixMarkerPoint);

            var skMatrixAngle = Matrix.CreateRotationDegrees(svgMarker.Orient.IsAuto ? fAngle : svgMarker.Orient.Angle);

            skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixAngle);

            var strokeWidth = pOwner.StrokeWidth.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);

            var refX         = svgMarker.RefX.ToDeviceValue(UnitRenderingType.Horizontal, svgMarker, skOwnerBounds);
            var refY         = svgMarker.RefY.ToDeviceValue(UnitRenderingType.Vertical, svgMarker, skOwnerBounds);
            var markerWidth  = svgMarker.MarkerWidth.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);
            var markerHeight = svgMarker.MarkerHeight.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);
            var viewBoxToMarkerUnitsScaleX = 1f;
            var viewBoxToMarkerUnitsScaleY = 1f;

            switch (svgMarker.MarkerUnits)
            {
            case SvgMarkerUnits.StrokeWidth:
            {
                var skMatrixStrokeWidth = Matrix.CreateScale(strokeWidth, strokeWidth);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixStrokeWidth);

                var viewBoxWidth  = svgMarker.ViewBox.Width;
                var viewBoxHeight = svgMarker.ViewBox.Height;

                var scaleFactorWidth  = viewBoxWidth <= 0 ? 1 : markerWidth / viewBoxWidth;
                var scaleFactorHeight = viewBoxHeight <= 0 ? 1 : markerHeight / viewBoxHeight;

                viewBoxToMarkerUnitsScaleX = Math.Min(scaleFactorWidth, scaleFactorHeight);
                viewBoxToMarkerUnitsScaleY = Math.Min(scaleFactorWidth, scaleFactorHeight);

                var skMatrixTranslateRefXY = Matrix.CreateTranslation(-refX * viewBoxToMarkerUnitsScaleX, -refY * viewBoxToMarkerUnitsScaleY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixTranslateRefXY);

                var skMatrixScaleXY = Matrix.CreateScale(viewBoxToMarkerUnitsScaleX, viewBoxToMarkerUnitsScaleY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixScaleXY);
            }
            break;

            case SvgMarkerUnits.UserSpaceOnUse:
            {
                var skMatrixTranslateRefXY = Matrix.CreateTranslation(-refX, -refY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixTranslateRefXY);
            }
            break;
            }

            switch (svgMarker.Overflow)
            {
            case SvgOverflow.Auto:
            case SvgOverflow.Visible:
            case SvgOverflow.Inherit:
                break;

            default:
                drawable.MarkerClipRect = Rect.Create(
                    svgMarker.ViewBox.MinX,
                    svgMarker.ViewBox.MinY,
                    markerWidth / viewBoxToMarkerUnitsScaleX,
                    markerHeight / viewBoxToMarkerUnitsScaleY);
                break;
            }

            var markerElementDrawable = DrawableFactory.Create(markerElement, skOwnerBounds, drawable, assetLoader, Attributes.Display);

            if (markerElementDrawable is { })
Exemplo n.º 11
0
        public void TestArrowCodeCreation()
        {
            // Sample code from Issue 212. Thanks to podostro.
            const int width  = 50;
            const int height = 50;

            var document = new SvgDocument()
            {
                ID      = "svgMap",
                ViewBox = new SvgViewBox(0, 0, width, height)
            };

            var defsElement = new SvgDefinitionList()
            {
                ID = "defsMap"
            };

            document.Children.Add(defsElement);

            var groupElement = new SvgGroup()
            {
                ID = "gMap"
            };

            document.Children.Add(groupElement);

            var arrowPath = new SvgPath()
            {
                ID       = "pathMarkerArrow",
                Fill     = new SvgColourServer(Color.Black),
                PathData = SvgPathBuilder.Parse(@"M0,0 L4,2 L0,4 L1,2 z")
            };

            var arrowMarker = new SvgMarker()
            {
                ID           = "markerArrow",
                MarkerUnits  = SvgMarkerUnits.StrokeWidth,
                MarkerWidth  = 5,
                MarkerHeight = 5,
                RefX         = 3,
                RefY         = 2,
                Orient       = new SvgOrient()
                {
                    IsAuto = true
                },
                Children = { arrowPath }
            };

            defsElement.Children.Add(arrowMarker);

            var line = new SvgLine()
            {
                ID          = "lineLinkedPoint",
                StartX      = 0,
                StartY      = 15,
                EndX        = 35,
                EndY        = 35,
                Stroke      = new SvgColourServer(Color.Black),
                StrokeWidth = 3,
                MarkerEnd   = new Uri(string.Format("url(#{0})", arrowMarker.ID), UriKind.Relative)
            };

            groupElement.Children.Add(line);

            var svgXml = document.GetXML();
            var img    = document.Draw();

            var file = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            File.WriteAllText(file + ".svg", svgXml);
            img.Save(file + ".png");
            Debug.WriteLine(string.Format("Svg saved to '{0}'", file));

            Debugger.Break();

            // Remove
            var svg = new FileInfo(file + ".svg");

            if (svg.Exists)
            {
                svg.Delete();
            }
            var png = new FileInfo(file + ".png");

            if (png.Exists)
            {
                png.Delete();
            }
        }
Exemplo n.º 12
0
        public MarkerDrawable(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pMarkerPoint, float fAngle, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None)
            : base(svgMarker, root, parent)
        {
            IgnoreAttributes = Attributes.Display | ignoreAttributes;
            IsDrawable       = true;

            if (!IsDrawable)
            {
                return;
            }

            var markerElement = GetMarkerElement(svgMarker);

            if (markerElement == null)
            {
                IsDrawable = false;
                return;
            }

            var skMarkerMatrix = SKMatrix.MakeIdentity();

            var skMatrixMarkerPoint = SKMatrix.MakeTranslation(pMarkerPoint.X, pMarkerPoint.Y);

            skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixMarkerPoint);

            var skMatrixAngle = SKMatrix.MakeRotationDegrees(svgMarker.Orient.IsAuto ? fAngle : svgMarker.Orient.Angle);

            skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixAngle);

            var strokeWidth = pOwner.StrokeWidth.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);

            var   refX         = svgMarker.RefX.ToDeviceValue(UnitRenderingType.Horizontal, svgMarker, skOwnerBounds);
            var   refY         = svgMarker.RefY.ToDeviceValue(UnitRenderingType.Vertical, svgMarker, skOwnerBounds);
            float markerWidth  = svgMarker.MarkerWidth.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);
            float markerHeight = svgMarker.MarkerHeight.ToDeviceValue(UnitRenderingType.Other, svgMarker, skOwnerBounds);
            float viewBoxToMarkerUnitsScaleX = 1f;
            float viewBoxToMarkerUnitsScaleY = 1f;

            switch (svgMarker.MarkerUnits)
            {
            case SvgMarkerUnits.StrokeWidth:
            {
                var skMatrixStrokeWidth = SKMatrix.MakeScale(strokeWidth, strokeWidth);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixStrokeWidth);

                var viewBoxWidth  = svgMarker.ViewBox.Width;
                var viewBoxHeight = svgMarker.ViewBox.Height;

                var scaleFactorWidth  = (viewBoxWidth <= 0) ? 1 : (markerWidth / viewBoxWidth);
                var scaleFactorHeight = (viewBoxHeight <= 0) ? 1 : (markerHeight / viewBoxHeight);

                viewBoxToMarkerUnitsScaleX = Math.Min(scaleFactorWidth, scaleFactorHeight);
                viewBoxToMarkerUnitsScaleY = Math.Min(scaleFactorWidth, scaleFactorHeight);

                var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX * viewBoxToMarkerUnitsScaleX, -refY * viewBoxToMarkerUnitsScaleY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixTranslateRefXY);

                var skMatrixScaleXY = SKMatrix.MakeScale(viewBoxToMarkerUnitsScaleX, viewBoxToMarkerUnitsScaleY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixScaleXY);
            }
            break;

            case SvgMarkerUnits.UserSpaceOnUse:
            {
                var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX, -refY);
                skMarkerMatrix = skMarkerMatrix.PreConcat(skMatrixTranslateRefXY);
            }
            break;
            }

            switch (svgMarker.Overflow)
            {
            case SvgOverflow.Auto:
            case SvgOverflow.Visible:
            case SvgOverflow.Inherit:
                break;

            default:
                MarkerClipRect = SKRect.Create(
                    svgMarker.ViewBox.MinX,
                    svgMarker.ViewBox.MinY,
                    markerWidth / viewBoxToMarkerUnitsScaleX,
                    markerHeight / viewBoxToMarkerUnitsScaleY);
                break;
            }

            var drawable = DrawableFactory.Create(markerElement, skOwnerBounds, root, this, Attributes.Display);

            if (drawable != null)
            {
                MarkerElementDrawable = drawable;
                _disposable.Add(MarkerElementDrawable);
            }
            else
            {
                IsDrawable = false;
                return;
            }

            IsAntialias = SvgPaintingExtensions.IsAntialias(svgMarker);

            TransformedBounds = MarkerElementDrawable.TransformedBounds;

            Transform = SvgTransformsExtensions.ToSKMatrix(svgMarker.Transforms);
            Transform = Transform.PreConcat(skMarkerMatrix);

            Fill   = null;
            Stroke = null;

            // TODO: Transform _skBounds using _skMatrix.
            TransformedBounds = Transform.MapRect(TransformedBounds);
        }
Exemplo n.º 13
0
 public Marker(SvgMarker svgMarker)
 {
     matrix = SvgHelper.GetSKMatrix(svgMarker.Transforms);
 }
Exemplo n.º 14
0
        internal void DrawMarker(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pMarkerPoint, float fAngle)
        {
            var markerElement = GetMarkerElement(svgMarker);

            if (markerElement == null)
            {
                return;
            }

            var skMarkerMatrix = SKMatrix.MakeIdentity();

            var skMatrixMarkerPoint = SKMatrix.MakeTranslation(pMarkerPoint.X, pMarkerPoint.Y);

            SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixMarkerPoint);

            var skMatrixAngle = SKMatrix.MakeRotationDegrees(svgMarker.Orient.IsAuto ? fAngle : svgMarker.Orient.Angle);

            SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixAngle);

            var strokeWidth = pOwner.StrokeWidth.ToDeviceValue(null, UnitRenderingType.Other, svgMarker);

            var   refX         = svgMarker.RefX.ToDeviceValue(null, UnitRenderingType.Horizontal, svgMarker);
            var   refY         = svgMarker.RefY.ToDeviceValue(null, UnitRenderingType.Horizontal, svgMarker);
            float markerWidth  = svgMarker.MarkerWidth;
            float markerHeight = svgMarker.MarkerHeight;
            float viewBoxToMarkerUnitsScaleX = 1f;
            float viewBoxToMarkerUnitsScaleY = 1f;

            switch (svgMarker.MarkerUnits)
            {
            case SvgMarkerUnits.StrokeWidth:
            {
                var skMatrixStrokeWidth = SKMatrix.MakeScale(strokeWidth, strokeWidth);
                SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixStrokeWidth);

                var viewBoxWidth  = svgMarker.ViewBox.Width;
                var viewBoxHeight = svgMarker.ViewBox.Height;

                var scaleFactorWidth  = (viewBoxWidth <= 0) ? 1 : (markerWidth / viewBoxWidth);
                var scaleFactorHeight = (viewBoxHeight <= 0) ? 1 : (markerHeight / viewBoxHeight);

                viewBoxToMarkerUnitsScaleX = Math.Min(scaleFactorWidth, scaleFactorHeight);
                viewBoxToMarkerUnitsScaleY = Math.Min(scaleFactorWidth, scaleFactorHeight);

                var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX * viewBoxToMarkerUnitsScaleX, -refY * viewBoxToMarkerUnitsScaleY);
                SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixTranslateRefXY);

                var skMatrixScaleXY = SKMatrix.MakeScale(viewBoxToMarkerUnitsScaleX, viewBoxToMarkerUnitsScaleY);
                SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixScaleXY);
            }
            break;

            case SvgMarkerUnits.UserSpaceOnUse:
            {
                var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX, -refY);
                SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixTranslateRefXY);
            }
            break;
            }

            _skCanvas.Save();

            var skMatrix = SkiaUtil.GetSKMatrix(svgMarker.Transforms);

            SKMatrix.PreConcat(ref skMatrix, ref skMarkerMatrix);
            SetTransform(skMatrix);
            SetClipPath(svgMarker, _disposable);

            var skPaintOpacity = SetOpacity(svgMarker, _disposable);

            var skPaintFilter = SetFilter(svgMarker, _disposable);

            switch (svgMarker.Overflow)
            {
            case SvgOverflow.Auto:
            case SvgOverflow.Visible:
            case SvgOverflow.Inherit:
                break;

            default:
                var skClipRect = SKRect.Create(
                    svgMarker.ViewBox.MinX,
                    svgMarker.ViewBox.MinY,
                    markerWidth / viewBoxToMarkerUnitsScaleX,
                    markerHeight / viewBoxToMarkerUnitsScaleY);
                _skCanvas.ClipRect(skClipRect, SKClipOperation.Intersect);
                break;
            }

            Draw(markerElement, true);

            if (skPaintFilter != null)
            {
                _skCanvas.Restore();
            }

            if (skPaintOpacity != null)
            {
                _skCanvas.Restore();
            }

            _skCanvas.Restore();
        }
Exemplo n.º 15
0
        public static void MakeSVG(List <CapturePacket> packets, string fileName)
        {
            const int baselinestep       = 250;  // distance between vertical lines
            const int horizontalBase     = 130;  // upper range for the vertical lines
            const int unitBoxWidth       = 120;  // width of device box
            const int unitBoxHeight      = 40;   // height of device box
            const int firstarrowdistance = 50;   // vertical distance before the first sequence arrow
            const int maxboxwidth        = 1000; // maximum width of description textboxes

            var font = new Font("Calibri",
                                9); // SVG and C# have different ideas of what a fontsize is apparently, so we set this lower and hope for the best

            int baselinegen =
                -100;                                           // iterator for making the vertical lines, the first line does one step from this value
            int arrowgen = horizontalBase + firstarrowdistance; // iterator for making sequence arrows

            // iterate through the data and gather what we need into a little struct for convenience
            List <Sequence> list = GetSequences(packets, baselinestep, out var devices, ref baselinegen);

            // after all vertical lines have been placed, make one for the description boxes
            int descriptionBaseline = baselinegen + 50;

            var svg          = new SvgDocument();
            var groupDevices = new SvgGroup
            {
                FontFamily = "Calibri",
                FontSize   = 16
            };
            var groupArrows = new SvgGroup
            {
                ID          = "arrows",
                Stroke      = new SvgColourServer(Color.Black),
                StrokeWidth = 2
            };
            var groupArrowTexts = new SvgGroup
            {
                ID         = "arrowtexts",
                FontFamily = "Calibri",
                FontSize   = 11
            };
            var groupBaselines = new SvgGroup
            {
                ID              = "baselines",
                Stroke          = new SvgColourServer(Color.Black),
                StrokeWidth     = 2,
                StrokeDashArray = new SvgUnitCollection {
                    10, 10
                }
            };
            var groupDescriptionBoxes = new SvgGroup
            {
                ID          = "descriptionboxes",
                Fill        = new SvgColourServer(Color.Transparent),
                Stroke      = new SvgColourServer(Color.Black),
                StrokeWidth = 2
            };
            var groupDescriptionTexts = new SvgGroup
            {
                ID         = "descriptiontexts",
                FontFamily = "Calibri",
                FontSize   = 12
            };

            svg.Children.Add(groupDevices);
            svg.Children.Add(groupArrows);
            svg.Children.Add(groupArrowTexts);
            svg.Children.Add(groupBaselines);
            svg.Children.Add(groupDescriptionBoxes);
            svg.Children.Add(groupDescriptionTexts);

            var svgDefinitionList = new SvgDefinitionList();
            var svgMarker         = new SvgMarker
            {
                ID           = "arrow",
                MarkerWidth  = 10,
                MarkerHeight = 10,
                RefX         = 9,
                RefY         = 3,
                Orient       = new SvgOrient {
                    IsAuto = true
                },
                MarkerUnits = SvgMarkerUnits.StrokeWidth
            };
            var svgPath = new SvgPath
            {
                PathData = new SvgPathSegmentList
                {
                    new SvgMoveToSegment(new PointF(0, 0)),
                    new SvgLineSegment(new PointF(0, 0), new PointF(0, 6)),
                    new SvgLineSegment(new PointF(0, 0), new PointF(9, 3)),
                    new SvgClosePathSegment()
                },
                Fill = new SvgColourServer(Color.Black)
            };

            svgMarker.Children.Add(svgPath);
            svgDefinitionList.Children.Add(svgMarker);
            svg.Children.Add(svgDefinitionList);

            // make the device boxes
            foreach (KeyValuePair <IPAddress, int> device in devices)
            {
                groupDevices.Children.Add(new SvgRectangle
                {
                    Fill        = new SvgColourServer(Color.White),
                    Stroke      = new SvgColourServer(Color.Black),
                    StrokeWidth = 2,
                    X           = device.Value - unitBoxWidth / 2,
                    Y           = horizontalBase - unitBoxHeight,
                    Width       = unitBoxWidth,
                    Height      = unitBoxHeight
                });
                groupDevices.Children.Add(new SvgText
                {
                    Text   = device.Key.ToString(),
                    Stroke = new SvgColourServer(Color.Black),
                    X      = new SvgUnitCollection {
                        new SvgUnit(device.Value)
                    },
                    Y = new SvgUnitCollection {
                        new SvgUnit(horizontalBase - unitBoxHeight / 2)
                    },
                    TextAnchor = SvgTextAnchor.Middle
                });
            }


            foreach (Sequence sequence in list)
            {
                // get the x axis of the two devices we are relating
                int one = devices[sequence.From];
                int two = devices[sequence.To];


                groupArrows.Children.Add(new SvgLine
                {
                    StartX    = one,
                    StartY    = arrowgen,
                    EndX      = two,
                    EndY      = arrowgen,
                    MarkerEnd = new Uri("url(#arrow)", UriKind.Relative)
                });

                // get middle of arrow
                int right  = Math.Max(one, two);
                int left   = Math.Min(one, two);
                int middle = (right - left) / 2;
                middle = left + middle;
                groupArrowTexts.Children.Add(new SvgText
                {
                    Text = sequence.Name,
                    X    = new SvgUnitCollection {
                        new SvgUnit(middle)
                    },
                    Y = new SvgUnitCollection {
                        new SvgUnit(arrowgen - 2)
                    },
                    TextAnchor = SvgTextAnchor.Middle
                });


                var svgBoxText = new SvgText
                {
                    X = new SvgUnitCollection {
                        new SvgUnit(descriptionBaseline + 5)
                    },
                    Y = new SvgUnitCollection {
                        new SvgUnit(arrowgen - 12)
                    }
                };
                svgBoxText.Children.Add(new SvgTextSpan
                {
                    Text           = sequence.Time,
                    TextDecoration = SvgTextDecoration.Underline,
                    X = new SvgUnitCollection {
                        new SvgUnit(descriptionBaseline + 5)
                    },
                    Dy = new SvgUnitCollection {
                        new SvgUnit(SvgUnitType.Em, 1.2f)
                    }
                });

                int maxstrlen = TextRenderer.MeasureText(sequence.Time, font).Width;
                var lines     = 1;
                foreach (KeyValuePair <string, string> pair in sequence.Dic)
                {
                    var both = new SvgTextSpan
                    {
                        X = new SvgUnitCollection {
                            new SvgUnit(descriptionBaseline + 5)
                        },
                        Dy = new SvgUnitCollection {
                            new SvgUnit(SvgUnitType.Em, 1.2f)
                        }
                    };

                    string textKey   = pair.Key + ": ";
                    string textValue = Functions.RemoveInvalidXMLChars(pair.Value);

                    int strlen = TextRenderer.MeasureText(textKey + textValue, font).Width;

                    if (strlen > maxboxwidth)
                    {
                        // ooof
                        string tv1 = textValue;
                        var    tv2 = "";
                        while (TextRenderer.MeasureText(textKey + tv1, font).Width > maxboxwidth)
                        {
                            tv2 = tv1[tv1.Length - 1] + tv2;
                            tv1 = tv1.Substring(0, tv1.Length - 1);
                        }

                        var keySpan = new SvgTextSpan {
                            Text = textKey, FontWeight = SvgFontWeight.Bold
                        };
                        var valueSpan1 = new SvgTextSpan {
                            Text = tv1
                        };
                        var valueSpan2 = new SvgTextSpan
                        {
                            Text = tv2,
                            X    = new SvgUnitCollection {
                                new SvgUnit(descriptionBaseline + 5)
                            },
                            Dy = new SvgUnitCollection {
                                new SvgUnit(SvgUnitType.Em, 1.2f)
                            }
                        };
                        both.Children.Add(keySpan);
                        both.Children.Add(valueSpan1);
                        svgBoxText.Children.Add(both);

                        svgBoxText.Children.Add(valueSpan2);
                        lines += 2;
                    }
                    else
                    {
                        var keySpan = new SvgTextSpan {
                            Text = textKey, FontWeight = SvgFontWeight.Bold
                        };
                        var valueSpan = new SvgTextSpan {
                            Text = textValue
                        };
                        both.Children.Add(keySpan);
                        both.Children.Add(valueSpan);
                        svgBoxText.Children.Add(both);
                        lines++;
                    }


                    if (strlen > maxstrlen)
                    {
                        maxstrlen = strlen;
                    }
                }

                // box height calc, 30 margin + 14 per line. Then have 20 between box bottom and next arrow (at least)

                var boxheight = (int)(lines * font.Height * 1.02);


                // draw the box
                groupDescriptionBoxes.Children.Add(new SvgRectangle
                {
                    X      = descriptionBaseline,
                    Y      = arrowgen - 10,
                    Width  = maxstrlen,
                    Height = boxheight
                });

                // add text after box
                groupDescriptionTexts.Children.Add(svgBoxText);

                // setup next arrow
                arrowgen += boxheight + 30;
            }


            // finally, draw the baselines
            foreach (KeyValuePair <IPAddress, int> device in devices)
            {
                groupBaselines.Children.Add(new SvgLine
                {
                    StartX = device.Value,
                    StartY = horizontalBase,
                    EndX   = device.Value,
                    EndY   = arrowgen
                });
            }

            // now lets make SVG!!!
            svg.Width   = descriptionBaseline + maxboxwidth + 5;
            svg.Height  = arrowgen + 5;
            svg.ViewBox = new SvgViewBox(0, 0, descriptionBaseline + maxboxwidth + 5, arrowgen + 5);


            using (FileStream fileStream = File.Create(fileName))
            {
                svg.Write(fileStream);
            }
        }
Exemplo n.º 16
0
        public void TestArrowCodeCreation()
        {
            // Sample code from Issue 212. Thanks to podostro.
            const int width = 50;
            const int height = 50;

            var document = new SvgDocument()
            {
                ID = "svgMap",
                ViewBox = new SvgViewBox(0, 0, width, height)
            };

            var defsElement = new SvgDefinitionList() { ID = "defsMap" };
            document.Children.Add(defsElement);

            var groupElement = new SvgGroup() { ID = "gMap" };
            document.Children.Add(groupElement);

            var arrowPath = new SvgPath()
            {
                ID = "pathMarkerArrow",
                Fill = new SvgColourServer(Color.Black),
                PathData = SvgPathBuilder.Parse(@"M0,0 L4,2 L0,4 L1,2 z")
            };

            var arrowMarker = new SvgMarker()
            {
                ID = "markerArrow",
                MarkerUnits = SvgMarkerUnits.StrokeWidth,
                MarkerWidth = 5,
                MarkerHeight = 5,
                RefX = 3,
                RefY = 2,
                Orient = new SvgOrient() { IsAuto = true },
                Children = { arrowPath }
            };

            defsElement.Children.Add(arrowMarker);

            var line = new SvgLine()
            {
                ID = "lineLinkedPoint",
                StartX = 0,
                StartY = 15,
                EndX = 35,
                EndY = 35,
                Stroke = new SvgColourServer(Color.Black),
                StrokeWidth = 3,
                MarkerEnd = new Uri(string.Format("url(#{0})", arrowMarker.ID), UriKind.Relative)
            };

            groupElement.Children.Add(line);

            var svgXml = document.GetXML();
            var img = document.Draw();

            var file = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            File.WriteAllText(file + ".svg", svgXml);
            img.Save(file + ".png");
            Debug.WriteLine(string.Format("Svg saved to '{0}'", file));

            Debugger.Break();

            // Remove
            var svg = new FileInfo(file + ".svg");
            if (svg.Exists) svg.Delete();
            var png = new FileInfo(file + ".png");
            if (png.Exists) png.Delete();
        }