示例#1
1
        public void RenderRect(OxyRect bounds, OxyColor fill, OxyColor borderColor, double borderThickness)
        {
            var border = new[]
                             {
                                 new ScreenPoint(bounds.Left, bounds.Top), new ScreenPoint(bounds.Right, bounds.Top),
                                 new ScreenPoint(bounds.Right, bounds.Bottom), new ScreenPoint(bounds.Left, bounds.Bottom),
                                 new ScreenPoint(bounds.Left, bounds.Top)
                             };

            rc.DrawPolygon(border, fill, borderColor, borderThickness, null, true);
        }
示例#2
0
        public GraphComponents(OxyColor color)
        {
            scatters = new ScatterSeries
            {
                BinSize = 8,
                MarkerFill = color,
                MarkerSize = 2.0,
                MarkerStroke = color,
                MarkerStrokeThickness = 1.0,
                MarkerType = MarkerType.Circle
            };

            lines = new LineSeries
            {
                Color = color,
                LineStyle = LineStyle.Solid,
                StrokeThickness = 1.0,
                Smooth = true
            };

            stems = new StemSeries
            {
                Color = color,
                StrokeThickness = 1.0,
            };
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="CandleStickSeries"/> class.
 /// </summary>
 /// <param name="color">
 /// The color.
 /// </param>
 /// <param name="strokeThickness">
 /// The stroke thickness.
 /// </param>
 /// <param name="title">
 /// The title.
 /// </param>
 public CandleStickSeries(OxyColor color, double strokeThickness = 1, string title = null)
     : this()
 {
     this.Color = color;
     this.StrokeThickness = strokeThickness;
     this.Title = title;
 }
示例#4
0
        /// <summary>
        /// Draws an ellipse.
        /// </summary>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            var isStroked = stroke.IsVisible() && thickness > 0;
            var isFilled = fill.IsVisible();
            if (!isStroked && !isFilled)
            {
                return;
            }

            double y = this.doc.PageHeight - rect.Bottom;
            if (isStroked)
            {
                this.SetLineWidth(thickness);
                this.doc.SetColor(stroke);
                if (isFilled)
                {
                    this.doc.SetFillColor(fill);
                    this.doc.DrawEllipse(rect.Left, y, rect.Width, rect.Height, true);
                }
                else
                {
                    this.doc.DrawEllipse(rect.Left, y, rect.Width, rect.Height);
                }
            }
            else
            {
                this.doc.SetFillColor(fill);
                this.doc.FillEllipse(rect.Left, y, rect.Width, rect.Height);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ScatterSeries"/> class.
 /// </summary>
 /// <param name="title">
 /// The title.
 /// </param>
 /// <param name="markerFill">
 /// The marker fill color.
 /// </param>
 /// <param name="markerSize">
 /// Size of the markers (If ScatterPoint.Size is set, this value will be overriden).
 /// </param>
 public ScatterSeries(string title, OxyColor markerFill = null, double markerSize = 5)
     : this()
 {
     this.MarkerFill = markerFill;
     this.MarkerSize = markerSize;
     this.Title = title;
 }
示例#6
0
 /// <summary>
 /// Draws the collection of ellipses, where all have the same stroke and fill.
 /// This performs better than calling DrawEllipse multiple times.
 /// </summary>
 /// <param name="rectangles">The rectangles.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The stroke thickness.</param>
 public virtual void DrawEllipses(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness)
 {
     foreach (var r in rectangles)
     {
         this.DrawEllipse(r, fill, stroke, thickness);
     }
 }
        /// <summary>
        /// Construct a new instance of the class.
        /// </summary>
        /// <param name="title">The plot title.</param>
        /// <param name="results">The data to plot.</param>
        public Plot(string title, List <List <double> > results)
        {
            // set up plot model
            var plotModel = new OxyPlot.PlotModel();

            plotModel.Title = title;

            // set up axes and colors
            plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
            {
                Position = OxyPlot.Axes.AxisPosition.Left, Title = "Error"
            });
            plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
            {
                Position = OxyPlot.Axes.AxisPosition.Bottom, Title = "Epochs"
            });
            var colors = new OxyPlot.OxyColor[] { OxyPlot.OxyColors.Blue, OxyPlot.OxyColors.Green, OxyPlot.OxyColors.Red, OxyPlot.OxyColors.Black };

            // set up lines
            for (int i = 0; i < results.Count; i++)
            {
                var lineSeries = new OxyPlot.Series.LineSeries();
                lineSeries.ItemsSource = results[i].Select((value, index) => new OxyPlot.DataPoint(index, value));
                lineSeries.Title       = string.Format("KFold {0}/{1}", i + 1, results.Count);
                //lineSeries.Color = colors[i];
                plotModel.Series.Add(lineSeries);
            }

            var plotView = new OxyPlot.Wpf.PlotView();

            plotView.Model = plotModel;

            Title   = title;
            Content = plotView;
        }
示例#8
0
 /// <summary>
 /// Draws a polyline.
 /// </summary>
 /// <param name="points">The points.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The stroke thickness.</param>
 /// <param name="dashArray">The dash array.</param>
 /// <param name="lineJoin">The line join type.</param>
 /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param>
 public abstract void DrawLine(
     IList<ScreenPoint> points,
     OxyColor stroke,
     double thickness,
     double[] dashArray,
     OxyPenLineJoin lineJoin,
     bool aliased);
        /// <summary>
        /// Draws an ellipse.
        /// </summary>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            var isStroked = stroke.IsVisible() && thickness > 0;

            if (fill.IsVisible())
            {
                if (!isStroked)
                {
                    this.g.SmoothingMode = SmoothingMode.HighQuality;
                }

                this.g.FillEllipse(this.GetCachedBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
            }

            if (!isStroked)
            {
                return;
            }

            using (var pen = this.GetCachedPen(stroke, thickness))
            {
                this.g.SmoothingMode = SmoothingMode.HighQuality;
                this.g.DrawEllipse(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
            }
        }
示例#10
0
        public void AddSeries(IEnumerable<double> x, IEnumerable<double> y, string title, OxyColor fill)
        {
            var series = new ScatterSeries
            {
                MarkerFill = fill,
                MarkerSize = 2,
                MarkerStrokeThickness = 0,
                MarkerType = MarkerType.Diamond,
                Title = title
            };

            double[] xPoints = x as double[] ?? x.ToArray();
            double[] yPoints = y as double[] ?? y.ToArray();

            if (xPoints.Length != yPoints.Length)
                throw new Exception("The two data arrays must be of equal length.");

            for (int i = 0; i < xPoints.Length; i++)
            {
                var point = new ScatterPoint(xPoints[i], yPoints[i]);
                series.Points.Add(point);
            }

            Model.Series.Add(series);
        }
示例#11
0
        /// <summary>
        /// Encodes the specified image data to png.
        /// </summary>
        /// <param name="pixels">
        /// The pixel data (bottom line first).
        /// </param>
        /// <param name="dpi">
        /// The image resolution in dots per inch.
        /// </param>
        /// <returns>
        /// The png image data.
        /// </returns>
        public static byte[] Encode(OxyColor[,] pixels, int dpi = 96)
        {
            int height = pixels.GetLength(0);
            int width = pixels.GetLength(1);
            var bytes = new byte[(width * height * 4) + height];

            int k = 0;
            for (int i = height - 1; i >= 0; i--)
            {
                bytes[k++] = 0; // Filter
                for (int j = 0; j < width; j++)
                {
                    bytes[k++] = pixels[i, j].R;
                    bytes[k++] = pixels[i, j].G;
                    bytes[k++] = pixels[i, j].B;
                    bytes[k++] = pixels[i, j].A;
                }
            }

            var w = new MemoryWriter();
            w.Write((byte)0x89);
            w.Write("PNG\r\n\x1a\n".ToCharArray());
            WriteChunk(w, "IHDR", CreateHeaderData(width, height));
            WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(dpi, dpi));
            WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes));
            WriteChunk(w, "IEND", new byte[0]);
            return w.ToArray();
        }
示例#12
0
        /// <summary>
        /// Draws or measures text containing sub- and superscript.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="pt">The point.</param>
        /// <param name="text">The text.</param>
        /// <param name="textColor">Color of the text.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="ha">The horizontal alignment.</param>
        /// <param name="va">The vertical alignment.</param>
        /// <param name="maxsize">The maximum size of the text.</param>
        /// <param name="measure">Measure the size of the text if set to <c>true</c>.</param>
        /// <returns>The size of the text.</returns>
        /// <example>Subscript: H_{2}O
        /// Superscript: E=mc^{2}
        /// Both: A^{2}_{i,j}</example>
        public static OxySize DrawMathText(
            this IRenderContext rc,
            ScreenPoint pt,
            string text,
            OxyColor textColor,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double angle,
            HorizontalAlignment ha,
            VerticalAlignment va,
            OxySize? maxsize,
            bool measure)
        {
            if (string.IsNullOrEmpty(text))
            {
                return OxySize.Empty;
            }

            if (text.Contains("^{") || text.Contains("_{"))
            {
                double x = pt.X;
                double y = pt.Y;

                // Measure
                var size = InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, true, angle);

                switch (ha)
                {
                    case HorizontalAlignment.Right:
                        x -= size.Width;
                        break;
                    case HorizontalAlignment.Center:
                        x -= size.Width * 0.5;
                        break;
                }

                switch (va)
                {
                    case VerticalAlignment.Bottom:
                        y -= size.Height;
                        break;
                    case VerticalAlignment.Middle:
                        y -= size.Height * 0.5;
                        break;
                }

                InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, false, angle);
                return measure ? size : OxySize.Empty;
            }

            rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxsize);
            if (measure)
            {
                return rc.MeasureText(text, fontFamily, fontSize, fontWeight);
            }

            return OxySize.Empty;
        }
 private static PlotModel CreateRandomScatterSeriesWithColorAxisPlotModel(int n, OxyPalette palette, MarkerType markerType, AxisPosition colorAxisPosition, OxyColor highColor, OxyColor lowColor)
 {
     var model = new PlotModel { Title = string.Format("ScatterSeries (n={0})", n), Background = OxyColors.LightGray };
     var colorAxis = new LinearColorAxis { Position = colorAxisPosition, Palette = palette, Minimum = -1, Maximum = 1, HighColor = highColor, LowColor = lowColor };
     model.Axes.Add(colorAxis);
     model.Series.Add(CreateRandomScatterSeries(n, markerType, false, true, colorAxis));
     return model;
 }
示例#14
0
 /// <summary>
 /// Draws a polyline.
 /// </summary>
 /// <param name="points">The points.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param>
 /// <param name="dashArray">The dash array (in device independent units, 1/96 inch). Use <c>null</c> to get a solid line.</param>
 /// <param name="lineJoin">The line join type.</param>
 /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param>
 public void DrawLine(
     IList<ScreenPoint> points,
     OxyColor stroke,
     double thickness = 1,
     double[] dashArray = null,
     LineJoin lineJoin = LineJoin.Miter,
     bool aliased = false)
 {
 }
 /// <summary>
 /// Draws a polyline.
 /// </summary>
 /// <param name="points">The points.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The stroke thickness.</param>
 /// <param name="dashArray">The dash array.</param>
 /// <param name="lineJoin">The line join type.</param>
 /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param>
 public override void DrawLine(
     IList<ScreenPoint> points,
     OxyColor stroke,
     double thickness,
     double[] dashArray,
     OxyPenLineJoin lineJoin,
     bool aliased)
 {
     var xckdPoints = this.Distort(points);
     this.rc.DrawLine(xckdPoints, stroke, thickness * this.ThicknessScale, dashArray, lineJoin);
 }
示例#16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PdfRenderContext" /> class.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="background">The background.</param>
        public PdfRenderContext(double width, double height, OxyColor background)
        {
            this.doc = new PortableDocument();
            this.doc.AddPage(width, height);
            this.RendersToScreen = false;

            if (background.IsVisible())
            {
                this.doc.SetFillColor(background);
                this.doc.FillRectangle(0, 0, width, height);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="OxyPen"/> class.
 /// </summary>
 /// <param name="color">
 /// The color.
 /// </param>
 /// <param name="thickness">
 /// The thickness.
 /// </param>
 /// <param name="lineStyle">
 /// The line style.
 /// </param>
 /// <param name="lineJoin">
 /// The line join.
 /// </param>
 public OxyPen(
     OxyColor color,
     double thickness = 1.0,
     LineStyle lineStyle = LineStyle.Solid,
     OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter)
 {
     this.Color = color;
     this.Thickness = thickness;
     this.DashArray = LineStyleHelper.GetDashArray(lineStyle);
     this.LineStyle = lineStyle;
     this.LineJoin = lineJoin;
 }
示例#18
0
 private static void SetPlotData(PlotModel IncomePlot, 
     Transaction data, OxyColor barColor, int number)
 {
     var barSeries = new LinearBarSeries
     {
         StrokeThickness = 1,
         FillColor = barColor,
         Title = data.Description
     };
     barSeries.Points.Add(new DataPoint(DateTimeAxis.ToDouble(data.TimeStamp),
         double.Parse((number * data.Amount).ToString())));
     IncomePlot.Series.Add(barSeries);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="SvgRenderContext" /> class.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="isDocument">Create an SVG document if set to <c>true</c>.</param>
        /// <param name="textMeasurer">The text measurer.</param>
        /// <param name="background">The background.</param>
        public SvgRenderContext(Stream s, double width, double height, bool isDocument, IRenderContext textMeasurer, OxyColor background)
        {
            if (textMeasurer == null)
            {
                throw new ArgumentNullException("textMeasurer", "A text measuring render context must be provided.");
            }

            this.w = new SvgWriter(s, width, height, isDocument);
            this.TextMeasurer = textMeasurer;
            if (background != null)
            {
                this.w.WriteRectangle(0, 0, width, height, this.w.CreateStyle(background, null, 0));
            }
        }
示例#20
0
        /// <summary>
        /// Interpolates the specified colors to a palette of the specified size.
        /// </summary>
        /// <param name="paletteSize">The size of the palette.</param>
        /// <param name="colors">The colors.</param>
        /// <returns>A palette.</returns>
        public static OxyPalette Interpolate(int paletteSize, params OxyColor[] colors)
        {
            var palette = new OxyColor[paletteSize];
            for (int i = 0; i < paletteSize; i++)
            {
                double y = (double)i / (paletteSize - 1);
                double x = y * (colors.Length - 1);
                int i0 = (int)x;
                int i1 = i0 + 1 < colors.Length ? i0 + 1 : i0;
                palette[i] = OxyColor.Interpolate(colors[i0], colors[i1], x - i0);
            }

            return new OxyPalette(palette);
        }
示例#21
0
        /// <summary>
        /// Exports the specified plot model to a stream.
        /// </summary>
        /// <param name="model">The plot model.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="width">The width of the export image.</param>
        /// <param name="height">The height of the exported image.</param>
        /// <param name="background">The background.</param>
        public static void Export(IPlotModel model, Stream stream, double width, double height, OxyColor background)
        {
            var canvas = new Canvas { Width = width, Height = height };
            if (background.IsVisible())
            {
                canvas.Background = background.ToBrush();
            }

            canvas.Measure(new Size(width, height));
            canvas.Arrange(new Rect(0, 0, width, height));

            var rc = new SilverlightRenderContext(canvas);
            model.Update(true);
            model.Render(rc, width, height);

            canvas.UpdateLayout();
            var image = canvas.ToImage();
            image.WriteToStream(stream);
        }
        /// <summary>
        /// Draws the ellipse.
        /// </summary>
        /// <param name="rect">The rect.</param>
        /// <param name="fill">The fill.</param>
        /// <param name="stroke">The stroke.</param>
        /// <param name="thickness">The thickness.</param>
        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            if (fill != null)
            {
                this.g.FillEllipse(
                    this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
            }

            if (stroke == null || thickness <= 0)
            {
                return;
            }

            using (var pen = new Pen(this.ToColor(stroke), (float)thickness))
            {
                this.g.SmoothingMode = SmoothingMode.HighQuality;
                this.g.DrawEllipse(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height);
            }
        }
示例#23
0
        /// <summary>
        /// Encodes the specified image data to png.
        /// </summary>
        /// <param name="pixels">The pixel data (bottom line first).</param>
        /// <returns>The png image data.</returns>
        public byte[] Encode(OxyColor[,] pixels)
        {
            int width = pixels.GetLength(0);
            int height = pixels.GetLength(1);

            var bytes = new byte[width * height * 4];
            int k = 0;
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    bytes[k++] = pixels[x, y].B;
                    bytes[k++] = pixels[x, y].G;
                    bytes[k++] = pixels[x, y].R;
                    bytes[k++] = pixels[x, y].A;
                }
            }

            var ms = new MemoryStream();
            var w = new BinaryWriter(ms);

            const int OffBits = 14 + 40;
            var size = OffBits + bytes.Length;

            // Bitmap file header (14 bytes)
            w.Write((byte)'B');
            w.Write((byte)'M');
            w.Write((uint)size);
            w.Write((ushort)0);
            w.Write((ushort)0);
            w.Write((uint)OffBits);

            // Bitmap info header (40 bytes)
            WriteBitmapInfoHeader(w, width, height, 32, bytes.Length, this.options.DpiX, this.options.DpiY);

            // Bitmap info V4 header (108 bytes)
            //// WriteBitmapV4Header(w, width, height, 32, bytes.Length, this.options.DpiX, this.options.DpiY);

            // Pixel array (from bottom-left corner)
            w.Write(bytes);

            return ms.ToArray();
        }
        public static PlotModel CreateRandomScatterSeriesWithColorAxisPlotModel(int n, OxyPalette palette, MarkerType markerType = MarkerType.Square, AxisPosition colorAxisPosition = AxisPosition.Right, OxyColor highColor = null, OxyColor lowColor = null)
        {
            var model = new PlotModel(string.Format("ScatterSeries (n={0})", n)) { Background = OxyColors.LightGray };
            model.Axes.Add(new ColorAxis { Position = colorAxisPosition, Palette = palette, Minimum = -1, Maximum = 1, HighColor = highColor, LowColor = lowColor });

            var s1 = new ScatterSeries
            {
                MarkerType = markerType,
                MarkerSize = 6,
            };
            var random = new Random();
            for (int i = 0; i < n; i++)
            {
                double x = random.NextDouble() * 2.2 - 1.1;
                s1.Points.Add(new ScatterPoint(x, random.NextDouble()) { Value = x });
            }

            model.Series.Add(s1);
            return model;
        }
示例#25
0
 /// <summary>
 /// Draws a circle at the specified position.
 /// </summary>
 /// <param name="rc">The render context.</param>
 /// <param name="x">The center x-coordinate.</param>
 /// <param name="y">The center y-coordinate.</param>
 /// <param name="r">The radius.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The thickness.</param>
 /// <param name="edgeRenderingMode">The edge rendering mode.</param>
 public static void DrawCircle(this IRenderContext rc, double x, double y, double r, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode)
 {
     rc.DrawEllipse(new OxyRect(x - r, y - r, r * 2, r * 2), fill, stroke, thickness, edgeRenderingMode);
 }
示例#26
0
 /// <summary>
 /// Draws an ellipse.
 /// </summary>
 /// <param name="rect">The rectangle.</param>
 /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the ellipse will not be filled.</param>
 /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the ellipse will not be stroked.</param>
 /// <param name="thickness">The thickness (in device independent units, 1/96 inch).</param>
 public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1)
 {
 }
示例#27
0
 /// <summary>
 /// Draws a rectangle.
 /// </summary>
 /// <param name="rect">The rectangle.</param>
 /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the rectangle will not be filled.</param>
 /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the rectangle will not be stroked.</param>
 /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param>
 public void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1)
 {
 }
 /// <summary>
 /// Creates a color defined by an alpha value and another color.
 /// </summary>
 /// <param name="a">
 /// Alpha value.
 /// </param>
 /// <param name="color">
 /// The original color.
 /// </param>
 /// <returns>
 /// A color.
 /// </returns>
 public static OxyColor FromAColor(byte a, OxyColor color)
 {
     return new OxyColor { A = a, R = color.R, G = color.G, B = color.B };
 }
示例#29
0
 /// <summary>
 /// Initializes a new instance of the <see cref="StairStepSeries"/> class.
 /// </summary>
 /// <param name="color">
 /// The color.
 /// </param>
 /// <param name="strokeThickness">
 /// The stroke thickness.
 /// </param>
 /// <param name="title">
 /// The title.
 /// </param>
 public StairStepSeries(OxyColor color, double strokeThickness = 1, string title = null)
     : base(color, strokeThickness, title)
 {
     this.VerticalStrokeThickness = double.NaN;
     this.VerticalLineStyle       = this.LineStyle;
 }
示例#30
0
        /// <summary>
        /// Decodes an image from the specified byte array.
        /// </summary>
        /// <param name="bytes">The image data.</param>
        /// <returns>The 32-bit pixel data, indexed as [x,y].</returns>
        public OxyColor[,] Decode(byte[] bytes)
        {
            // http://www.w3.org/TR/PNG/
            // http://en.wikipedia.org/wiki/Portable_Network_Graphics
            var s           = new MemoryStream(bytes);
            var inputReader = new BinaryReader(s);
            var signature   = inputReader.ReadBytes(8);

            if (signature[0] != 0x89 || signature[1] != 0x50 || signature[2] != 0x4E || signature[3] != 0x47 ||
                signature[4] != 0x0D || signature[5] != 0x0A || signature[6] != 0x1A || signature[7] != 0x0A)
            {
                throw new FormatException("Invalid signature.");
            }

            var headerLength = inputReader.ReadBigEndianUInt32();

            if (headerLength != 13)
            {
                throw new FormatException("Header not supported.");
            }

            var headerType = inputReader.ReadString(4);

            if (headerType != "IHDR")
            {
                throw new FormatException("Invalid header.");
            }

            var width             = (int)inputReader.ReadBigEndianUInt32();
            var height            = (int)inputReader.ReadBigEndianUInt32();
            var bitDepth          = inputReader.ReadByte();
            var colorType         = (ColorType)inputReader.ReadByte();
            var compressionMethod = (CompressionMethod)inputReader.ReadByte();
            var filterMethod      = (FilterMethod)inputReader.ReadByte();
            var interlaceMethod   = (InterlaceMethod)inputReader.ReadByte();

            inputReader.ReadBigEndianUInt32(); // headerCRC

            if (bitDepth != 8)
            {
                throw new NotImplementedException();
            }

            if (colorType != ColorType.TrueColorWithAlpha)
            {
                throw new NotImplementedException();
            }

            if (compressionMethod != CompressionMethod.Deflate)
            {
                throw new NotImplementedException();
            }

            if (filterMethod != FilterMethod.None)
            {
                throw new NotImplementedException();
            }

            if (interlaceMethod != InterlaceMethod.None)
            {
                throw new NotImplementedException();
            }

            var ms = new MemoryStream();

            while (true)
            {
                var length = (int)inputReader.ReadBigEndianUInt32();
                var type   = inputReader.ReadString(4);
                if (type == "IEND")
                {
                    break;
                }

                switch (type)
                {
                case "PLTE":
                    throw new NotImplementedException();

                case "IDAT":
                {
                    inputReader.ReadByte();         // method
                    inputReader.ReadByte();         // check
                    var chunkBytes       = inputReader.ReadBytes(length - 6);
                    var expectedCheckSum = inputReader.ReadBigEndianUInt32();

                    var deflatedBytes  = Deflate(chunkBytes);
                    var actualCheckSum = PngEncoder.Adler32(deflatedBytes);

                    if (actualCheckSum != expectedCheckSum)
                    {
                        throw new FormatException("Invalid checksum.");
                    }

                    ms.Write(deflatedBytes, 0, deflatedBytes.Length);
                    break;
                }

                default:
                {
                    inputReader.ReadBytes(length);
                    break;
                }
                }

                inputReader.ReadBigEndianUInt32(); // crc
            }

            var pixels = new OxyColor[width, height];

            ms.Position = 0;
            for (int y = height - 1; y >= 0; y--)
            {
                ms.ReadByte();
                for (int x = 0; x < width; x++)
                {
                    var red   = (byte)ms.ReadByte();
                    var green = (byte)ms.ReadByte();
                    var blue  = (byte)ms.ReadByte();
                    var alpha = (byte)ms.ReadByte();

                    pixels[x, y] = OxyColor.FromArgb(alpha, red, green, blue);
                }
            }

            /*
             * var bitReader = new ByteBitReader(ms);
             * for (int y = 0; y < height; y++)
             * {
             *  var filterType = bitReader.readByte();
             *  for (int x = 0; x < width; x++)
             *  {
             *      var red = (byte)bitReader.ReadBits(bitDepth);
             *      var green = (byte)bitReader.ReadBits(bitDepth);
             *      var blue = (byte)bitReader.ReadBits(bitDepth);
             *      var alpha = (byte)bitReader.ReadBits(bitDepth);
             *
             *      pixels[x, y] = OxyColor.FromArgb(alpha, red, green, blue);
             *  }
             * }*/

            if (ms.Position != ms.Length)
            {
                throw new InvalidOperationException();
            }

            return(pixels);
        }
示例#31
0
 /// <summary>
 /// Fills a circle at the specified position.
 /// </summary>
 /// <param name="rc">The render context.</param>
 /// <param name="center">The center.</param>
 /// <param name="r">The radius.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="edgeRenderingMode">The edge rendering mode.</param>
 public static void FillCircle(this IRenderContext rc, ScreenPoint center, double r, OxyColor fill, EdgeRenderingMode edgeRenderingMode)
 {
     DrawCircle(rc, center.X, center.Y, r, fill, OxyColors.Undefined, 0d, edgeRenderingMode);
 }
        /// <summary>
        /// Draws the rectangle as an aliased polygon.
        /// (makes sure pixel alignment is the same as for lines)
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill.</param>
        /// <param name="stroke">The stroke.</param>
        /// <param name="thickness">The thickness.</param>
        public static void DrawRectangleAsPolygon(this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            var sp0 = new ScreenPoint(rect.Left, rect.Top);
            var sp1 = new ScreenPoint(rect.Right, rect.Top);
            var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
            var sp3 = new ScreenPoint(rect.Left, rect.Bottom);

            rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, stroke, thickness, null, OxyPenLineJoin.Miter, true);
        }
示例#33
0
        /// <summary>
        /// The internal draw math text.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="s">The s.</param>
        /// <param name="textColor">The text color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="measureOnly">The measure only.</param>
        /// <param name="angle">The angle of the text (degrees).</param>
        /// <returns>The size of the text.</returns>
        private static OxySize InternalDrawMathText(
            IRenderContext rc,
            double x,
            double y,
            string s,
            OxyColor textColor,
            string fontFamily,
            double fontSize,
            double fontWeight,
            bool measureOnly,
            double angle)
        {
            int    i           = 0;
            double angleRadian = (angle * Math.PI) / 180.0;
            double cosAngle    = Math.Round(Math.Cos(angleRadian), 5);
            double sinAngle    = Math.Round(Math.Sin(angleRadian), 5);

            double currentX = x, maximumX = x, minimumX = x;
            double currentY = y, maximumY = y, minimumY = y;

            // http://en.wikipedia.org/wiki/Subscript_and_superscript
            double superScriptXDisplacement = sinAngle * fontSize * SuperAlignment;
            double superScriptYDisplacement = cosAngle * fontSize * SuperAlignment;

            double subscriptXDisplacement   = sinAngle * fontSize * SubAlignment;
            double subscriptYDisplacement   = cosAngle * fontSize * SubAlignment;

            double superscriptFontSize      = fontSize * SuperSize;
            double subscriptFontSize        = fontSize * SubSize;

            Func <double, double, string, double, OxySize> drawText = (xb, yb, text, fSize) =>
            {
                if (!measureOnly)
                {
                    rc.DrawText(new ScreenPoint(xb, yb), text, textColor, fontFamily, fSize, fontWeight, angle);
                }

                var    flatSize = rc.MeasureText(text, fontFamily, fSize, fontWeight);
                double width    = Math.Abs((flatSize.Width * cosAngle) + (flatSize.Height * sinAngle));
                double height   = Math.Abs((flatSize.Width * sinAngle) + (flatSize.Height * cosAngle));
                return(new OxySize(width, height));
            };

            while (i < s.Length)
            {
                // Superscript
                if (i + 1 < s.Length && s[i] == '^' && s[i + 1] == '{')
                {
                    int i1 = s.IndexOf('}', i);
                    if (i1 != -1)
                    {
                        string supString = s.Substring(i + 2, i1 - i - 2);
                        i = i1 + 1;
                        double sx   = currentX + superScriptXDisplacement;
                        double sy   = currentY + superScriptYDisplacement;
                        var    size = drawText(sx, sy, supString, superscriptFontSize);
                        if (currentX + size.Width > maximumX)
                        {
                            maximumX = currentX + size.Width;
                        }

                        if (currentX + size.Width < minimumX)
                        {
                            minimumX = currentX + size.Width;
                        }

                        if (currentY + size.Height > maximumY)
                        {
                            maximumY = currentY + size.Height;
                        }

                        if (currentY + size.Height < minimumY)
                        {
                            minimumY = currentY + size.Height;
                        }

                        continue;
                    }
                }

                // Subscript
                if (i + 1 < s.Length && s[i] == '_' && s[i + 1] == '{')
                {
                    int i1 = s.IndexOf('}', i);
                    if (i1 != -1)
                    {
                        string subString = s.Substring(i + 2, i1 - i - 2);
                        i = i1 + 1;
                        double sx   = currentX - subscriptXDisplacement;
                        double sy   = currentY + subscriptYDisplacement;
                        var    size = drawText(sx, sy, subString, subscriptFontSize);
                        if (currentX + (size.Width * cosAngle) > maximumX)
                        {
                            maximumX = currentX + (size.Width * cosAngle);
                        }

                        if (currentX + (size.Width * cosAngle) < minimumX)
                        {
                            minimumX = currentX + (size.Width * cosAngle);
                        }

                        if (currentY + (size.Height * sinAngle) > maximumY)
                        {
                            maximumY = currentY + (size.Height * sinAngle);
                        }

                        if (currentY + (size.Height * sinAngle) < minimumY)
                        {
                            minimumY = currentY + (size.Height * sinAngle);
                        }

                        continue;
                    }
                }

                // Regular text
                int    i2 = s.IndexOfAny("^_".ToCharArray(), i);
                string regularString;
                if (i2 == -1)
                {
                    regularString = s.Substring(i);
                    i             = s.Length;
                }
                else
                {
                    regularString = s.Substring(i, i2 - i);
                    i             = i2;
                }

                currentX = maximumX + (2 * cosAngle);
                currentY = maximumY + (2 * sinAngle);
                var size2 = drawText(currentX, currentY, regularString, fontSize);

                currentX += (size2.Width + 2) * cosAngle;
                currentY += (size2.Height + 2) * sinAngle;

                maximumX = Math.Max(currentX, maximumX);
                maximumY = Math.Max(currentY, maximumY);
                minimumX = Math.Min(currentX, minimumX);
                minimumY = Math.Min(currentY, minimumY);
            }

            return(new OxySize(maximumX - minimumX, maximumY - minimumY));
        }
        /// <summary>
        /// Draws or measures text containing sub- and superscript.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="pt">The point.</param>
        /// <param name="text">The text.</param>
        /// <param name="textColor">Color of the text.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="ha">The horizontal alignment.</param>
        /// <param name="va">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        /// <param name="measure">Measure the size of the text if set to <c>true</c>.</param>
        /// <returns>The size of the text.</returns>
        /// <example>Subscript: H_{2}O
        /// Superscript: E=mc^{2}
        /// Both: A^{2}_{i,j}</example>
        public static OxySize DrawMathText(
            this IRenderContext rc,
            ScreenPoint pt,
            string text,
            OxyColor textColor,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double angle,
            HorizontalAlignment ha,
            VerticalAlignment va,
            OxySize?maxSize,
            bool measure)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(OxySize.Empty);
            }

            if (text.Contains("^{") || text.Contains("_{"))
            {
                var x = pt.X;
                var y = pt.Y;

                // Measure
                var size = InternalDrawMathText(rc, x, y, 0, 0, text, textColor, fontFamily, fontSize, fontWeight, true, angle);

                var dx = 0d;
                var dy = 0d;

                switch (ha)
                {
                case HorizontalAlignment.Right:
                    dx = -size.Width;
                    break;

                case HorizontalAlignment.Center:
                    dx = -size.Width * 0.5;
                    break;
                }

                switch (va)
                {
                case VerticalAlignment.Bottom:
                    dy = -size.Height;
                    break;

                case VerticalAlignment.Middle:
                    dy = -size.Height * 0.5;
                    break;
                }

                InternalDrawMathText(rc, x, y, dx, dy, text, textColor, fontFamily, fontSize, fontWeight, false, angle);
                return(measure ? size : OxySize.Empty);
            }

            rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxSize);
            if (measure)
            {
                return(rc.MeasureText(text, fontFamily, fontSize, fontWeight));
            }

            return(OxySize.Empty);
        }
示例#35
0
 /// <summary>
 /// Creates a color defined by an alpha value and another color.
 /// </summary>
 /// <param name="a">Alpha value.</param>
 /// <param name="color">The original color.</param>
 /// <returns>A color.</returns>
 public static OxyColor FromAColor(byte a, OxyColor color)
 {
     return(FromArgb(a, color.R, color.G, color.B));
 }
示例#36
0
 /// <summary>
 /// Draws a collection of rectangles, where all have the same stroke and fill.
 /// This performs better than calling DrawRectangle multiple times.
 /// </summary>
 /// <param name="rectangles">
 /// The rectangles.
 /// </param>
 /// <param name="fill">
 /// The fill color.
 /// </param>
 /// <param name="stroke">
 /// The stroke color.
 /// </param>
 /// <param name="thickness">
 /// The stroke thickness.
 /// </param>
 public virtual void DrawRectangles(IList <OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness)
 {
     foreach (var r in rectangles)
     {
         this.DrawRectangle(r, fill, stroke, thickness);
     }
 }
示例#37
0
        /// <summary>
        /// Draws a clipped polyline through the specified points.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRectangle">The clipping rectangle.</param>
        /// <param name="points">The points.</param>
        /// <param name="minDistSquared">The minimum line segment length (squared).</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="strokeThickness">The stroke thickness.</param>
        /// <param name="edgeRenderingMode">The edge rendering mode.</param>
        /// <param name="dashArray">The dash array (in device independent units, 1/96 inch).</param>
        /// <param name="lineJoin">The line join.</param>
        /// <param name="outputBuffer">The output buffer.</param>
        /// <param name="pointsRendered">The points rendered callback.</param>
        public static void DrawClippedLine(
            this IRenderContext rc,
            OxyRect clippingRectangle,
            IList <ScreenPoint> points,
            double minDistSquared,
            OxyColor stroke,
            double strokeThickness,
            EdgeRenderingMode edgeRenderingMode,
            double[] dashArray,
            LineJoin lineJoin,
            List <ScreenPoint> outputBuffer = null,
            Action <IList <ScreenPoint> > pointsRendered = null)
        {
            var n = points.Count;

            if (n == 0)
            {
                return;
            }

            if (outputBuffer != null)
            {
                outputBuffer.Clear();
                outputBuffer.Capacity = n;
            }
            else
            {
                outputBuffer = new List <ScreenPoint>(n);
            }

            if (rc.SetClip(clippingRectangle))
            {
                ReducePoints(points, minDistSquared, outputBuffer);
                rc.DrawLine(outputBuffer, stroke, strokeThickness, edgeRenderingMode, dashArray, lineJoin);
                rc.ResetClip();

                if (outputBuffer != null)
                {
                    outputBuffer.Clear();
                    outputBuffer.AddRange(points);
                }

                pointsRendered?.Invoke(outputBuffer);

                return;
            }

            // draws the points in the output buffer and calls the callback (if specified)
            Action drawLine = () =>
            {
                EnsureNonEmptyLineIsVisible(outputBuffer);
                rc.DrawLine(outputBuffer, stroke, strokeThickness, edgeRenderingMode, dashArray, lineJoin);

                // Execute the 'callback'
                if (pointsRendered != null)
                {
                    pointsRendered(outputBuffer);
                }
            };

            var clipping = new CohenSutherlandClipping(clippingRectangle);

            if (n == 1 && clipping.IsInside(points[0]))
            {
                outputBuffer.Add(points[0]);
            }

            int lastPointIndex = 0;

            for (int i = 1; i < n; i++)
            {
                // Calculate the clipped version of previous and this point.
                var  sc0      = points[i - 1];
                var  sc1      = points[i];
                bool isInside = clipping.ClipLine(ref sc0, ref sc1);

                if (!isInside)
                {
                    // the line segment is outside the clipping rectangle
                    // keep the previous coordinate for minimum distance comparison
                    continue;
                }

                // length calculation (inlined for performance)
                var dx = sc1.X - points[lastPointIndex].X;
                var dy = sc1.Y - points[lastPointIndex].Y;

                if ((dx * dx) + (dy * dy) > minDistSquared || outputBuffer.Count == 0 || i == n - 1)
                {
                    // point comparison inlined for performance
                    // ReSharper disable CompareOfFloatsByEqualityOperator
                    if (sc0.X != points[lastPointIndex].X || sc0.Y != points[lastPointIndex].Y || outputBuffer.Count == 0)
                    // ReSharper restore disable CompareOfFloatsByEqualityOperator
                    {
                        outputBuffer.Add(new ScreenPoint(sc0.X, sc0.Y));
                    }

                    outputBuffer.Add(new ScreenPoint(sc1.X, sc1.Y));
                    lastPointIndex = i;
                }

                if (clipping.IsInside(points[i]) || outputBuffer.Count == 0)
                {
                    continue;
                }

                // we are leaving the clipping region - render the line
                drawLine();
                outputBuffer.Clear();
            }

            if (outputBuffer.Count > 0)
            {
                drawLine();
            }
        }
示例#38
0
 /// <summary>
 /// Fills a rectangle at the specified position.
 /// </summary>
 /// <param name="rc">The render context.</param>
 /// <param name="rectangle">The rectangle.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="edgeRenderingMode">The edge rendering mode.</param>
 public static void FillRectangle(this IRenderContext rc, OxyRect rectangle, OxyColor fill, EdgeRenderingMode edgeRenderingMode)
 {
     rc.DrawRectangle(rectangle, fill, OxyColors.Undefined, 0d, edgeRenderingMode);
 }
 /// <summary>
 /// Fills a rectangle at the specified position.
 /// </summary>
 /// <param name="rc">The render context.</param>
 /// <param name="rectangle">The rectangle.</param>
 /// <param name="fill">The fill color.</param>
 public static void FillRectangle(this IRenderContext rc, OxyRect rectangle, OxyColor fill)
 {
     rc.DrawRectangle(rectangle, fill, OxyColors.Undefined, 0d);
 }
        /// <summary>
        /// Draws a list of markers.
        /// </summary>
        /// <param name="rc">
        /// The render context.
        /// </param>
        /// <param name="markerPoints">
        /// The marker points.
        /// </param>
        /// <param name="clippingRect">
        /// The clipping rectangle.
        /// </param>
        /// <param name="markerType">
        /// Type of the marker.
        /// </param>
        /// <param name="markerOutline">
        /// The marker outline.
        /// </param>
        /// <param name="markerSize">
        /// Size of the markers.
        /// </param>
        /// <param name="markerFill">
        /// The marker fill.
        /// </param>
        /// <param name="markerStroke">
        /// The marker stroke.
        /// </param>
        /// <param name="markerStrokeThickness">
        /// The marker stroke thickness.
        /// </param>
        /// <param name="resolution">
        /// The resolution.
        /// </param>
        /// <param name="binOffset">
        /// The bin Offset.
        /// </param>
        public static void DrawMarkers(
            this IRenderContext rc,
            IList <ScreenPoint> markerPoints,
            OxyRect clippingRect,
            MarkerType markerType,
            IList <ScreenPoint> markerOutline,
            IList <double> markerSize,
            OxyColor markerFill,
            OxyColor markerStroke,
            double markerStrokeThickness,
            int resolution        = 0,
            ScreenPoint binOffset = new ScreenPoint())
        {
            if (markerType == MarkerType.None)
            {
                return;
            }

            int n        = markerPoints.Count;
            var ellipses = new List <OxyRect>(n);
            var rects    = new List <OxyRect>(n);
            var polygons = new List <IList <ScreenPoint> >(n);
            var lines    = new List <ScreenPoint>(n);

            var hashset = new Dictionary <uint, bool>();

            int i = 0;

            double minx = clippingRect.Left;
            double maxx = clippingRect.Right;
            double miny = clippingRect.Top;
            double maxy = clippingRect.Bottom;

            foreach (var p in markerPoints)
            {
                if (resolution > 1)
                {
                    var  x    = (int)((p.X - binOffset.X) / resolution);
                    var  y    = (int)((p.Y - binOffset.Y) / resolution);
                    uint hash = (uint)(x << 16) + (uint)y;
                    if (hashset.ContainsKey(hash))
                    {
                        i++;
                        continue;
                    }

                    hashset.Add(hash, true);
                }

                bool outside = p.x <minx || p.x> maxx || p.y <miny || p.y> maxy;
                if (!outside)
                {
                    int j = i < markerSize.Count ? i : 0;
                    AddMarkerGeometry(p, markerType, markerOutline, markerSize[j], ellipses, rects, polygons, lines);
                }

                i++;
            }

            if (ellipses.Count > 0)
            {
                rc.DrawEllipses(ellipses, markerFill, markerStroke, markerStrokeThickness);
            }

            if (rects.Count > 0)
            {
                rc.DrawRectangles(rects, markerFill, markerStroke, markerStrokeThickness);
            }

            if (polygons.Count > 0)
            {
                rc.DrawPolygons(polygons, markerFill, markerStroke, markerStrokeThickness);
            }

            if (lines.Count > 0)
            {
                rc.DrawLineSegments(lines, markerStroke, markerStrokeThickness);
            }
        }
示例#41
0
 /// <summary>
 /// Draws a circle at the specified position.
 /// </summary>
 /// <param name="rc">The render context.</param>
 /// <param name="center">The center.</param>
 /// <param name="r">The radius.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The thickness.</param>
 /// <param name="edgeRenderingMode">The edge rendering mode.</param>
 public static void DrawCircle(this IRenderContext rc, ScreenPoint center, double r, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode)
 {
     DrawCircle(rc, center.X, center.Y, r, fill, stroke, thickness, edgeRenderingMode);
 }
示例#42
0
 /// <summary>
 /// Determines whether the specified <see cref="OxyColor" /> is equal to this instance.
 /// </summary>
 /// <param name="other">The <see cref="OxyColor" /> to compare with this instance.</param>
 /// <returns><c>true</c> if the specified <see cref="OxyColor" /> is equal to this instance; otherwise, <c>false</c> .</returns>
 public bool Equals(OxyColor other)
 {
     return(other.A == this.A && other.R == this.R && other.G == this.G && other.B == this.B);
 }
        /// <summary>
        /// Draws the clipped line.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="points">The points.</param>
        /// <param name="clippingRectangle">The clipping rectangle.</param>
        /// <param name="minDistSquared">The min dist squared.</param>
        /// <param name="stroke">The stroke.</param>
        /// <param name="strokeThickness">The stroke thickness.</param>
        /// <param name="lineStyle">The line style.</param>
        /// <param name="lineJoin">The line join.</param>
        /// <param name="aliased">if set to <c>true</c> [aliased].</param>
        /// <param name="pointsRendered">The points rendered callback.</param>
        public static void DrawClippedLine(
            this IRenderContext rc,
            IList <ScreenPoint> points,
            OxyRect clippingRectangle,
            double minDistSquared,
            OxyColor stroke,
            double strokeThickness,
            LineStyle lineStyle,
            OxyPenLineJoin lineJoin,
            bool aliased,
            Action <IList <ScreenPoint> > pointsRendered = null)
        {
            var clipping = new CohenSutherlandClipping(clippingRectangle.Left, clippingRectangle.Right, clippingRectangle.Top, clippingRectangle.Bottom);

            var pts = new List <ScreenPoint>();
            int n   = points.Count;

            if (n > 0)
            {
                if (n == 1)
                {
                    pts.Add(points[0]);
                }

                var last = points[0];
                for (int i = 1; i < n; i++)
                {
                    var s0 = points[i - 1];
                    var s1 = points[i];

                    // Clipped version of this and next point.
                    var  s0c      = s0;
                    var  s1c      = s1;
                    bool isInside = clipping.ClipLine(ref s0c, ref s1c);
                    s0 = s1;

                    if (!isInside)
                    {
                        // keep the previous coordinate
                        continue;
                    }

                    // render from s0c-s1c
                    double dx = s1c.x - last.x;
                    double dy = s1c.y - last.y;

                    if (dx * dx + dy * dy > minDistSquared || i == 1 || i == n - 1)
                    {
                        if (!s0c.Equals(last) || i == 1)
                        {
                            pts.Add(s0c);
                        }

                        pts.Add(s1c);
                        last = s1c;
                    }

                    // render the line if we are leaving the clipping region););
                    if (!clipping.IsInside(s1))
                    {
                        if (pts.Count > 0)
                        {
                            rc.DrawLine(
                                pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);
                            if (pointsRendered != null)
                            {
                                pointsRendered(pts);
                            }

                            pts = new List <ScreenPoint>();
                        }
                    }
                }

                // Check if the line contains two points and they are at the same point
                if (pts.Count == 2)
                {
                    if (pts[0].DistanceTo(pts[1]) < 1)
                    {
                        // Modify to a small horizontal line to make sure it is being rendered
                        pts[1] = new ScreenPoint(pts[0].X + 1, pts[0].Y);
                        pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y);
                    }
                }

                // Check if the line contains a single point
                if (pts.Count == 1)
                {
                    // Add a second point to make sure the line is being rendered as a small dot
                    pts.Add(new ScreenPoint(pts[0].X + 1, pts[0].Y));
                    pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y);
                }

                if (pts.Count > 0)
                {
                    rc.DrawLine(pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased);

                    // Execute the 'callback'.
                    if (pointsRendered != null)
                    {
                        pointsRendered(pts);
                    }
                }
            }
        }
        private void DrawDVHs()
        {
            this.plotModel.Series.Clear();

            string ptid1 = patient1.Split(',')[0];
            string ptid2 = patient2.Split(',')[0];

            try
            {
                // search for patient in database
                foreach (var patientSummary in cur_app.PatientSummaries)
                {
                    if (patientSummary.Id == ptid1)   //this is the first patient
                    {
                        VMS.TPS.Common.Model.API.Patient pt1 = cur_app.OpenPatient(patientSummary);
                        if (pt1 == null)
                        {
                            throw new ApplicationException("Cannot open patient No.1" + patientSummary.Id);
                        }
                        Console.WriteLine("Open patient No.1");

                        //get patient info
                        rd1.CurPatientInfo.LastName  = pt1.LastName;
                        rd1.CurPatientInfo.FirstName = pt1.FirstName;
                        rd1.CurPatientInfo.PatientID = pt1.Id;

                        //loop through courses
                        foreach (var course in pt1.Courses)
                        {
                            Console.WriteLine("course=" + course.Id);  //print course name and send to UI
                            rd1.CurPlanInfo.CourseID = course.Id;

                            foreach (var planSetup in course.PlanSetups)
                            {
                                Console.WriteLine("planID=" + planSetup.Id);
                                rd1.CurPlanInfo.PlaneID = planSetup.Id;
                                rd1.CurDosePrescription.Fractionation              = planSetup.UniqueFractionation.Id;
                                rd1.CurDosePrescription.TotalPrescribedDose        = planSetup.TotalPrescribedDose.ToString();
                                rd1.CurDosePrescription.PlanNormalization          = planSetup.PlanNormalizationValue.ToString();
                                rd1.CurDosePrescription.PrescribedDoseFractination = planSetup.UniqueFractionation.PrescribedDosePerFraction.ToString();
                                rd1.CurDosePrescription.NumberOfFraction           = planSetup.UniqueFractionation.NumberOfFractions.ToString();

                                foreach (var beam in planSetup.Beams)
                                {
                                    FieldInfo fieldInfo1 = new FieldInfo();
                                    fieldInfo1.BeamID     = beam.Id;
                                    fieldInfo1.Collimator = beam.ControlPoints[0].CollimatorAngle.ToString();
                                    fieldInfo1.Gantry     = beam.ControlPoints[0].GantryAngle.ToString();
                                    fieldInfo1.Couch      = beam.ControlPoints[0].PatientSupportAngle.ToString();
                                    fieldInfo1.DoseRate   = beam.DoseRate.ToString();
                                    fieldInfo1.Energy     = beam.EnergyModeDisplayName;
                                    fieldInfo1.Machine    = beam.TreatmentUnit.Id;
                                    fieldInfo1.MU         = beam.Meterset.ToString();
                                    fieldInfo1.X1         = beam.ControlPoints[0].JawPositions.X1.ToString();
                                    fieldInfo1.Y1         = beam.ControlPoints[0].JawPositions.Y1.ToString();
                                    fieldInfo1.X2         = beam.ControlPoints[0].JawPositions.X2.ToString();
                                    fieldInfo1.Y2         = beam.ControlPoints[0].JawPositions.Y2.ToString();

                                    rd1.CurFieldInfoList.Add(fieldInfo1);
                                }

                                // get structure Set
                                StructureSet structureSet = planSetup.StructureSet;

                                foreach (var structure in structureSet.Structures)
                                {
                                    //StructureData structureData1 = new StructureData();


                                    if (colors.ContainsKey(structure.Id.ToLower()) || colors.ContainsKey(structure.DicomType.ToLower()))
                                    {
                                        DVHData dvhData = planSetup.GetDVHCumulativeData(structure,
                                                                                         DoseValuePresentation.Absolute,
                                                                                         VolumePresentation.Relative, 0.2);

                                        if (dvhData == null)
                                        {
                                            continue;
                                            throw new ApplicationException("DVH data does not exist. Script execution cancelled.");
                                        }



                                        //To print and anlyze the DVH
                                        //
                                        if (colors.ContainsKey(structure.Id.ToLower()))
                                        {
                                            OxyPlot.OxyColor color = colors[structure.Id.ToLower()];
                                            Console.WriteLine("maximum dose of" + structure.Id + " is:" + dvhData.MaxDose.ToString());
                                            AddData(dvhData, structure.Id, color, OxyPlot.MarkerType.Circle);
                                        }
                                        else if (colors.ContainsKey(structure.DicomType.ToLower()))
                                        {
                                            OxyPlot.OxyColor color = colors[structure.DicomType.ToLower()];
                                            Console.WriteLine("maximum dose of" + structure.DicomType + " is:" + dvhData.MaxDose.ToString());
                                            AddData(dvhData, structure.Id, color, OxyPlot.MarkerType.Circle);
                                        }
                                    }
                                }
                            }
                        }
                        cur_app.ClosePatient(); //close the first patient
                    }


                    //Read second patient
                    if (patientSummary.Id == ptid2)   //this is the second patient
                    {
                        VMS.TPS.Common.Model.API.Patient pt2 = cur_app.OpenPatient(patientSummary);
                        if (pt2 == null)
                        {
                            throw new ApplicationException("Cannot open patient No.2" + patientSummary.Id);
                        }
                        Console.WriteLine("===========================");

                        Console.WriteLine("Open patient No.2");
                        //loop through courses
                        foreach (var course in pt2.Courses)
                        {
                            Console.WriteLine("course=" + course.Id);  //print course name and send to UI
                            foreach (var planSetup in course.PlanSetups)
                            {
                                Console.WriteLine("planID=" + planSetup.Id);

                                // get structure Set
                                StructureSet structureSet = planSetup.StructureSet;

                                foreach (var structure in structureSet.Structures)
                                {
                                    if (colors.ContainsKey(structure.Id.ToLower()) || colors.ContainsKey(structure.DicomType.ToLower()))
                                    {
                                        DVHData dvhData2 = planSetup.GetDVHCumulativeData(structure,
                                                                                          DoseValuePresentation.Absolute,
                                                                                          VolumePresentation.Relative, 1);

                                        if (dvhData2 == null)
                                        {
                                            continue;
                                            throw new ApplicationException("DVH data does not exist. Script execution cancelled.");
                                        }


                                        //To print and anlyze the DVH
                                        //

                                        if (colors.ContainsKey(structure.Id.ToLower()))
                                        {
                                            OxyPlot.OxyColor color = colors[structure.Id.ToLower()];
                                            Console.WriteLine("maximum dose of" + structure.Id + " is:" + dvhData2.MaxDose.ToString());
                                            AddData(dvhData2, structure.Id, color, OxyPlot.MarkerType.Cross);
                                        }
                                        else if (colors.ContainsKey(structure.DicomType.ToLower()))
                                        {
                                            OxyPlot.OxyColor color = colors[structure.DicomType.ToLower()];
                                            Console.WriteLine("maximum dose of" + structure.Id + " is:" + dvhData2.MaxDose.ToString());
                                            AddData(dvhData2, structure.Id, color, OxyPlot.MarkerType.Cross);
                                        }
                                    }
                                }
                            }
                        }
                        cur_app.ClosePatient(); //close the second patient
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                cur_app.ClosePatient();
            }

            plotModel.InvalidatePlot(true);
        }
示例#45
0
        // Load input file
        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Create new problem
            this.p = new Problem();
            this.BC_list.Clear();
            this.BC_list_nodes.Clear();
            this.BC_list_type.Clear();

            // Clear plot
            this.plotModel.Series.Clear();
            this.plotModel.Annotations.Clear();
            this.plotModel.InvalidatePlot(true);

            // Import input
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.ShowDialog();
            string fileName;

            fileName = openFileDialog.FileName;
            if (fileName == "")
            {
                this.plotModel.Annotations.Clear();
                this.plotModel.Series.Clear();
                this.plotModel.InvalidatePlot(true);
                return;
            }
            new inputTxtReader(fileName, this.p);

            // show and hide components plot
            this.plot.Visibility             = Visibility.Visible;
            this.button.Visibility           = Visibility.Visible;
            this.calculating_text.Visibility = Visibility.Visible;
            this.calculating_text.Text       = "Black = Frame\tPurple = Truss\tOrange = Spring\t\nHover mouse on blue nodes to view boundary condition\n";

            // determine max X Y
            double xmin, xmax, ymin, ymax;

            xmin = Node.all[0].x;
            xmax = Node.all[0].x;
            ymin = Node.all[0].y;
            ymax = Node.all[0].y;

            for (int i = 0; i < Node.all.Count; i++)
            {
                if (Node.all[i].x < xmin)
                {
                    xmin = Node.all[i].x;
                }
                if (Node.all[i].x > xmax)
                {
                    xmax = Node.all[i].x;
                }
                if (Node.all[i].y < ymin)
                {
                    ymin = Node.all[i].y;
                }
                if (Node.all[i].y > ymax)
                {
                    ymax = Node.all[i].y;
                }
            }

            this.l = Math.Max(xmax - xmin, ymax - ymin);


            // determine maxLoadMagnitude and arrowUnitLenght to scale loads
            double maxLoadMagnitude = 0;
            double arrowUnitLength  = this.l * 0.1;

            for (int i = 0; i < p.inputConcentratedLoads.Count; i++)
            {
                if (p.inputConcentratedLoads[i].magnitude > maxLoadMagnitude && p.inputConcentratedLoads[i].alpha != null)
                {
                    maxLoadMagnitude = p.inputConcentratedLoads[i].magnitude;
                }
            }
            for (int i = 0; i < p.inputDistributedLoads.Count; i++)
            {
                if (p.inputDistributedLoads[i][0].magnitude > maxLoadMagnitude && p.inputDistributedLoads[i][0].alpha != null)
                {
                    maxLoadMagnitude = p.inputDistributedLoads[i][0].magnitude;
                }
                if (p.inputDistributedLoads[i][1].magnitude > maxLoadMagnitude && p.inputDistributedLoads[i][1].alpha != null)
                {
                    maxLoadMagnitude = p.inputDistributedLoads[i][1].magnitude;
                }
            }

            this.plotModel.Axes[0].Reset();
            this.plotModel.Axes[1].Reset();

            if (maxLoadMagnitude == 0)
            {
                maxLoadMagnitude = 1;
            }

            this.plotModel.Axes[0].Maximum = xmax + this.l / 10.0;
            this.plotModel.Axes[0].Minimum = xmin - this.l / 10.0;
            this.plotModel.Axes[1].Maximum = ymax + this.l / 10.0;
            this.plotModel.Axes[1].Minimum = ymin - this.l / 10.0;

            // add lines
            double d = this.l * 0.014;
            int    dx1;
            int    dy1;
            int    dx2;
            int    dy2;

            for (int i = 0; i < Element.all.Count; i++)
            {
                if (Element.all[i].node1.x >= Element.all[i].node2.x)
                {
                    dx1 = -1;
                    dx2 = 1;
                }
                else
                {
                    dx1 = 1;
                    dx2 = -1;
                }
                if (Element.all[i].node1.y >= Element.all[i].node2.y)
                {
                    dy1 = -1;
                    dy2 = 1;
                }
                else
                {
                    dy1 = 1;
                    dy2 = -1;
                }

                // Pick color
                OxyPlot.OxyColor lineCol = OxyColors.Black;
                if (Element.all[i].type == "spring")
                {
                    lineCol = OxyColors.DarkOrange;
                }
                if (Element.all[i].type == "truss")
                {
                    lineCol = OxyColors.DarkOrchid;
                }

                addLine(this, Element.all[i].node1.x + dx1 * Math.Abs(d * Math.Cos(Element.all[i].alpha)),
                        Element.all[i].node1.y + dy1 * Math.Abs(d * Math.Sin(Element.all[i].alpha)),
                        Element.all[i].node2.x + dx2 * Math.Abs(d * Math.Cos(Element.all[i].alpha)),
                        Element.all[i].node2.y + dy2 * Math.Abs(d * Math.Sin(Element.all[i].alpha)), lineCol);
                addNode(this, Element.all[i].node1.x, Element.all[i].node1.y, "Node " + Element.all[i].node1.number + "\n",
                        5, OxyColors.Black);
            }


            // add BCs
            addBCs(this, 5);

            // add loads
            for (int i = 0; i < p.inputConcentratedLoads.Count; i++)
            {
                addLoad(this, p.inputConcentratedLoads[i], OxyColors.Aqua, circleSize: 5,
                        maxLoadMagnitude: maxLoadMagnitude, arrowUnitLength: arrowUnitLength);
            }
            for (int i = 0; i < p.inputDistributedLoads.Count; i++)
            {
                addDistributedLoad(this, p.inputDistributedLoads[i], OxyColors.DeepSkyBlue,
                                   circleSize: 5, maxLoadMagnitude: maxLoadMagnitude, arrowUnitLength: arrowUnitLength);
            }

            this.plotModel.InvalidatePlot(true); // refresh
        }
示例#46
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PlotModel" /> class.
        /// </summary>
        public PlotModel()
        {
            this.Axes        = new ElementCollection <Axis>(this);
            this.Series      = new ElementCollection <Series.Series>(this);
            this.Annotations = new ElementCollection <Annotation>(this);

            this.PlotType = PlotType.XY;

            this.PlotMargins = new OxyThickness(double.NaN);
            this.Padding     = new OxyThickness(8);

            this.Background         = OxyColors.Undefined;
            this.PlotAreaBackground = OxyColors.Undefined;

            this.TextColor     = OxyColors.Black;
            this.TitleColor    = OxyColors.Automatic;
            this.SubtitleColor = OxyColors.Automatic;

            this.DefaultFont     = "Segoe UI";
            this.DefaultFontSize = 12;

            this.TitleToolTip       = null;
            this.TitleFont          = null;
            this.TitleFontSize      = 18;
            this.TitleFontWeight    = FontWeights.Bold;
            this.SubtitleFont       = null;
            this.SubtitleFontSize   = 14;
            this.SubtitleFontWeight = FontWeights.Normal;
            this.TitlePadding       = 6;

            this.PlotAreaBorderColor     = OxyColors.Black;
            this.PlotAreaBorderThickness = new OxyThickness(1);

            this.IsLegendVisible       = true;
            this.LegendTitleFont       = null;
            this.LegendTitleFontSize   = 12;
            this.LegendTitleFontWeight = FontWeights.Bold;
            this.LegendFont            = null;
            this.LegendFontSize        = 12;
            this.LegendFontWeight      = FontWeights.Normal;
            this.LegendSymbolLength    = 16;
            this.LegendSymbolMargin    = 4;
            this.LegendPadding         = 8;
            this.LegendColumnSpacing   = 8;
            this.LegendItemSpacing     = 24;
            this.LegendLineSpacing     = 0;
            this.LegendMargin          = 8;

            this.LegendBackground      = OxyColors.Undefined;
            this.LegendBorder          = OxyColors.Undefined;
            this.LegendBorderThickness = 1;

            this.LegendTextColor  = OxyColors.Automatic;
            this.LegendTitleColor = OxyColors.Automatic;

            this.LegendMaxWidth        = double.NaN;
            this.LegendMaxHeight       = double.NaN;
            this.LegendPlacement       = LegendPlacement.Inside;
            this.LegendPosition        = LegendPosition.RightTop;
            this.LegendOrientation     = LegendOrientation.Vertical;
            this.LegendItemOrder       = LegendItemOrder.Normal;
            this.LegendItemAlignment   = HorizontalAlignment.Left;
            this.LegendSymbolPlacement = LegendSymbolPlacement.Left;

            this.DefaultColors = new List <OxyColor>
            {
                OxyColor.FromRgb(0x4E, 0x9A, 0x06),
                OxyColor.FromRgb(0xC8, 0x8D, 0x00),
                OxyColor.FromRgb(0xCC, 0x00, 0x00),
                OxyColor.FromRgb(0x20, 0x4A, 0x87),
                OxyColors.Red,
                OxyColors.Orange,
                OxyColors.Yellow,
                OxyColors.Green,
                OxyColors.Blue,
                OxyColors.Indigo,
                OxyColors.Violet
            };

            this.AxisTierDistance = 4.0;
        }
示例#47
0
 /// <summary>
 /// Gets the selection fill color it the element is selected, or the specified fill color if it is not.
 /// </summary>
 /// <param name="originalColor">The unselected fill color of the element.</param>
 /// <param name="index">The index of the item to check (use -1 for all items).</param>
 /// <returns>A fill color.</returns>
 protected OxyColor GetSelectableFillColor(OxyColor originalColor, int index = -1)
 {
     // TODO: rename to GetActualFillColor (13 usages)
     return(this.GetSelectableColor(originalColor, index));
 }
        /// <summary>
        /// Determines whether the specified <see cref="OxyColor"/> is equal to this instance.
        /// </summary>
        /// <param name="other">
        /// The <see cref="OxyColor"/> to compare with this instance.
        /// </param>
        /// <returns>
        /// <c>true</c> if the specified <see cref="OxyColor"/> is equal to this instance; otherwise, <c>false</c> .
        /// </returns>
        public bool Equals(OxyColor other)
        {
            if (ReferenceEquals(null, other))
            {
                return false;
            }

            if (ReferenceEquals(this, other))
            {
                return true;
            }

            return other.A == this.A && other.R == this.R && other.G == this.G && other.B == this.B;
        }
示例#49
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="p">The position of the text.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        public override void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            HorizontalAlignment halign,
            VerticalAlignment valign,
            OxySize?maxSize)
        {
            this.doc.SaveState();
            this.doc.SetFont(fontFamily, fontSize / 96 * 72, fontWeight > 500);
            this.doc.SetFillColor(fill);

            double width, height;

            this.doc.MeasureText(text, out width, out height);
            if (maxSize != null)
            {
                if (width > maxSize.Value.Width)
                {
                    width = Math.Max(maxSize.Value.Width, 0);
                }

                if (height > maxSize.Value.Height)
                {
                    height = Math.Max(maxSize.Value.Height, 0);
                }
            }

            double dx = 0;

            if (halign == HorizontalAlignment.Center)
            {
                dx = -width / 2;
            }

            if (halign == HorizontalAlignment.Right)
            {
                dx = -width;
            }

            double dy = 0;

            if (valign == VerticalAlignment.Middle)
            {
                dy = -height / 2;
            }

            if (valign == VerticalAlignment.Top)
            {
                dy = -height;
            }

            double y = this.doc.PageHeight - p.Y;

            this.doc.Translate(p.X, y);
            if (Math.Abs(rotate) > 1e-6)
            {
                this.doc.Rotate(-rotate);
            }

            this.doc.Translate(dx, dy);

            // this.doc.DrawRectangle(0, 0, width, height);
            this.doc.SetClippingRectangle(0, 0, width, height);
            this.doc.DrawText(0, 0, text);
            this.doc.RestoreState();
        }
        /// <summary>
        /// The set default values.
        /// </summary>
        /// <param name="model">
        /// The model.
        /// </param>
        protected internal override void SetDefaultValues(PlotModel model)
        {
            // todo: should use ActualLineStyle
            if (this.Color == null)
            {
                if (this.LineStyle == LineStyle.Undefined)
                {
                    this.LineStyle = model.GetDefaultLineStyle();
                }

                this.defaultColor = model.GetDefaultColor();

                // And MarkerFill will be overridden if not set to null
                if (this.MarkerFill == null)
                {
                    this.MarkerFill = this.defaultColor;
                }
            }
        }
        /// <summary>
        /// Draws text with sub- and superscript items.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        /// <param name="dx">The x offset (in rotated coordinates).</param>
        /// <param name="dy">The y offset (in rotated coordinates).</param>
        /// <param name="s">The s.</param>
        /// <param name="textColor">The text color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="measureOnly">Only measure if set to <c>true</c>.</param>
        /// <param name="angle">The angle of the text (degrees).</param>
        /// <returns>The size of the text.</returns>
        private static OxySize InternalDrawMathText(
            IRenderContext rc,
            double x,
            double y,
            double dx,
            double dy,
            string s,
            OxyColor textColor,
            string fontFamily,
            double fontSize,
            double fontWeight,
            bool measureOnly,
            double angle)
        {
            var i           = 0;
            var angleRadian = (angle * Math.PI) / 180.0;
            var cosAngle    = Math.Round(Math.Cos(angleRadian), 5);
            var sinAngle    = Math.Round(Math.Sin(angleRadian), 5);

            var currentX = x;
            var maximumX = x;
            var minimumX = x;
            var currentY = y;
            var maximumY = y;
            var minimumY = y;

            // http://en.wikipedia.org/wiki/Subscript_and_superscript
            var superScriptYDisplacement = fontSize * SuperAlignment;

            var subscriptYDisplacement = fontSize * SubAlignment;

            var superscriptFontSize = fontSize * SuperSize;
            var subscriptFontSize   = fontSize * SubSize;

            Func <double, double, string, double, OxySize> drawText = (xb, yb, text, fSize) =>
            {
                if (!measureOnly)
                {
                    var xr = x + ((xb - x + dx) * cosAngle) - ((yb - y + dy) * sinAngle);
                    var yr = y + ((xb - x + dx) * sinAngle) + ((yb - y + dy) * cosAngle);
                    rc.DrawText(new ScreenPoint(xr, yr), text, textColor, fontFamily, fSize, fontWeight, angle);
                }

                var flatSize = rc.MeasureText(text, fontFamily, fSize, fontWeight);
                return(new OxySize(flatSize.Width, flatSize.Height));
            };

            while (i < s.Length)
            {
                // Superscript
                if (i + 1 < s.Length && s[i] == '^' && s[i + 1] == '{')
                {
                    var i1 = s.IndexOf('}', i);
                    if (i1 != -1)
                    {
                        var supString = s.Substring(i + 2, i1 - i - 2);
                        i = i1 + 1;
                        var sx   = currentX;
                        var sy   = currentY + superScriptYDisplacement;
                        var size = drawText(sx, sy, supString, superscriptFontSize);
                        maximumX = Math.Max(sx + size.Width, maximumX);
                        maximumY = Math.Max(sy + size.Height, maximumY);
                        minimumX = Math.Min(sx, minimumX);
                        minimumY = Math.Min(sy, minimumY);

                        continue;
                    }
                }

                // Subscript
                if (i + 1 < s.Length && s[i] == '_' && s[i + 1] == '{')
                {
                    var i1 = s.IndexOf('}', i);
                    if (i1 != -1)
                    {
                        var subString = s.Substring(i + 2, i1 - i - 2);
                        i = i1 + 1;
                        var sx   = currentX;
                        var sy   = currentY + subscriptYDisplacement;
                        var size = drawText(sx, sy, subString, subscriptFontSize);
                        maximumX = Math.Max(sx + size.Width, maximumX);
                        maximumY = Math.Max(sy + size.Height, maximumY);
                        minimumX = Math.Min(sx, minimumX);
                        minimumY = Math.Min(sy, minimumY);

                        continue;
                    }
                }

                // Regular text
                var    i2 = s.IndexOfAny("^_".ToCharArray(), i);
                string regularString;
                if (i2 == -1)
                {
                    regularString = s.Substring(i);
                    i             = s.Length;
                }
                else
                {
                    regularString = s.Substring(i, i2 - i);
                    i             = i2;
                }

                currentX = maximumX + 2;
                var size2 = drawText(currentX, currentY, regularString, fontSize);

                maximumX = Math.Max(currentX + size2.Width, maximumX);
                maximumY = Math.Max(currentY + size2.Height, maximumY);
                minimumX = Math.Min(currentX, minimumX);
                minimumY = Math.Min(currentY, minimumY);

                currentX = maximumX;
            }

            return(new OxySize(maximumX - minimumX, maximumY - minimumY));
        }
示例#52
0
 /// <summary>
 /// Draws text.
 /// </summary>
 /// <param name="p">The position.</param>
 /// <param name="text">The text.</param>
 /// <param name="fill">The text color.</param>
 /// <param name="fontFamily">The font family.</param>
 /// <param name="fontSize">Size of the font (in device independent units, 1/96 inch).</param>
 /// <param name="fontWeight">The font weight.</param>
 /// <param name="rotate">The rotation angle.</param>
 /// <param name="halign">The horizontal alignment.</param>
 /// <param name="valign">The vertical alignment.</param>
 /// <param name="maxSize">The maximum size of the text (in device independent units, 1/96 inch).</param>
 public void DrawText(
     ScreenPoint p,
     string text,
     OxyColor fill,
     string fontFamily = null,
     double fontSize = 10,
     double fontWeight = 500,
     double rotate = 0,
     HorizontalAlignment halign = HorizontalAlignment.Left,
     VerticalAlignment valign = VerticalAlignment.Top,
     OxySize? maxSize = null)
 {
 }
        /// <summary>
        /// Draws the rectangle as an aliased polygon.
        /// (makes sure pixel alignment is the same as for lines)
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill.</param>
        /// <param name="stroke">The stroke.</param>
        /// <param name="thickness">The thickness.</param>
        public static void DrawRectangleAsPolygon(this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, OxyThickness thickness)
        {
            if (thickness.Left.Equals(thickness.Right) && thickness.Left.Equals(thickness.Top) && thickness.Left.Equals(thickness.Bottom))
            {
                DrawRectangleAsPolygon(rc, rect, fill, stroke, thickness.Left);
                return;
            }

            var sp0 = new ScreenPoint(rect.Left, rect.Top);
            var sp1 = new ScreenPoint(rect.Right, rect.Top);
            var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
            var sp3 = new ScreenPoint(rect.Left, rect.Bottom);

            rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, OxyColors.Undefined, 0, null, OxyPenLineJoin.Miter, true);
            rc.DrawLine(new[] { sp0, sp1 }, stroke, thickness.Top, null, OxyPenLineJoin.Miter, true);
            rc.DrawLine(new[] { sp1, sp2 }, stroke, thickness.Right, null, OxyPenLineJoin.Miter, true);
            rc.DrawLine(new[] { sp2, sp3 }, stroke, thickness.Bottom, null, OxyPenLineJoin.Miter, true);
            rc.DrawLine(new[] { sp3, sp0 }, stroke, thickness.Left, null, OxyPenLineJoin.Miter, true);
        }
示例#54
0
 /// <summary>
 /// Draws a collection of ellipses, where all have the same stroke and fill.
 /// This performs better than calling DrawEllipse multiple times.
 /// </summary>
 /// <param name="rectangles">The rectangles.</param>
 /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the ellipses will not be filled.</param>
 /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the ellipses will not be stroked.</param>
 /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param>
 public void DrawEllipses(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness = 1)
 {
 }
示例#55
0
        /// <summary>
        /// Draws multi-line text at the specified point.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="point">The point.</param>
        /// <param name="text">The text.</param>
        /// <param name="color">The text color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="dy">The line spacing.</param>
        public static void DrawMultilineText(this IRenderContext rc, ScreenPoint point, string text, OxyColor color, string fontFamily = null, double fontSize = 10, double fontWeight = FontWeights.Normal, double dy = 12)
        {
            var lines = StringHelper.SplitLines(text);

            for (int i = 0; i < lines.Length; i++)
            {
                rc.DrawText(
                    new ScreenPoint(point.X, point.Y + (i * dy)),
                    lines[i],
                    color,
                    fontWeight: fontWeight,
                    fontSize: fontSize);
            }
        }
示例#56
0
 /// <summary>
 /// Draws an ellipse.
 /// </summary>
 /// <param name="rect">
 /// The rectangle.
 /// </param>
 /// <param name="fill">
 /// The fill color.
 /// </param>
 /// <param name="stroke">
 /// The stroke color.
 /// </param>
 /// <param name="thickness">
 /// The thickness.
 /// </param>
 public abstract void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness);
示例#57
0
 /// <summary>
 /// Gets the actual color.
 /// </summary>
 /// <param name="defaultColor">The default color.</param>
 /// <returns>The default color if the current color equals OxyColors.Automatic, otherwise the color itself.</returns>
 public OxyColor GetActualColor(OxyColor defaultColor)
 {
     return(this.IsAutomatic() ? defaultColor : this);
 }