Beispiel #1
0
        void PathTest()
        {
            var pathSin = new GraphicsPath();
            var pathCos = new GraphicsPath();

            for (int i = 0; i < 48; i++)
            {
                if (i == 0)
                {
                    pathSin.MoveTo(0, 120 + (int)(Math.Sin(i * 10 * Math.PI / 180) * 100));
                    pathCos.MoveTo(0, 120 + (int)(Math.Cos(i * 10 * Math.PI / 180) * 100));
                    continue;
                }

                pathSin.LineTo(i * 5, 120 + (int)(Math.Sin(i * 10 * Math.PI / 180) * 100));
                pathCos.LineTo(i * 5, 120 + (int)(Math.Cos(i * 10 * Math.PI / 180) * 100));
            }

            graphics.Clear();

            graphics.Stroke = 3;
            graphics.DrawLine(0, 120, 240, 120, Color.White);
            graphics.DrawPath(pathSin, Color.Cyan);
            graphics.DrawPath(pathCos, Color.LawnGreen);

            graphics.Show();
        }
Beispiel #2
0
 void MoveTo(double x, double y, bool rel)          // M, m
 {
     if (rel)
     {
         m_storage.RelToAbs(ref x, ref y);
     }
     m_storage.MoveTo(x, y);
 }
Beispiel #3
0
        GraphicsPath CreatePath()
        {
            var path = new GraphicsPath();

            path.MoveTo(new Point(10, 10));
            path.LineTo(new Point(20, 90));
            path.LineTo(new Point(10, 60));
            path.LineTo(new Point(90, 80));
            path.LineTo(new Point(60, 30));
            return(path);
        }
Beispiel #4
0
        private void PaintCurve(double[] points, Color col, Graphics g)
        {
            float w = Width / (points.Length - 1f);
            float h = Height - 1;

            var path = new GraphicsPath();

            path.MoveTo(0, h);
            for (int i = 1; i < points.Length; i++)
            {
                path.LineTo(i * w, (float)(h - (points[i] * h)));
            }
            g.DrawPath(col, path);
        }
Beispiel #5
0
        public void Render(Graphics g, Train train)
        {
            var style = new TrainStyle(train, attrs);

            if (!style.CalcedShow)
            {
                return;
            }

            var ardps = train.GetArrDeps();
            var dir   = GetTrainDirection(train);

            using (var pen = new Pen((Color)style.CalcedColor, style.CalcedWidth)
            {
                DashStyle = ds.ParseDashstyle(style.CalcedLineStyle)
            })
                using (var brush = new SolidBrush((Color)style.CalcedColor))
                {
                    List <PointF> points = new List <PointF>();
                    bool          hadFirstArrival = false, hadLastDeparture = false, isFirst = true;
                    var           stas = dir ? Enumerable.Reverse(stations) : stations;

                    //TODO: Those helpers are ugly in this part of the code...
                    // Render helpers
                    float GetTimeY(TimeSpan time) => margin.Top + ((time - startTime).GetMinutes() * attrs.HeightPerHour / 60f);

                    PointF?GetGutterPoint(bool arrival, StationX sx, TimeSpan time)
                    {
                        if (time == default)
                        {
                            return(null);
                        }
                        var x = arrival ^ dir ? sx.Left : sx.Right;

                        return(new PointF(margin.Left + x, GetTimeY(time)));
                    }

                    PointF?GetInternalPoint(StationX sx, TimeSpan time, string track)
                    {
                        if (time == default || track == null || !sx.TrackOffsets.TryGetValue(track, out float x))
                        {
                            return(null);
                        }
                        return(new PointF(margin.Left + x, GetTimeY(time)));
                    }

                    void MaybeAddPoint(PointF?point)
                    {
                        if (point.HasValue)
                        {
                            points.Add(point.Value);
                        }
                    }

                    foreach (var sta in stas)
                    {
                        if (!ardps.ContainsKey(sta))
                        {
                            continue;
                        }
                        var ardp = ardps[sta];

                        if (!ardp.HasMinOneTimeSet)
                        {
                            continue;
                        }

                        MaybeAddPoint(GetGutterPoint(true, stationOffsets[sta], ardp.Arrival));
                        MaybeAddPoint(GetInternalPoint(stationOffsets[sta], ardp.Arrival, ardp.ArrivalTrack));

                        foreach (var shunt in ardp.ShuntMoves)
                        {
                            MaybeAddPoint(GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.SourceTrack));
                            MaybeAddPoint(GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.TargetTrack));
                        }

                        MaybeAddPoint(GetInternalPoint(stationOffsets[sta], ardp.Departure, ardp.DepartureTrack));
                        MaybeAddPoint(GetGutterPoint(false, stationOffsets[sta], ardp.Departure));

                        hadLastDeparture = ardp.Departure != default;
                        if (isFirst)
                        {
                            hadFirstArrival = ardp.Arrival != default;
                        }
                        isFirst = false;
                    }

                    // Halbe Linien bei Abfahrten / Ankünften ohne Gegenstelle
                    var hly = !dir ? 20 : -20;
                    if (hadLastDeparture)
                    {
                        points.Add(points.Last() + new Size(50, hly));
                    }
                    if (hadFirstArrival)
                    {
                        points.Insert(0, points.First() - new Size(50, hly));
                    }

                    // Verbindung zum Folgezug
                    var transition = tt.GetTransition(train);
                    if (transition != null && !hadLastDeparture && attrs.StationLines != StationLineStyle.None)
                    {
                        var lastStaOfFirst = GetSortedStations(train)?.LastOrDefault();
                        var firstStaOfNext = GetSortedStations(transition)?.FirstOrDefault();

                        if (lastStaOfFirst == firstStaOfNext)
                        {
                            var departure = transition.GetArrDep(firstStaOfNext).Departure;
                            points.Add(new PointF(points.Last().X, GetTimeY(departure)));
                        }
                    }

                    using (var p = new GraphicsPath())
                    {
                        for (int i = 0; i < points.Count; i += 1)
                        {
                            if (points.Count <= i + 1)
                            {
                                continue;
                            }

                            var isStationLine = (int)points[i].X == (int)points[i + 1].X;
                            if (isStationLine)
                            {
                                var preX         = i > 0 ? points[i - 1].X : 0;
                                var postX        = i < points.Count - 2 ? points[i + 2].X : 0;
                                var x            = points[i].X;
                                var isTransition = isStationLine && (points.Count == i + 2 || Math.Sign(preX - x) == Math.Sign(postX - x));

                                float bezierFactor = !isTransition ?
                                                     ((preX < postX) ? -1 : 1) : // preX < postX --> TrainDirection.ti
                                                     Math.Sign(preX - x);        // Bei Transitions
                                if (isTransition)
                                {
                                    bezierFactor *= 0.5f;
                                }
                                var bezierOffset  = new SizeF(bezierFactor * 14, (points[i + 1].Y - points[i].Y) / -4.0f);
                                var bezierOffsetT = new SizeF(bezierOffset.Width, -bezierOffset.Height);

                                switch (attrs.StationLines)
                                {
                                case StationLineStyle.None:
                                    p.MoveTo(points[i + 1]);
                                    break;

                                case StationLineStyle.Normal:
                                    p.AddLine(points[i], points[i + 1]);
                                    break;

                                case StationLineStyle.Cubic:
                                    var control2 = points[i + 1] + (!isTransition ? bezierOffset : -bezierOffsetT);
                                    p.AddBezier(points[i], points[i] - bezierOffset, control2, points[i + 1]);
                                    break;
                                }
                            }
                            else
                            {
                                p.AddLine(points[i], points[i + 1]); // Normale Zuglinie
                            }
                            if (points[i].X == points[i + 1].X || points[i].Y == points[i + 1].Y)
                            {
                                continue;
                            }
                            // Zugnummern zeichnen
                            var trainFont = (Font)attrs.TrainFont;

                            var     size = g.MeasureString(trainFont, train.TName);
                            float[] ys   = new[] { points[i].Y, points[i + 1].Y };
                            float[] xs   = new[] { points[i].X, points[i + 1].X };
                            float   ty   = ys.Min() + (ys.Max() - ys.Min()) / 2 - (size.Height / 2);
                            float   tx   = xs.Min() + (xs.Max() - xs.Min()) / 2;

                            float angle = CalcAngle(ys, xs, train);
                            g.SaveTransform();
                            g.TranslateTransform(tx, ty);
                            g.RotateTransform(-angle);
                            g.DrawText(trainFont, brush, -(size.Width / 2), -(size.Height / 2), train.TName);
                            g.RestoreTransform();
                        }
                        g.DrawPath(pen, p);
                    }
                }
        }
Beispiel #6
0
        GraphicsPath CreatePath()
        {
            var newPath = new GraphicsPath();
            var start   = StartFigures;
            var close   = CloseFigures;

            // connected segments

            newPath.MoveTo(10, 10);
            newPath.LineTo(20, 90);
            newPath.LineTo(10, 60);
            newPath.LineTo(90, 80);
            newPath.LineTo(60, 30);
            if (close && start)
            {
                newPath.CloseFigure();
            }

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddArc(100, 0, 100, 50, 200, -160);
            if (close && start)
            {
                newPath.CloseFigure();
            }

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddBezier(new PointF(200, 10), new PointF(285, 20), new PointF(210, 85), new PointF(300, 90));
            if (close && start)
            {
                newPath.CloseFigure();
            }

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddCurve(new PointF(310, 90), new PointF(390, 90), new PointF(390, 10), new PointF(310, 10));
            if (close && start)
            {
                newPath.CloseFigure();
            }

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddLine(410, 10, 410, 90);
            if (close && start)
            {
                newPath.CloseFigure();
            }

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddLines(new PointF(420, 10), new PointF(420, 90));
            if (close && start)
            {
                newPath.CloseFigure();
            }

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddLines(new PointF(430, 10), new PointF(430, 90));
            if (close)
            {
                newPath.CloseFigure();
            }

            // separate segments

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddEllipse(100, 100, 100, 45);
            if (close)
            {
                newPath.CloseFigure();
            }

            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddRectangle(10, 110, 80, 80);
            if (close)
            {
                newPath.CloseFigure();
            }

            // at the end, draw a line so we can potentially connect to parent path
            if (start)
            {
                newPath.StartFigure();
            }
            newPath.AddLines(new PointF(440, 10), new PointF(440, 90));
            if (close)
            {
                newPath.CloseFigure();
            }

            return(newPath);
        }
Beispiel #7
0
        private void LoadDocument()
        {
            //Create a new document
            Document doc = new Document();

            //Add a page to the document
            doc.Pages.Add(new Page(4000, 2600));

            //Set the page's background
            doc.Pages.Last().Background = Colour.FromRgba(35, 127, 255, 0.05);

            //Obtain the page's graphics object
            Graphics gpr = doc.Pages.Last().Graphics;

            //Text samples using default fonts
            //To use a custom font in TTF format, supply the path to the font's TTF file to the FontFamily(string) constructor
            gpr.FillText(200, 200, "Times-Roman", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.TimesRoman), 120), Colour.FromRgb(0, 0, 0));
            gpr.FillText(200, 340, "Times-Bold", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.TimesBold), 120), Colour.FromRgb(127, 127, 127));
            gpr.FillText(200, 480, "Times-Italic", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.TimesItalic), 120), Colour.FromRgb(136, 0, 21));
            gpr.FillText(200, 620, "Times-BoldItalic", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.TimesBoldItalic), 120), Colour.FromRgb(237, 28, 36));

            gpr.FillText(200, 860, "Helvetica", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 120), Colour.FromRgb(255, 174, 201));
            gpr.FillText(200, 1000, "Helvetica-Bold", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBold), 120), Colour.FromRgb(255, 127, 39));
            gpr.FillText(200, 1140, "Helvetica-Oblique", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaOblique), 120), Colour.FromRgb(255, 242, 0));
            gpr.FillText(200, 1280, "Helvetica-BoldOblique", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBoldOblique), 120), Colour.FromRgb(181, 230, 29));

            gpr.FillText(200, 1520, "Courier", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Courier), 120), Colour.FromRgb(34, 177, 76));
            gpr.FillText(200, 1660, "Courier-Bold", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.CourierBold), 120), Colour.FromRgb(0, 162, 232));
            gpr.FillText(200, 1800, "Courier-Oblique", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.CourierOblique), 120), Colour.FromRgb(112, 146, 190));
            gpr.FillText(200, 1940, "Courier-BoldOblique", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.CourierBoldOblique), 120), Colour.FromRgb(63, 72, 204));

            gpr.FillText(200, 2180, "Σψμβολ", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Symbol), 120), Colour.FromRgb(163, 73, 204));
            gpr.FillText(200, 2320, "✺❁❐❆✤❉■❇❂❁▼▲", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.ZapfDingbats), 120), Colour.FromRgb(200, 191, 231));


            //Text metrics sample
            string testString = "VectSharp";
            Font   timesBI    = new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.TimesBoldItalic), 240);

            Font.DetailedFontMetrics metrics = timesBI.MeasureTextAdvanced(testString);
            gpr.FillText(2000, 500, testString, timesBI, Colour.FromRgb(0, 0, 0), textBaseline: TextBaselines.Baseline);

            //Text baseline
            gpr.StrokePath(new GraphicsPath().MoveTo(1900, 500).LineTo(2050 + metrics.Width, 500), Colour.FromRgb(237, 28, 36), lineWidth: 5);
            gpr.FillText(1880 - gpr.MeasureText("Baseline", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50)).Width, 500, "Baseline", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(237, 28, 36), textBaseline: TextBaselines.Middle);

            //Font ascent and descent
            gpr.StrokePath(new GraphicsPath().MoveTo(1900, 500 - timesBI.Ascent).LineTo(2100 + metrics.Width, 500 - timesBI.Ascent), Colour.FromRgb(255, 127, 39), lineWidth: 5);
            gpr.FillText(2120 + metrics.Width, 500 - timesBI.Ascent, "Ascent", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(255, 127, 39), textBaseline: TextBaselines.Middle);

            gpr.StrokePath(new GraphicsPath().MoveTo(1900, 500 - timesBI.Descent).LineTo(2100 + metrics.Width, 500 - timesBI.Descent), Colour.FromRgb(255, 127, 39), lineWidth: 5);
            gpr.FillText(2120 + metrics.Width, 500 - timesBI.Descent, "Descent", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(255, 127, 39), textBaseline: TextBaselines.Middle);


            //Text top and bottom
            gpr.StrokePath(new GraphicsPath().MoveTo(1900, 500 - metrics.Top).LineTo(2050 + metrics.Width, 500 - metrics.Top), Colour.FromRgb(0, 162, 232), lineWidth: 5);
            gpr.FillText(1880 - gpr.MeasureText("Top", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50)).Width, 500 - metrics.Top, "Top", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(0, 162, 232), textBaseline: TextBaselines.Middle);

            gpr.StrokePath(new GraphicsPath().MoveTo(1900, 500 - metrics.Bottom).LineTo(2050 + metrics.Width, 500 - metrics.Bottom), Colour.FromRgb(0, 162, 232), lineWidth: 5);
            gpr.FillText(1880 - gpr.MeasureText("Bottom", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50)).Width, 500 - metrics.Bottom, "Bottom", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(0, 162, 232), textBaseline: TextBaselines.Middle);

            gpr.StrokePath(new GraphicsPath().MoveTo(2065 + metrics.Width, 520 - metrics.Top).LineTo(2075 + metrics.Width, 500 - metrics.Top).LineTo(2085 + metrics.Width, 520 - metrics.Top).MoveTo(2075 + metrics.Width, 500 - metrics.Top).LineTo(2075 + metrics.Width, 500 - metrics.Bottom).MoveTo(2065 + metrics.Width, 480 - metrics.Bottom).LineTo(2075 + metrics.Width, 500 - metrics.Bottom).LineTo(2085 + metrics.Width, 480 - metrics.Bottom), Colour.FromRgb(0, 162, 232), lineWidth: 5);

            //Text width
            gpr.StrokePath(new GraphicsPath().MoveTo(2000, 425 - timesBI.Ascent).LineTo(2000, 550 - timesBI.Descent).MoveTo(2000 + metrics.Width, 425 - timesBI.Ascent).LineTo(2000 + metrics.Width, 550 - timesBI.Descent), Colour.FromRgb(63, 72, 204), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2020, 390 - timesBI.Ascent).LineTo(2000, 400 - timesBI.Ascent).LineTo(2020, 410 - timesBI.Ascent).MoveTo(2000, 400 - timesBI.Ascent).LineTo(2000 + metrics.Width, 400 - timesBI.Ascent).MoveTo(1980 + metrics.Width, 390 - timesBI.Ascent).LineTo(2000 + metrics.Width, 400 - timesBI.Ascent).LineTo(1980 + metrics.Width, 410 - timesBI.Ascent), Colour.FromRgb(63, 72, 204), lineWidth: 5);
            gpr.FillText(2000 + metrics.Width / 2 - gpr.MeasureText("Width", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50)).Width / 2, 380 - timesBI.Ascent, "Width", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(63, 72, 204), textBaseline: TextBaselines.Bottom);

            //Left- and right-side bearing
            gpr.StrokePath(new GraphicsPath().MoveTo(2000 - metrics.LeftSideBearing, 450 - timesBI.Ascent).LineTo(2000 - metrics.LeftSideBearing, 550 - timesBI.Descent).MoveTo(2000 + metrics.Width + metrics.RightSideBearing, 450 - timesBI.Ascent).LineTo(2000 + metrics.Width + metrics.RightSideBearing, 550 - timesBI.Descent), Colour.FromRgb(163, 73, 204), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2000, 565 - timesBI.Descent).LineTo(2000, 585 - timesBI.Descent).MoveTo(2000, 575 - timesBI.Descent).LineTo(2000 - metrics.LeftSideBearing, 575 - timesBI.Descent).MoveTo(2000 - metrics.LeftSideBearing, 565 - timesBI.Descent).LineTo(2000 - metrics.LeftSideBearing, 585 - timesBI.Descent), Colour.FromRgb(163, 73, 204), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2000 + metrics.Width + metrics.RightSideBearing, 565 - timesBI.Descent).LineTo(2000 + metrics.Width + metrics.RightSideBearing, 585 - timesBI.Descent).MoveTo(2000 + metrics.Width + metrics.RightSideBearing, 575 - timesBI.Descent).LineTo(2000 + metrics.Width, 575 - timesBI.Descent).MoveTo(2000 + metrics.Width, 565 - timesBI.Descent).LineTo(2000 + metrics.Width, 585 - timesBI.Descent), Colour.FromRgb(163, 73, 204), lineWidth: 5);

            gpr.FillText(2000, 600 - timesBI.Descent, "Left-side bearing", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(163, 73, 164));
            gpr.FillText(2000 + metrics.Width - gpr.MeasureText("Right-side bearing", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50)).Width, 600 - timesBI.Descent, "Right-side bearing", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 50), Colour.FromRgb(163, 73, 164));



            //Text metrics sample #2
            Font biggerTimes = new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.TimesBoldItalic), 300);

            Font.DetailedFontMetrics fMetrics = biggerTimes.MeasureTextAdvanced("f");
            Font.DetailedFontMetrics qMetrics = biggerTimes.MeasureTextAdvanced("q");

            gpr.StrokePath(new GraphicsPath().MoveTo(2050, 1200).LineTo(2750 + qMetrics.Width, 1200), Colour.FromRgb(237, 28, 36), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2050, 1200 - biggerTimes.Ascent).LineTo(2750 + qMetrics.Width, 1200 - biggerTimes.Ascent), Colour.FromRgb(255, 127, 39), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2050, 1200 - biggerTimes.Descent).LineTo(2750 + qMetrics.Width, 1200 - biggerTimes.Descent), Colour.FromRgb(255, 127, 39), lineWidth: 5);

            gpr.StrokePath(new GraphicsPath().MoveTo(2050, 1200 - fMetrics.Top).LineTo(2150 + fMetrics.Width, 1200 - fMetrics.Top), Colour.FromRgb(0, 162, 232), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2050, 1200 - fMetrics.Bottom).LineTo(2150 + fMetrics.Width, 1200 - fMetrics.Bottom), Colour.FromRgb(0, 162, 232), lineWidth: 5);

            gpr.StrokePath(new GraphicsPath().MoveTo(2650, 1200 - qMetrics.Top).LineTo(2750 + qMetrics.Width, 1200 - qMetrics.Top), Colour.FromRgb(0, 162, 232), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2650, 1200 - qMetrics.Bottom).LineTo(2750 + qMetrics.Width, 1200 - qMetrics.Bottom), Colour.FromRgb(0, 162, 232), lineWidth: 5);

            gpr.StrokePath(new GraphicsPath().MoveTo(2100, 1150 - biggerTimes.Ascent).LineTo(2100, 1250 - biggerTimes.Descent), Colour.FromRgb(63, 72, 204), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2100 + fMetrics.Width, 1150 - biggerTimes.Ascent).LineTo(2100 + fMetrics.Width, 1250 - biggerTimes.Descent), Colour.FromRgb(63, 72, 204), lineWidth: 5);

            gpr.StrokePath(new GraphicsPath().MoveTo(2700, 1150 - biggerTimes.Ascent).LineTo(2700, 1250 - biggerTimes.Descent), Colour.FromRgb(63, 72, 204), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2700 + qMetrics.Width, 1150 - biggerTimes.Ascent).LineTo(2700 + qMetrics.Width, 1250 - biggerTimes.Descent), Colour.FromRgb(63, 72, 204), lineWidth: 5);

            gpr.StrokePath(new GraphicsPath().MoveTo(2100 - fMetrics.LeftSideBearing, 1150 - biggerTimes.Ascent).LineTo(2100 - fMetrics.LeftSideBearing, 1250 - biggerTimes.Descent), Colour.FromRgb(163, 73, 164), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2100 + fMetrics.Width + fMetrics.RightSideBearing, 1150 - biggerTimes.Ascent).LineTo(2100 + fMetrics.Width + fMetrics.RightSideBearing, 1250 - biggerTimes.Descent), Colour.FromRgb(163, 73, 164), lineWidth: 5);

            gpr.StrokePath(new GraphicsPath().MoveTo(2700 - qMetrics.LeftSideBearing, 1150 - biggerTimes.Ascent).LineTo(2700 - qMetrics.LeftSideBearing, 1250 - biggerTimes.Descent), Colour.FromRgb(163, 73, 164), lineWidth: 5);
            gpr.StrokePath(new GraphicsPath().MoveTo(2700 + qMetrics.Width + qMetrics.RightSideBearing, 1150 - biggerTimes.Ascent).LineTo(2700 + qMetrics.Width + qMetrics.RightSideBearing, 1250 - biggerTimes.Descent), Colour.FromRgb(163, 73, 164), lineWidth: 5);

            gpr.FillText(2100, 1200, "f", biggerTimes, Colour.FromRgb(0, 0, 0), textBaseline: TextBaselines.Baseline);
            gpr.FillText(2700, 1200, "q", biggerTimes, Colour.FromRgb(0, 0, 0), textBaseline: TextBaselines.Baseline);



            //Create a new graphics object
            Graphics faceGraphics = new Graphics();

            //Scale
            faceGraphics.Scale(5, 5);

            //Create a new path object
            GraphicsPath face = new GraphicsPath();

            //Figure start point
            face.MoveTo(135.484, 186.221);
            //Cubic Beziers (the start point is the current point; two control points and a destination point are provided)
            face.CubicBezierTo(119.634, 185.011, 96.762, 211.243, 89.044, 228.362);
            face.CubicBezierTo(83.104, 225.903, 76.343, 224.519, 69.141, 224.519);
            face.CubicBezierTo(61.986, 224.519, 55.267, 225.884, 49.302, 228.335);
            face.CubicBezierTo(42.919, 212.558, 18.514, 185.011, 2.664, 186.221);
            face.CubicBezierTo(-2.291, 186.6, 2.727, 212.423, 32.997, 239.883);
            face.CubicBezierTo(27.684, 246.062, 24.576, 253.702, 24.576, 262.033);
            face.CubicBezierTo(24.576, 282.245, 43.032, 296, 69.141, 296);
            face.CubicBezierTo(95.25, 296, 113.705, 282.245, 113.705, 262.033);
            face.CubicBezierTo(113.705, 253.662, 110.567, 245.988, 105.176, 239.757);
            face.CubicBezierTo(135.614, 211.926, 140.439, 186.6, 135.484, 186.221);
            //Close the path
            face.Close();
            //Fill the path
            faceGraphics.FillPath(face, Colour.FromRgb(242, 216, 35));

            //Another path
            GraphicsPath mouth = new GraphicsPath();

            mouth.MoveTo(69.361, 288.088);
            mouth.CubicBezierTo(78.235, 288.088, 81.085, 268.837, 81.085, 268.837);
            mouth.CubicBezierTo(77.594, 269.597, 72.494, 267.158, 69.084, 267.158);
            mouth.CubicBezierTo(66.007, 267.158, 61.554, 269.144, 58.156, 268.97);
            mouth.CubicBezierTo(58.156, 268.97, 60.486, 288.088, 69.361, 288.088);
            mouth.Close();
            faceGraphics.FillPath(mouth, Colour.FromRgb(181, 20, 24));

            //Yet another path
            GraphicsPath tongue = new GraphicsPath();

            tongue.MoveTo(60.305, 278.13);
            tongue.CubicBezierTo(61.968, 283.028, 64.795, 288.088, 69.361, 288.088);
            tongue.CubicBezierTo(73.931, 288.088, 76.896, 282.985, 78.683, 278.074);
            tongue.CubicBezierTo(72.673, 275.222, 66.57, 274.868, 60.305, 278.13);
            tongue.Close();
            faceGraphics.FillPath(tongue, Colour.FromRgb(237, 27, 36));

            //Yet another path
            GraphicsPath leftCheek = new GraphicsPath();

            leftCheek.MoveTo(41.666, 270.34);
            leftCheek.CubicBezierTo(42.67, 275.168, 40.005, 279.806, 35.713, 280.698);
            leftCheek.CubicBezierTo(31.421, 281.591, 27.127, 278.4, 26.124, 273.571);
            leftCheek.CubicBezierTo(25.12, 268.743, 27.785, 264.105, 32.077, 263.213);
            leftCheek.CubicBezierTo(36.369, 262.32, 40.662, 265.511, 41.666, 270.34);
            leftCheek.Close();
            faceGraphics.FillPath(leftCheek, Colour.FromRgb(235, 28, 34));

            //Yet another path
            GraphicsPath rightCheek = new GraphicsPath();

            rightCheek.MoveTo(96.503, 270.34);
            rightCheek.CubicBezierTo(95.499, 275.168, 98.164, 279.806, 102.456, 280.698);
            rightCheek.CubicBezierTo(106.748, 281.591, 111.041, 278.4, 112.045, 273.571);
            rightCheek.CubicBezierTo(113.049, 268.743, 110.384, 264.105, 106.092, 263.213);
            rightCheek.CubicBezierTo(101.8, 262.32, 97.507, 265.511, 96.503, 270.34);
            rightCheek.Close();
            faceGraphics.FillPath(rightCheek, Colour.FromRgb(235, 28, 34));

            //Inline path syntax - mouth
            faceGraphics.StrokePath(new GraphicsPath().MoveTo(84.683, 265.03)
                                    .CubicBezierTo(82.771, 272.435, 74.1, 267.158, 69.084, 267.158)
                                    .CubicBezierTo(64.069, 267.158, 55.398, 272.435, 53.486, 265.03)
                                    .MoveTo(58.182, 268.972)
                                    .CubicBezierTo(58.182, 268.972, 60.486, 288.088, 69.361, 288.088)
                                    .CubicBezierTo(78.235, 288.088, 81.059, 268.842, 81.059, 268.842)
                                    .MoveTo(60.31, 278.145)
                                    .CubicBezierTo(66.57, 274.868, 72.673, 275.222, 78.669, 278.114),
                                    Colour.FromRgb(0, 0, 0), lineWidth: 2.5, lineCap: LineCaps.Round);

            //Again, inline path syntax - left ear
            faceGraphics.FillPath(new GraphicsPath().MoveTo(20.118, 192.906).CubicBezierTo(14.005, 188.531, 7.872, 185.824, 2.664, 186.221).CubicBezierTo(-1.235, 186.519, 1.041, 202.568, 16.932, 222.774).CubicBezierTo(15.793, 212.993, 14.194, 202.11, 20.118, 192.906).Close(), Colour.FromRgb(0, 0, 0));
            //Right ear
            faceGraphics.FillPath(new GraphicsPath().MoveTo(120.095, 224.029).CubicBezierTo(137.116, 203.05, 139.479, 186.526, 135.484, 186.221).CubicBezierTo(130.041, 185.806, 123.77, 188.626, 117.569, 193.202).CubicBezierTo(122.356, 200.373, 120.978, 212.396, 120.095, 224.029).Close(), Colour.FromRgb(0, 0, 0));
            //Nose
            faceGraphics.FillPath(new GraphicsPath().MoveTo(71.3, 261.868).CubicBezierTo(71.3, 262.361, 70.308, 262.761, 69.084, 262.761).CubicBezierTo(67.861, 262.761, 66.869, 262.361, 66.869, 261.868).CubicBezierTo(66.869, 261.375, 67.861, 260.975, 69.085, 260.975).CubicBezierTo(70.308, 260.975, 71.3, 261.375, 71.3, 261.868).Close(), Colour.FromRgb(0, 0, 0));

            GraphicsPath leftEye = new GraphicsPath();

            //Circle
            leftEye.Arc(44.875, 252.274, 8.029, 0, 2 * Math.PI);
            faceGraphics.FillPath(leftEye, Colour.FromRgb(0, 0, 0));
            faceGraphics.FillPath(new GraphicsPath().Arc(45.757, 249.371, 3.567, 0, 2 * Math.PI), Colour.FromRgb(255, 255, 255));

            //Right eye
            faceGraphics.FillPath(new GraphicsPath().Arc(93.294, 252.274, 8.029, 0, 2 * Math.PI), Colour.FromRgb(0, 0, 0));
            faceGraphics.FillPath(new GraphicsPath().Arc(92.412, 249.371, 3.567, 0, 2 * Math.PI), Colour.FromRgb(255, 255, 255));

            //Reuse the first path for a stroke
            faceGraphics.StrokePath(face, Colour.FromRgb(0, 0, 0), lineWidth: 2.5);

            //Copy the graphics object on the main graphics
            gpr.DrawGraphics(2000, 1000, faceGraphics);



            //Rotation sample

            //Save graphics state (e.g. rotation, translation, scale etc.)
            gpr.Save();

            string[] angles = new string[] { "0", "π/6", "π/3", "π/2", "2π/3", "5π/6", "π", "7π/6", "4π/3", "3π/2", "5π/3", "11π/6" };

            for (int i = 0; i < 12; i++)
            {
                gpr.StrokePath(new GraphicsPath().MoveTo(3400, 1150).LineTo(3550, 1150), Colour.FromRgb(0, 0, 0), lineWidth: 5);
                gpr.FillText(3600, 1150, angles[i], new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.TimesBold), 60), Colour.FromRgb(0, 0, 0), textBaseline: TextBaselines.Middle);

                //Rotate around a point
                gpr.RotateAt(Math.PI / 6, new VectSharp.Point(3400, 1150));
            }

            //Restore graphics state
            gpr.Restore();


            //Transparency sample

            //Checkerboard
            for (int x = 3150; x < 3650; x += 100)
            {
                for (int y = 1825; y < 2475; y += 100)
                {
                    gpr.FillRectangle(x, y, 50, 50, Colour.FromRgb(220, 220, 220));
                    gpr.FillRectangle(x + 50, y + 50, 50, 50, Colour.FromRgb(220, 220, 220));
                }
            }

            //Transparent text
            gpr.FillText(3400 - gpr.MeasureText("Transparent", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBoldOblique), 80)).Width / 2, 1925, "Transparent", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBoldOblique), 80), Colour.FromRgba(255, 127, 39, 85), textBaseline: TextBaselines.Bottom);

            //Transparent stroke
            gpr.StrokePath(new GraphicsPath().MoveTo(3175, 1950).LineTo(3625, 1950), Colour.FromRgba(163, 73, 164, 128), lineWidth: 30);

            //Transparent fill
            gpr.FillPath(new GraphicsPath().Arc(3325, 2300, 150, 0, 2 * Math.PI), Colour.FromRgba((byte)234, (byte)28, (byte)36, (byte)85), tag: "red");
            gpr.FillPath(new GraphicsPath().Arc(3400, 2150, 150, 0, 2 * Math.PI), Colour.FromRgba((byte)34, (byte)177, (byte)76, (byte)85));
            gpr.FillPath(new GraphicsPath().Arc(3475, 2300, 150, 0, 2 * Math.PI), Colour.FromRgba((byte)0, (byte)162, (byte)232, (byte)85));


            //Text fill vs stroke
            gpr.FillText(1925, 1450, "Fill", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBoldOblique), 150), Colour.FromRgb(203, 245, 216));
            gpr.StrokeText(2325, 1450, "Stroke", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBoldOblique), 150), Colour.FromRgb(34, 177, 76), lineWidth: 6, lineJoin: LineJoins.Round);

            //Text can be also added to a graphics path.
            GraphicsPath textPath = new GraphicsPath().AddText(1925, 1650, "Fill & stroke", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBoldOblique), 150));

            gpr.FillPath(textPath, Colour.FromRgb(203, 245, 216));
            gpr.StrokePath(textPath, Colour.FromRgb(34, 177, 76), lineWidth: 6, lineJoin: LineJoins.Round);

            //Embedding raster images
            //First draw what is going to be the raster image
            Page rasterPage = new Page(50, 25);

            Graphics rasterGpr = rasterPage.Graphics;

            rasterGpr.FillRectangle(10, 0, 4, 4, Colour.FromRgb(237, 28, 36));
            rasterGpr.FillRectangle(14, 0, 4, 4, Colour.FromRgb(34, 177, 76));
            rasterGpr.FillRectangle(18, 0, 4, 4, Colour.FromRgb(255, 127, 39));
            rasterGpr.FillRectangle(22, 0, 4, 4, Colour.FromRgb(0, 162, 232));
            rasterGpr.FillRectangle(26, 0, 4, 4, Colour.FromRgb(255, 242, 0));
            rasterGpr.FillRectangle(10, 4, 4, 4, Colour.FromRgb(63, 72, 204));
            rasterGpr.FillRectangle(14, 4, 4, 4, Colour.FromRgb(255, 201, 14));
            rasterGpr.FillRectangle(18, 4, 4, 4, Colour.FromRgb(163, 73, 164));
            rasterGpr.FillRectangle(22, 4, 4, 4, Colour.FromRgb(181, 230, 29));
            rasterGpr.FillRectangle(26, 4, 4, 4, Colour.FromRgb(128, 128, 128));

            rasterGpr.FillText(2, 10, "Raster", new Font(new VectSharp.FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 12), Colours.Black);

            //Save the raster image to a stream in PNG format
            System.IO.MemoryStream rasterStream = new System.IO.MemoryStream();
            rasterPage.SaveAsPNG(rasterStream, 2);

            //Load the raster image from the stream (we load it twice: once with interpolation enabled and once with interpolation disabled).
            RasterImage nonInterpolatedRasterImage = new RasterImageStream(rasterStream, MuPDFCore.InputFileTypes.PNG, interpolate: false);
            RasterImage interpolatedRasterImage    = new RasterImageStream(rasterStream, MuPDFCore.InputFileTypes.PNG, interpolate: true);

            //Create and set clipping path
            GraphicsPath clippingPathLeft = new GraphicsPath().MoveTo(1050, 250).LineTo(1275, 250).LineTo(1325, 300).LineTo(1275, 350).LineTo(1325, 400).LineTo(1275, 450).LineTo(1325, 500).LineTo(1275, 550).LineTo(1050, 550).Close();

            gpr.Save();
            gpr.SetClippingPath(clippingPathLeft);

            //Draw the raster image
            gpr.DrawRasterImage(1100, 300, 500, 250, nonInterpolatedRasterImage);

            //Restore the clipping path
            gpr.Restore();

            //Create and set the new clipping path
            GraphicsPath clippingPathRight = new GraphicsPath().MoveTo(1550, 250).LineTo(1275, 250).LineTo(1325, 300).LineTo(1275, 350).LineTo(1325, 400).LineTo(1275, 450).LineTo(1325, 500).LineTo(1275, 550).LineTo(1550, 550).Close();

            gpr.Save();
            gpr.SetClippingPath(clippingPathRight);

            //Draw the other raster image
            gpr.DrawRasterImage(1100, 300, 500, 250, interpolatedRasterImage);

            //Restore the clipping path
            gpr.Restore();

            //Draw a path on the boundary between the clipping paths
            GraphicsPath clippingPathTear = new GraphicsPath().MoveTo(1325, 200).LineTo(1275, 250).LineTo(1325, 300).LineTo(1275, 350).LineTo(1325, 400).LineTo(1275, 450).LineTo(1325, 500).LineTo(1275, 550).LineTo(1325, 600);

            gpr.StrokePath(clippingPathTear, Colours.Red, 5);


            //Interactivity sample (Avalonia only)
            //Fill rectangle
            gpr.FillRectangle(3100, 1550, 600, 200, Colour.FromRgb(220, 220, 220), tag: "ClickMeRectangle");

            //Stroke rectangle (with dashed line)
            gpr.StrokeRectangle(3100, 1550, 600, 200, Colour.FromRgb(80, 80, 80), lineWidth: 20, lineDash: new LineDash(60, 60, 0));

            //Text
            gpr.FillText(3400 - gpr.MeasureText("Click me!", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBold), 80)).Width / 2, 1650, "Click me!", new Font(new FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBold), 80), Colour.FromRgb(0, 0, 0), textBaseline: TextBaselines.Middle, tag: "ClickMeText");

            //Text along a path
            GraphicsPath flowPath = new GraphicsPath().Arc(1550, 1100, 300, -7 * Math.PI / 8, -Math.PI / 8);

            gpr.StrokePath(flowPath, Colour.FromRgb(220, 220, 220), lineWidth: 10);
            gpr.FillTextOnPath(flowPath, "Text on a path!", new Font(new VectSharp.FontFamily(VectSharp.FontFamily.StandardFontFamilies.HelveticaBold), 80), Colour.FromRgb(34, 177, 76), reference: 0.5, anchor: TextAnchors.Center, textBaseline: TextBaselines.Baseline);

            //Dictionary associating each tag to the action to perform on the object (Avalonia only)
            Dictionary <string, Delegate> taggedActions = new Dictionary <string, Delegate>()
            {
                { "ClickMeText", new Action <Control>(block => { block.IsHitTestVisible = false; }) },
                { "ClickMeRectangle", new Action <Path>(path =>
                    {
                        path.Cursor        = new Avalonia.Input.Cursor(Avalonia.Input.StandardCursorType.Hand);
                        path.PointerEnter += (sender, e) =>
                        {
                            path.Fill = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Color.FromRgb(180, 180, 180));
                        };

                        path.PointerLeave += (sender, e) =>
                        {
                            path.Fill = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Color.FromRgb(220, 220, 220));
                        };

                        path.PointerPressed += (sender, e) =>
                        {
                            path.Fill = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Color.FromRgb(128, 128, 128));
                        };

                        path.PointerReleased += async(sender, e) =>
                        {
                            path.Fill = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Color.FromRgb(180, 180, 180));

                            Window win = new Window()
                            {
                                Width = 300, Height = 150, Title = "Thanks for clicking!", WindowStartupLocation = WindowStartupLocation.CenterOwner, Content = new TextBlock()
                                {
                                    Text = "Hello world!", HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, FontSize = 40
                                }
                            };
                            await win.ShowDialog(this);
                        };
                    }) },
            };

            //Save the image as a PNG file
            doc.Pages.Last().SaveAsPNG(@"Sample.png");

            //Save the image as an SVG file
            doc.Pages.Last().SaveAsSVG("Sample.svg");

            //Transfer the page onto an Avalonia Canvas object
            this.FindControl <Viewbox>("mainViewBox").Child = doc.Pages.Last().PaintToCanvas(taggedActions);

            //Add another page to the document (the size of each page can be different)
            doc.Pages.Add(new Page(480, 100));

            //Write some text on the second page
            doc.Pages.Last().Graphics.FillText(20, 50, "This is the second page!", new Font(new VectSharp.FontFamily(VectSharp.FontFamily.StandardFontFamilies.Helvetica), 40), Colour.FromRgb(0, 0, 0), textBaseline: TextBaselines.Middle);

            //Create a PDF document
            doc.SaveAsPDF(@"Sample.pdf");
        }
Beispiel #8
0
        public void Render(Graphics g, ITrain train, bool exportColor)
        {
            var style = new TrainStyle(train, attrs);

            if (!style.CalcedShow)
            {
                return;
            }

            var ardps = train.GetArrDepsUnsorted();
            var dir   = GetTrainDirection(train);

            using var pen = new Pen(style.CalcedColor.ToSD(exportColor), style.CalcedWidth)
                  {
                      DashPattern = ds.ParseDashstyle(style.CalcedLineStyle)
                  };
            using var brush = new SolidBrush(style.CalcedColor.ToSD(exportColor));

            List <PointF> points = new List <PointF>();
            bool          hadFirstArrival = false, hadLastDeparture = false, isFirst = true;
            var           stas = dir ? Enumerable.Reverse(stations) : stations;

            int trainTravelsRouteCount = 0;

            foreach (var sta in stas)
            {
                if (!ardps.ContainsKey(sta))
                {
                    continue;
                }
                var ardp = ardps[sta];
                trainTravelsRouteCount++;

                if (!ardp.HasMinOneTimeSet)
                {
                    continue;
                }

                MaybeAddPoint(points, GetGutterPoint(true, dir, stationOffsets[sta], ardp.Arrival));
                MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], ardp.Arrival, ardp.ArrivalTrack));

                foreach (var shunt in ardp.ShuntMoves)
                {
                    MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.SourceTrack));
                    MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], shunt.Time, shunt.TargetTrack));
                }

                MaybeAddPoint(points, GetInternalPoint(stationOffsets[sta], ardp.Departure, ardp.DepartureTrack));
                MaybeAddPoint(points, GetGutterPoint(false, dir, stationOffsets[sta], ardp.Departure));

                hadLastDeparture = ardp.Departure != default;
                if (isFirst)
                {
                    hadFirstArrival = ardp.Arrival != default;
                }
                isFirst = false;
            }

            // Halbe Linien bei Abfahrten / Ankünften ohne Gegenstelle
            if (attrs.DrawNetworkTrains)
            {
                var hly = !dir ? 20 : -20;
                if (hadLastDeparture)
                {
                    points.Add(points.Last() + new Size(50, hly));
                }
                if (hadFirstArrival)
                {
                    points.Insert(0, points.First() - new Size(50, hly));
                }
            }
            else if (trainTravelsRouteCount <= 1)
            {
                return; // This train has only one station on this route and we don't draw network trains.
            }
            if (points.Count == 0)
            {
                return; // This train is not travelling on this route
            }
            // Transition to the next train; filtered by days and station.
            var lastStaOfFirst = GetSortedStations(train)?.LastOrDefault();
            var transition     = tt.GetTransition(train, renderDays, lastStaOfFirst);

            if (transition != null && !hadLastDeparture && attrs.StationLines != StationLineStyle.None && transition.Days.IsIntersecting(renderDays))
            {
                var firstStaOfNext = GetSortedStations(transition)?.FirstOrDefault();

                if (lastStaOfFirst == firstStaOfNext)
                {
                    var departure = transition.GetArrDep(firstStaOfNext).Departure;
                    points.Add(new PointF(points.Last().X, GetTimeY(departure)));
                }
            }

            using var p = new GraphicsPath();

            for (int i = 0; i < points.Count; i += 1)
            {
                if (points.Count <= i + 1)
                {
                    continue;
                }

                var isStationLine = (int)points[i].X == (int)points[i + 1].X;
                if (isStationLine)
                {
                    var preX         = i > 0 ? points[i - 1].X : 0;
                    var postX        = i < points.Count - 2 ? points[i + 2].X : 0;
                    var x            = points[i].X;
                    var isTransition = isStationLine && (points.Count == i + 2 || Math.Sign(preX - x) == Math.Sign(postX - x));

                    float bezierFactor = !isTransition ?
                                         ((preX < postX) ? -1 : 1) : // preX < postX --> TrainDirection.ti
                                         Math.Sign(preX - x);        // Transition
                    if (isTransition)
                    {
                        bezierFactor *= 0.5f;
                    }
                    var bezierOffset  = new SizeF(bezierFactor * 14, (points[i + 1].Y - points[i].Y) / -4.0f);
                    var bezierOffsetT = new SizeF(bezierOffset.Width, -bezierOffset.Height);

                    switch (attrs.StationLines)
                    {
                    case StationLineStyle.None:
                        p.MoveTo(points[i + 1]);
                        break;

                    case StationLineStyle.Normal:
                        p.AddLine(points[i], points[i + 1]);
                        break;

                    case StationLineStyle.Cubic:
                        var control2 = points[i + 1] + (!isTransition ? bezierOffset : (SizeF.Empty - bezierOffsetT));
                        p.AddBezier(points[i], points[i] - bezierOffset, control2, points[i + 1]);
                        break;
                    }
                }
                else
                {
                    p.AddLine(points[i], points[i + 1]); // Normal line between stations
                }
                if (points[i].X == points[i + 1].X || points[i].Y == points[i + 1].Y)
                {
                    continue;
                }
                // Zugnummern zeichnen
                var trainFont = (Font)attrs.TrainFont;

                var     size = g.MeasureString(trainFont, train.TName);
                float[] ys   = { points[i].Y, points[i + 1].Y };
                float[] xs   = { points[i].X, points[i + 1].X };
                float   ty   = ys.Min() + (ys.Max() - ys.Min()) / 2 - (size.Height / 2);
                float   tx   = xs.Min() + (xs.Max() - xs.Min()) / 2;

                if (g.Clip.IsVisible(new PointF(tx, ty))) // translated drawing does not respect clip (Idk why)
                {
                    float angle = CalcAngle(ys, xs, train);

                    var matrix = g.Transform.Clone();

                    g.TranslateTransform(tx, ty);
                    g.RotateTransform(-angle);
                    g.DrawText(trainFont, brush, -(size.Width / 2), -(size.Height / 2), train.TName);

                    g.Transform = matrix;
                }
            }
            g.DrawPath(pen, p);
        }
Beispiel #9
0
        private void FillTriangle(Graphics graphics, IEnumerable <Point> triangleProjection, Colour colour, double overFill, double scaleFactor, string tag)
        {
            GraphicsPath path = new GraphicsPath();

            if (overFill > 0)
            {
                double overfill = overFill * scaleFactor;

                double meanX = 0;
                double meanY = 0;

                int count = 0;

                foreach (Point pt in triangleProjection)
                {
                    meanX += pt.X;
                    meanY += pt.Y;
                    count++;
                }

                meanX /= count;
                meanY /= count;

                Point centroid2D = new Point(meanX, meanY);

                Point prevPoint  = new Point();
                Point firstPoint = new Point();

                foreach (Point pt in triangleProjection)
                {
                    if (path.Segments.Count == 0)
                    {
                        path.MoveTo(pt);
                        prevPoint  = pt;
                        firstPoint = pt;
                    }
                    else
                    {
                        Point meanPoint = Intersections2D.ProjectOnLine(centroid2D, prevPoint, pt);

                        Point  dir    = new Point(meanPoint.X - meanX, meanPoint.Y - meanY);
                        double length = dir.Modulus();

                        Point newMeanPoint = new Point(meanX + dir.X * (length + overfill) / length, meanY + dir.Y * (length + overfill) / length);

                        path.LineTo(prevPoint.X - meanPoint.X + newMeanPoint.X, prevPoint.Y - meanPoint.Y + newMeanPoint.Y);

                        path.LineTo(pt.X - meanPoint.X + newMeanPoint.X, pt.Y - meanPoint.Y + newMeanPoint.Y);

                        path.LineTo(pt);

                        prevPoint = pt;
                    }
                }

                {
                    Point meanPoint = Intersections2D.ProjectOnLine(centroid2D, prevPoint, firstPoint);

                    Point  dir    = new Point(meanPoint.X - meanX, meanPoint.Y - meanY);
                    double length = dir.Modulus();

                    Point newMeanPoint = new Point(meanX + dir.X * (length + overfill) / length, meanY + dir.Y * (length + overfill) / length);

                    path.LineTo(prevPoint.X - meanPoint.X + newMeanPoint.X, prevPoint.Y - meanPoint.Y + newMeanPoint.Y);

                    path.LineTo(firstPoint.X - meanPoint.X + newMeanPoint.X, firstPoint.Y - meanPoint.Y + newMeanPoint.Y);
                }
            }
            else
            {
                foreach (Point pt in triangleProjection)
                {
                    path.LineTo(pt);
                }
            }

            path.Close();

            graphics.FillPath(path, colour, tag: tag);
        }
        void panel2_Paint(object sender, GUI.PaintEventArgs e)
        {
            Graphics graphics           = e.Graphics;
            bool     isSoftwareGraphics = graphics is SoftwareGraphics;

            //if (isSoftwareGraphics)
            {
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
            }


            // Two simple paths
            if (rbGeometry5.IsChecked)
            {
                GraphicsPath ps1_path = new GraphicsPath();

                double x = m_X - m_DrawingPanel.ClientRectangle.Center.X / 2 + 100;
                double y = m_Y - m_DrawingPanel.ClientRectangle.Center.Y / 2 + 100;
                ps1_path.MoveTo(x + 140, y + 145);
                ps1_path.LineTo(x + 225, y + 44);
                ps1_path.LineTo(x + 296, y + 219);
                ps1_path.ClosePolygon();

                ps1_path.LineTo(x + 226, y + 289);
                ps1_path.LineTo(x + 82, y + 292);

                ps1_path.MoveTo(x + 220, y + 222);
                ps1_path.LineTo(x + 363, y + 249);
                ps1_path.LineTo(x + 265, y + 331);

                ps1_path.MoveTo(x + 242, y + 243);
                ps1_path.LineTo(x + 268, y + 309);
                ps1_path.LineTo(x + 325, y + 261);

                ps1_path.MoveTo(x + 259, y + 259);
                ps1_path.LineTo(x + 273, y + 288);
                ps1_path.LineTo(x + 298, y + 266);

                Rect ps1Bounds          = ps1_path.Bounds;
                GeometryTransformer ps1 = GeometryMatrix4Transformer.CreateOptimizedTransformer(ps1_path, Matrix4.CreateTranslation(
                                                                                                    m_X - ps1Bounds.Center.X,
                                                                                                    m_Y - ps1Bounds.Center.Y));


                GraphicsPath ps2_path = new GraphicsPath();
                ps2_path.MoveTo(100 + 32, 100 + 77);
                ps2_path.LineTo(100 + 473, 100 + 263);
                ps2_path.LineTo(100 + 351, 100 + 290);
                ps2_path.LineTo(100 + 354, 100 + 374);
                Rect ps2Bounds          = ps2_path.Bounds;
                GeometryTransformer ps2 = GeometryMatrix4Transformer.CreateOptimizedTransformer(ps2_path, Matrix4.CreateTranslation(
                                                                                                    (m_DrawingPanel.Width - ps2Bounds.Width) / 2 - ps2Bounds.Left,
                                                                                                    (m_DrawingPanel.Height - ps2Bounds.Height) / 2 - ps2Bounds.Top));


                graphics.FillGeometry(m_GeometryBColor, ps2);
                graphics.FillGeometry(m_GeometryAColor, ps1);

                CombinedGeometry clp = new CombinedGeometry(ps1, ps2, CombinedGeometry.CombineMode.Or, CombinedGeometry.FillType.NonZero, CombinedGeometry.FillType.NonZero);

                PerformRendering(graphics, clp);
            }
            // Closed stroke
            else if (rbGeometry4.IsChecked)
            {
                GraphicsPath ps1_path = new GraphicsPath();

                double x = m_X - m_DrawingPanel.ClientRectangle.Center.X / 2 + 100;
                double y = m_Y - m_DrawingPanel.ClientRectangle.Center.Y / 2 + 100;
                ps1_path.MoveTo(x + 140, y + 145);
                ps1_path.LineTo(x + 225, y + 44);
                ps1_path.LineTo(x + 296, y + 219);
                ps1_path.ClosePolygon();

                ps1_path.LineTo(x + 226, y + 289);
                ps1_path.LineTo(x + 82, y + 292);

                ps1_path.MoveTo(x + 220 - 50, y + 222);
                ps1_path.LineTo(x + 265 - 50, y + 331);
                ps1_path.LineTo(x + 363 - 50, y + 249);
                ps1_path.ClosePolygon(GeometryVertexCommandAndFlags.FlagCCW);

                Rect ps1Bounds          = ps1_path.Bounds;
                GeometryTransformer ps1 = GeometryMatrix4Transformer.CreateOptimizedTransformer(ps1_path, Matrix4.CreateTranslation(
                                                                                                    m_X - ps1Bounds.Center.X,
                                                                                                    m_Y - ps1Bounds.Center.Y));


                GraphicsPath ps2_path = new GraphicsPath();
                ps2_path.MoveTo(100 + 32, 100 + 77);
                ps2_path.LineTo(100 + 473, 100 + 263);
                ps2_path.LineTo(100 + 351, 100 + 290);
                ps2_path.LineTo(100 + 354, 100 + 374);
                ps2_path.ClosePolygon();
                Rect ps2Bounds          = ps2_path.Bounds;
                GeometryTransformer ps2 = GeometryMatrix4Transformer.CreateOptimizedTransformer(ps2_path, Matrix4.CreateTranslation(
                                                                                                    (m_DrawingPanel.Width - ps2Bounds.Width) / 2 - ps2Bounds.Left,
                                                                                                    (m_DrawingPanel.Height - ps2Bounds.Height) / 2 - ps2Bounds.Top));

                GeometryStroke stroke = new GeometryStroke(ps2, 10);


                graphics.FillGeometry(m_GeometryBColor, stroke);
                graphics.FillGeometry(m_GeometryAColor, ps1);

                CombinedGeometry clp = new CombinedGeometry(ps1, stroke, CombinedGeometry.CombineMode.Or, CombinedGeometry.FillType.NonZero, CombinedGeometry.FillType.NonZero);

                PerformRendering(graphics, clp);
            }
            // Great Britain and Arrows
            else if (rbGeometry3.IsChecked)
            {
                Geometry poly       = GreatBritain;
                Rect     polyBounds = poly.Bounds;
                double   scale      = 3;
                Matrix4  mtx        = Matrix4.CreateTranslation(-polyBounds.Center.X, -polyBounds.Center.Y);
                mtx *= Matrix4.CreateScaling(scale, scale);
                mtx *= Matrix4.CreateTranslation(m_DrawingPanel.Width / 2, m_DrawingPanel.Height / 2);
                GeometryTransformer trans_gb_poly = GeometryMatrix4Transformer.CreateOptimizedTransformer(poly, mtx);

                Geometry arrows       = Arrows;
                Rect     arrowsBounds = arrows.Bounds;
                mtx  = Matrix4.CreateTranslation(-arrowsBounds.Center.X, -arrowsBounds.Center.Y);
                mtx *= Matrix4.CreateScaling(scale, scale);
                mtx *= Matrix4.CreateTranslation(m_X, m_Y);
                GeometryTransformer trans_arrows = GeometryMatrix4Transformer.CreateOptimizedTransformer(arrows, mtx);

                CombinedGeometry clp = new CombinedGeometry(trans_gb_poly, trans_arrows,
                                                            CombinedGeometry.CombineMode.Or,
                                                            CombinedGeometry.FillType.NonZero,
                                                            CombinedGeometry.FillType.NonZero);

                graphics.FillGeometry(m_GeometryBColor, trans_gb_poly);
                graphics.DrawGeometry(isSoftwareGraphics ? m_GreatBritainContourPen_SWR : m_GreatBritainContourPen_HWR, trans_gb_poly);
                graphics.FillGeometry(m_GeometryAColor, trans_arrows);

                PerformRendering(graphics, clp);
            }
            // Great Britain and a Spiral
            else if (rbGeometry2.IsChecked)
            {
                Geometry poly       = GreatBritain;
                Rect     polyBounds = poly.Bounds;
                double   scale      = 3;
                Matrix4  mtx        = Matrix4.CreateTranslation(-polyBounds.Center.X, -polyBounds.Center.Y);
                mtx *= Matrix4.CreateScaling(scale, scale);
                mtx *= Matrix4.CreateTranslation(m_DrawingPanel.Width / 2, m_DrawingPanel.Height / 2);
                GeometryTransformer trans_gb_poly = GeometryMatrix4Transformer.CreateOptimizedTransformer(poly, mtx);

                Geometry       sp     = GeometryMatrix4Transformer.CreateOptimizedTransformer(Spiral, Matrix4.CreateTranslation(m_X, m_Y));
                GeometryStroke stroke = new GeometryStroke(sp, 15);

                CombinedGeometry clp = new CombinedGeometry(trans_gb_poly, stroke,
                                                            CombinedGeometry.CombineMode.Or,
                                                            CombinedGeometry.FillType.NonZero,
                                                            CombinedGeometry.FillType.NonZero);

                graphics.FillGeometry(m_GeometryBColor, trans_gb_poly);
                graphics.DrawGeometry(isSoftwareGraphics ? m_GreatBritainContourPen_SWR : m_GreatBritainContourPen_HWR, trans_gb_poly);
                graphics.DrawGeometry(m_SpiralPen, sp);

                PerformRendering(graphics, clp);
            }
            // Spiral and text
            else if (rbGeometry1.IsChecked)
            {
                Geometry            text            = Text;
                Rect                textBounds      = text.Bounds;
                GeometryTransformer transformedText = GeometryMatrix4Transformer.CreateOptimizedTransformer(text,
                                                                                                            Matrix4.CreateTranslation(
                                                                                                                (m_DrawingPanel.Width - textBounds.Width) / 2 - textBounds.Left,
                                                                                                                (m_DrawingPanel.Height - textBounds.Height) / 2 - textBounds.Top));

                Geometry       sp     = GeometryMatrix4Transformer.CreateOptimizedTransformer(Spiral, Matrix4.CreateTranslation(m_X, m_Y));
                GeometryStroke stroke = new GeometryStroke(sp, 15);

                CombinedGeometry clp = new CombinedGeometry(stroke, transformedText,
                                                            CombinedGeometry.CombineMode.Or,
                                                            CombinedGeometry.FillType.NonZero,
                                                            CombinedGeometry.FillType.NonZero);

                graphics.FillGeometry(m_GeometryBColor, transformedText);
                graphics.DrawGeometry(m_SpiralPen, sp);

                PerformRendering(graphics, clp);
            }
        }