public ArcTo(Size radius, bool largeArc, bool sweepClockwise, Point point) { Radius = radius; LargeArc = largeArc; SweepClockwise = sweepClockwise; Point = point; }
/// <summary> /// Calculates the aspect. /// </summary> /// <returns>The aspect.</returns> /// <param name="size">Size.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> public static NGraphics.Size CalcAspect(NGraphics.Size size, double width, double height) { double w; double h; if (width <= 0 && height <= 0) { return(size); } else if (width <= 0) { h = height; w = height * (size.Width / size.Height); } else if (height <= 0) { w = width; h = width * (size.Height / size.Width); } else { w = width; h = height; } return(new NGraphics.Size(w, h)); }
public static Size ScaleDownProportional (this Size size, Size max) { if (size.Width <= max.Width && size.Height <= max.Height) { return size; } return size.ScaleProportional (max); }
public Rect GetSection(Size parentSize, ResizableSvgSection section) { switch (section) { case ResizableSvgSection.TopLeft: return(new Rect(Point.Zero, new Size(Left, Top))); case ResizableSvgSection.TopCenter: return(new Rect(new Point(Left, 0), new Size(parentSize.Width - Right - Left, Top))); case ResizableSvgSection.TopRight: return(new Rect(new Point(parentSize.Width - Right, 0), new Size(Right, Top))); case ResizableSvgSection.CenterLeft: return(new Rect(new Point(0, Top), new Size(Right, parentSize.Height - Bottom - Top))); case ResizableSvgSection.CenterCenter: return(new Rect(new Point(Left, Top), new Size(parentSize.Width - Right - Left, parentSize.Height - Bottom - Top))); case ResizableSvgSection.CenterRight: return(new Rect(new Point(parentSize.Width - Right, Top), new Size(Right, parentSize.Height - Bottom - Top))); case ResizableSvgSection.BottomLeft: return(new Rect(new Point(0, parentSize.Height - Bottom), new Size(Right, Bottom))); case ResizableSvgSection.BottomCenter: return(new Rect(new Point(Left, parentSize.Height - Bottom), new Size(parentSize.Width - Right - Left, Bottom))); case ResizableSvgSection.BottomRight: return(new Rect(new Point(parentSize.Width - Right, parentSize.Height - Bottom), new Size(Right, Bottom))); default: throw new ArgumentOutOfRangeException("section", "Invalid resizable SVG section"); } }
public WICBitmapCanvas (Size size, double scale = 1.0, bool transparency = true, Direct2DFactories factories = null) : this ( // DIPs = pixels / (DPI/96.0) new WIC.Bitmap ((factories ?? Direct2DFactories.Shared).WICFactory, (int)(Math.Ceiling (size.Width * scale)), (int)(Math.Ceiling (size.Height * scale)), transparency ? WIC.PixelFormat.Format32bppPBGRA : WIC.PixelFormat.Format32bppBGR, WIC.BitmapCreateCacheOption.CacheOnLoad), new D2D1.RenderTargetProperties (D2D1.RenderTargetType.Default, new D2D1.PixelFormat (DXGI.Format.Unknown, D2D1.AlphaMode.Unknown), (float)(96.0 * scale), (float)(96.0 * scale), D2D1.RenderTargetUsage.None, D2D1.FeatureLevel.Level_DEFAULT)) { }
/// <summary> /// Loads a SVG as a bitmap with the specified width and height. /// /// If a desired width and height of -1 is specified, the dimensions of the resulting bitmap /// will be the actual width and height of the file, without any kind of stretching. /// The bitmap will be resized if the actual resolution of the file is less than 1000 pixels /// in both width and height, but this is done losslessly since SVGs are vector-based. /// </summary> /// <param name="path">Path to the svg file</param> /// <param name="width">The desired width, or -1 for actual width</param> /// <param name="height">The desired height, or -1 for actual height</param> private static Bitmap GetBitmapFromSvg(string path, int width = -1, int height = -1) { using (var text = File.OpenText(path)) { var graphic = Graphic.LoadSvg(text); NGraphics.Size size; if (width == -1 || height == -1) { //If no resolution is given, return the actual aspect ratio of the SVG file, but with a minimum resolution of 1000 to give pixel-based operations something to work with. var resolution = graphic.Size.Width < 1000 && graphic.Size.Height < 1000 ? FitDimensions(FitMode.Fill, 1000, 1000, (int)graphic.Size.Width, (int)graphic.Size.Height) : new Tuple <int, int>((int)graphic.Size.Width, (int)graphic.Size.Height); size = new NGraphics.Size(resolution.Item1, resolution.Item2); } else { size = new NGraphics.Size(width, height); } var canvas = Platforms.Current.CreateImageCanvas(size); graphic.TransformGeometry(Transform.Scale(size)); graphic.Size = size; graphic.Draw(canvas); var image = canvas.GetImage(); using (var ms = new MemoryStream()) { image.SaveAsPng(ms); var img = new Bitmap(ms); return(ConvertBitmapToPixelFormat_32bppArgb(img)); } } }
public ShapeView(AppKit.NSImageView imageView) : base(imageView) { var size = new NGraphics.Size(1, 1); canvas = Platforms.Current.CreateImageCanvas(size, scale: 2); Refresh(size); }
public RadialGradientBrush (Point relCenter, Size relRadius, params GradientStop[] stops) { Center = relCenter; Focus = relCenter; Radius = relRadius; Stops.AddRange (stops); }
public async Task <IImage> GetSvgImage(string path, float width, float height, CancellationToken token) { return(await Task <IImage> .Factory.StartNew(() => { var assembly = typeof(ToolbarItemEx).Assembly; var fullPath = $"ToolbarBadgeSample.Resources.Images.{path}"; using (var resource = assembly.GetManifestResourceStream(fullPath)) { if (resource == null) { throw new Exception( $"Error retrieving {path} make sure Build Action is Embedded Resource. Full path {fullPath}"); } var svg = new SvgReader(new StreamReader(resource)); var outputSize = svg.Graphic.Size; if (width > 0 && height > 0) { outputSize = new Size(width, height); var scale = svg.Graphic.Size.ScaleThatFits(outputSize); svg.Graphic.ViewBox = new Rect(Point.Zero, svg.Graphic.Size / scale); } var imageCanvas = _platform.CreateImageCanvas(outputSize, _scale); svg.Graphic.Draw(imageCanvas); return imageCanvas.GetImage(); } }, token)); }
public static void Scale (this ICanvas canvas, Size scale, Point point) { if (scale.Width != 1 || scale.Height != 1) { canvas.Translate (point); canvas.Scale (scale); canvas.Translate (-point); } }
public WICBitmapCanvas (WIC.Bitmap bmp, D2D1.RenderTargetProperties properties, Direct2DFactories factories = null) : base (new D2D1.WicRenderTarget ((factories ?? Direct2DFactories.Shared).D2DFactory, bmp, properties), factories) { this.Bmp = bmp; this.scale = properties.DpiX / 96.0; var bmpSize = bmp.Size; this.size = new Size (bmpSize.Width / scale, bmpSize.Height / scale); }
public Drawing(Size size, DrawingFunc func) { if (func == null) { throw new ArgumentNullException ("func"); } this.size = size; this.func = func; }
public RadialGradientBrush (Point relCenter, Size relRadius, Color startColor, Color endColor) { Center = relCenter; Focus = relCenter; Radius = relRadius; Stops.Add (new GradientStop (0, startColor)); Stops.Add (new GradientStop (1, endColor)); }
void Refresh(NGraphics.Size size) { OnDraw(canvas); var imageNative = canvas.GetImage().GetNSImage(); imageNative.Size = size.ToCGSize(); Image = new LiteForms.Cocoa.Image(imageNative); }
public Drawing (Size size, DrawingFunc func, IPlatform textPlatform) { if (func == null) { throw new ArgumentNullException ("func"); } this.size = size; this.func = func; this.textPlatform = textPlatform ?? new NullPlatform (); }
public static Size ScaleProportional (this Size size, Size max) { double fitScale = size.ScaleThatFits (max); if (fitScale == 1) { return size; } Size scaledSize = new Size (size.Width * fitScale, size.Height * fitScale); return scaledSize; }
public IImageCanvas CreateImageCanvas(Size size, double scale = 1.0, bool transparency = true) { var pixelWidth = (int)Math.Ceiling (size.Width * scale); var pixelHeight = (int)Math.Ceiling (size.Height * scale); var bitmap = Bitmap.CreateBitmap (pixelWidth, pixelHeight, Bitmap.Config.Argb8888); if (!transparency) { bitmap.EraseColor (Colors.Black.Argb); } return new BitmapCanvas (bitmap, scale); }
public static double ScaleThatFits (this Size size, Size max) { if (size == max || max.Width == 0 || max.Height == 0 || size.Width == 0 || size.Height == 0) { return 1; } double widthScale = max.Width / size.Width; double heightScale = max.Height / size.Height; double fitScale = (double)Math.Min (widthScale, heightScale); return fitScale; }
public IImageCanvas CreateImageCanvas(Size size, double scale = 1.0, bool transparency = true) { var pixelWidth = (int)Math.Ceiling (size.Width * scale); var pixelHeight = (int)Math.Ceiling (size.Height * scale); var bitmapInfo = transparency ? CGImageAlphaInfo.PremultipliedFirst : CGImageAlphaInfo.NoneSkipFirst; var bitsPerComp = 8; var bytesPerRow = transparency ? 4 * pixelWidth : 4 * pixelWidth; var colorSpace = CGColorSpace.CreateDeviceRGB (); var bitmap = new CGBitmapContext (IntPtr.Zero, pixelWidth, pixelHeight, bitsPerComp, bytesPerRow, colorSpace, bitmapInfo); return new CGBitmapContextCanvas (bitmap, scale); }
public override void Draw(Android.Graphics.Canvas canvas) { base.Draw(canvas); if (_formsControl != null) { var outputSize = new Size(canvas.Width, canvas.Height); var finalCanvas = _formsControl.RenderSvgToCanvas(outputSize, ScreenScale, CreatePlatformImageCanvas); var image = (BitmapImage)finalCanvas.GetImage(); Control.SetImageBitmap(image.Bitmap); } }
public static IImage CreateImage(this IPlatform platform, Func<int, int, Color> colorFunc, Size size, double scale = 1.0) { var w = (int)Math.Ceiling (size.Width); var h = (int)Math.Ceiling (size.Height); var colors = new Color[w * h]; for (var y = 0; y < h; y++) { var o = y * w; for (var x = 0; x < w; x++) { colors [o + x] = colorFunc (x, y); } } return platform.CreateImage (colors, w, scale); }
public IImage GetRoundedImage(Size size, NGraphics.Color color, float radius) { var paint = new Paint(); paint.AntiAlias = true; paint.SetARGB(color.A, color.R, color.G, color.B); paint.SetStyle(Paint.Style.Fill); var conf = Bitmap.Config.Argb8888; var bitmap = Bitmap.CreateBitmap(Forms.Context.Resources.DisplayMetrics, (int)size.Width, (int)size.Height, conf); var canvas = new Canvas(bitmap); var rect = new RectF(0, 0, (float)size.Width, (float)size.Height); canvas.DrawRoundRect(rect, radius, radius, paint); var image = new BitmapImage(bitmap, _scale); return(image); }
public override void Draw (CGRect rect) { base.Draw (rect); if (_formsControl != null) { using (CGContext context = UIGraphics.GetCurrentContext ()) { context.SetAllowsAntialiasing (true); context.SetShouldAntialias (true); context.SetShouldSmoothFonts (true); var outputSize = new Size (rect.Width, rect.Height); var finalCanvas = _formsControl.RenderSvgToCanvas (outputSize, ScreenScale, CreatePlatformImageCanvas); var image = finalCanvas.GetImage (); var uiImage = image.GetUIImage (); Control.Image = uiImage; } } }
void Read (XDocument doc) { var svg = doc.Root; var ns = svg.Name.Namespace; // // Find the defs (gradients) // foreach (var d in svg.Descendants ()) { var idA = d.Attribute ("id"); if (idA != null) { defs [ReadString (idA).Trim ()] = d; } } // // Get the dimensions // var widthA = svg.Attribute ("width"); var heightA = svg.Attribute ("height"); var width = ReadNumber (widthA); var height = ReadNumber (heightA); var size = new Size (width, height); var viewBox = new Rect (size); var viewBoxA = svg.Attribute ("viewBox") ?? svg.Attribute ("viewPort"); if (viewBoxA != null) { viewBox = ReadRectangle (viewBoxA.Value); } if (widthA != null && widthA.Value.Contains ("%")) { size.Width *= viewBox.Width; } if (heightA != null && heightA.Value.Contains ("%")) { size.Height *= viewBox.Height; } // // Add the elements // Graphic = new Graphic (size, viewBox); AddElements (Graphic.Children, svg.Elements (), null, Brushes.Black); }
public override void Draw(CGRect rect) { base.Draw(rect); if (_formsControl != null) { using (CGContext context = UIGraphics.GetCurrentContext()) { context.SetAllowsAntialiasing(true); context.SetShouldAntialias(true); context.SetShouldSmoothFonts(true); var outputSize = new Size(rect.Width, rect.Height); var finalCanvas = _formsControl.RenderSvgToCanvas(outputSize, ScreenScale, CreatePlatformImageCanvas); var image = finalCanvas.GetImage(); var uiImage = image.GetUIImage(); Control.Image = uiImage; } } }
public IImageCanvas RenderSvgToCanvas(Size outputSize, double finalScale, Func <Size, double, IImageCanvas> createPlatformImageCanvas) { var originalSvgSize = LoadedGraphic.Size; var finalCanvas = createPlatformImageCanvas(outputSize, finalScale); if (SvgStretchableInsets != ResizableSvgInsets.Zero) { // Doing a stretchy 9-slice manipulation on the original SVG. // Partition into 9 segments, based on _formsControl.Svg9SliceInsets, storing both original and scaled sizes. var sliceInsets = SvgStretchableInsets; var sliceFramePairs = new[] { ResizableSvgSection.TopLeft, ResizableSvgSection.TopCenter, ResizableSvgSection.TopRight, ResizableSvgSection.CenterLeft, ResizableSvgSection.CenterCenter, ResizableSvgSection.CenterRight, ResizableSvgSection.BottomLeft, ResizableSvgSection.BottomCenter, ResizableSvgSection.BottomRight, }.Select(section => { return(Tuple.Create( sliceInsets.GetSection(originalSvgSize, section), sliceInsets.GetSection(outputSize, section))); }).ToArray(); foreach (var sliceFramePair in sliceFramePairs) { var sliceImage = RenderSectionToImage(LoadedGraphic, sliceFramePair.Item1, sliceFramePair.Item2, finalScale, createPlatformImageCanvas); finalCanvas.DrawImage(sliceImage, sliceFramePair.Item2); } } else { // Typical approach to rendering an SVG; just draw it to the canvas. double proportionalOutputScale = originalSvgSize.ScaleThatFits(outputSize); // Make sure ViewBox is reset to a proportionally-scaled default in case it was previous set by slicing. LoadedGraphic.ViewBox = new Rect(Point.Zero, originalSvgSize / proportionalOutputScale); LoadedGraphic.Draw(finalCanvas); } return(finalCanvas); }
public IImage GetRoundedImage(Size size, NGraphics.Color color, float radius) { size *= _scale; UIGraphics.BeginImageContextWithOptions(new CGSize(size.Width, size.Height), false, 0); IImage image = null; using (var context = UIGraphics.GetCurrentContext()) { context.SetAllowsAntialiasing(true); context.SetShouldAntialias(true); context.SetFillColor(UIColor.FromRGBA(color.R, color.G, color.B, color.A).CGColor); context.AddPath(CGPath.FromRoundedRect(new CGRect(0, 0, size.Width, size.Height), radius, radius)); context.FillPath(); } var nativeImage = UIGraphics.GetImageFromCurrentImageContext(); image = new CGImageImage(nativeImage.CGImage, _scale); return(image); }
internal Rect ScaleSection(Size finalImageSize, ResizableSvgSection section) { // TODO: Decide if the corners scale proportionally (an option with SVGs) or if they always stay the same size (current) or if it is optional. // TODO: Factor in `scaleCorners`, if needed. //public Rect ScaleSection(Size originalSvgSize, Size finalImageSize, ResizableSvgSection section, bool scaleCorners) { // int horizontalScale = finalImageSize.Width / originalSvgSize.Width; // int verticalScale = finalImageSize.Height / originalSvgSize.Height; // Rect originalSection = GetSection(originalSvgSize, section); switch (section) { case ResizableSvgSection.TopLeft: return(new Rect(Point.Zero, new Size(Left, Top))); case ResizableSvgSection.TopCenter: return(new Rect(new Point(Left, 0), new Size(finalImageSize.Width - Right - Left, Top))); case ResizableSvgSection.TopRight: return(new Rect(new Point(finalImageSize.Width - Right, 0), new Size(Right, Top))); case ResizableSvgSection.CenterLeft: return(new Rect(new Point(0, Top), new Size(Right, finalImageSize.Height - Bottom - Top))); case ResizableSvgSection.CenterCenter: return(new Rect(new Point(Left, Top), new Size(finalImageSize.Width - Right - Left, finalImageSize.Height - Bottom - Top))); case ResizableSvgSection.CenterRight: return(new Rect(new Point(finalImageSize.Width - Right, Top), new Size(Right, finalImageSize.Height - Bottom - Top))); case ResizableSvgSection.BottomLeft: return(new Rect(new Point(0, finalImageSize.Height - Bottom), new Size(Right, Bottom))); case ResizableSvgSection.BottomCenter: return(new Rect(new Point(Left, finalImageSize.Height - Bottom), new Size(finalImageSize.Width - Right - Left, Bottom))); case ResizableSvgSection.BottomRight: return(new Rect(new Point(finalImageSize.Width - Right, finalImageSize.Height - Bottom), new Size(Right, Bottom))); default: throw new ArgumentOutOfRangeException("section", "Invalid resizable SVG section"); } }
public ForeignObject (Point pos, Size size) : base(null, null) { this.pos = pos; this.size = size; }
public IImageCanvas CreateImageCanvas(Size size, double scale = 1.0, bool transparency = true) { return new NullImageSurface (); }
public void DrawImage(IImage image, Rect frame, double alpha = 1.0) { var ii = image as BitmapImage; if (ii != null) { var paint = GetImagePaint (alpha); var isize = new Size (ii.Bitmap.Width, ii.Bitmap.Height); var scale = frame.Size / isize; var m = new Matrix (); m.PreTranslate ((float)frame.X, (float)frame.Y); m.PreScale ((float)scale.Width, (float)scale.Height); graphics.DrawBitmap (ii.Bitmap, m, paint); } }
public IImageCanvas RenderSvgToCanvas (Size outputSize, double finalScale, Func<Size, double, IImageCanvas> createPlatformImageCanvas) { var originalSvgSize = LoadedGraphic.Size; var finalCanvas = createPlatformImageCanvas (outputSize, finalScale); if (SvgStretchableInsets != ResizableSvgInsets.Zero) { // Doing a stretchy 9-slice manipulation on the original SVG. // Partition into 9 segments, based on _formsControl.Svg9SliceInsets, storing both original and scaled sizes. var sliceInsets = SvgStretchableInsets; var sliceFramePairs = new[] { ResizableSvgSection.TopLeft, ResizableSvgSection.TopCenter, ResizableSvgSection.TopRight, ResizableSvgSection.CenterLeft, ResizableSvgSection.CenterCenter, ResizableSvgSection.CenterRight, ResizableSvgSection.BottomLeft, ResizableSvgSection.BottomCenter, ResizableSvgSection.BottomRight, }.Select (section => { return Tuple.Create ( sliceInsets.GetSection (originalSvgSize, section), sliceInsets.ScaleSection (outputSize, section)); }).ToArray (); foreach (var sliceFramePair in sliceFramePairs) { var sliceImage = RenderSectionToImage (LoadedGraphic, sliceFramePair.Item1, sliceFramePair.Item2, finalScale, createPlatformImageCanvas); finalCanvas.DrawImage (sliceImage, sliceFramePair.Item2); } } else { // Typical approach to rendering an SVG; just draw it to the canvas. double proportionalOutputScale = originalSvgSize.ScaleThatFits (outputSize); // Make sure ViewBox is reset to a proportionally-scaled default in case it was previous set by slicing. LoadedGraphic.ViewBox = new Rect (Point.Zero, originalSvgSize / proportionalOutputScale); LoadedGraphic.Draw (finalCanvas); } return finalCanvas; }
/// <summary> /// Creates an object implementing the IImageCanvas interface /// </summary> /// <param name="size"></param> /// <param name="scale"></param> /// <param name="transparency"></param> /// <returns></returns> public IImageCanvas CreateImageCanvas(Size size, double scale = 1.0, bool transparency = true) { throw new NotImplementedException(); }
public IImageCanvas GetCanvas(Size size) { return(_platform.CreateImageCanvas(size)); }
public CGImageImage(CGImage image, double scale) { if (image == null) throw new ArgumentNullException ("image"); this.image = image; this.scale = scale; this.size = new Size (image.Width / scale, image.Height / scale); }
public static void Translate(this ICanvas canvas, Size translation) { canvas.Transform (Transform.Translate (translation)); }
private async Task <string> CreateBadge(CancellationToken token) { //Get the badge icon IImage badgeIcon = null; if (_mode == Mode.File) { badgeIcon = await _canvasService.GetImage(FileIcon, token); } else if (_mode == Mode.Svg) { badgeIcon = await _canvasService.GetSvgImage(SvgIcon, SvgWidth, SvgHeight, token); } if (badgeIcon == null) { return(null); } token.ThrowIfCancellationRequested(); IImageCanvas canvas = null; if (IsBadgeVisible) { //InitializeCache frames var font = new Font(null, BadgeFontSize); var metrics = _canvasService.MeasureText(BadgeCount.ToString(), font); var textSize = metrics.Size; var badgeSize = new Size(BadgePadding.Left + BadgePadding.Right + textSize.Width, BadgePadding.Top + BadgePadding.Bottom + textSize.Height); var canvasSize = new Size(badgeIcon.Size.Width + badgeSize.Width - BadgeInsets.Width, badgeIcon.Size.Height + badgeSize.Height - BadgeInsets.Height); //Create canvas canvas = _canvasService.GetCanvas(canvasSize); token.ThrowIfCancellationRequested(); //Draw icon var imageFrame = new Rect(0, badgeSize.Height - BadgeInsets.Height, badgeIcon.Size.Width, badgeIcon.Size.Height); canvas.DrawImage(badgeIcon, imageFrame); token.ThrowIfCancellationRequested(); //Draw the badge rounded rect var badgeFrame = new Rect(badgeIcon.Size.Width - BadgeInsets.Width, 0, badgeSize.Width, badgeSize.Height); var color = GetColor(BadgeColor); var badgeImage = _canvasService.GetRoundedImage(badgeFrame.Size, color, BadgeRadius); canvas.DrawImage(badgeImage, badgeFrame); token.ThrowIfCancellationRequested(); //Draw badge text var textFrame = new Rect(badgeFrame.X + BadgePadding.Left, badgeFrame.Y + BadgePadding.Top + metrics.Ascent, textSize.Width, textSize.Height); canvas.DrawText(BadgeCount.ToString(), textFrame, font, TextAlignment.Center, GetColor(BadgeTextColor)); } else { //Create canvas canvas = _canvasService.GetCanvas(badgeIcon.Size); token.ThrowIfCancellationRequested(); //Draw icon var imageFrame = new Rect(0, 0, badgeIcon.Size.Width, badgeIcon.Size.Height); canvas.DrawImage(badgeIcon, imageFrame); } token.ThrowIfCancellationRequested(); //Get the result image var image = canvas.GetImage(); //Save the image to cache var filename = GetBadgeCacheFileName(); var path = PortablePath.Combine(_cacheFolder.Path, filename); await _canvasService.SaveImage(image, _cacheFolder.Path, filename, token); return(path); }
/// <summary> /// Resize the specified g and size. /// </summary> /// <returns>The resize.</returns> /// <param name="g">The green component.</param> /// <param name="size">Size.</param> public static Graphic Resize(Graphic g, NGraphics.Size size) { var transform = Transform.AspectFillRect(g.ViewBox, new NGraphics.Rect(0, 0, size.Width, size.Height)); return(g.TransformGeometry(transform)); }
public GraphCell() : base() { StackLayout dateLayout; Label dateLabel; /* Used when drawing. */ var points = new List <NPoint>(); var pointSize = new NSize(CaptionSize * 5 / 6); var halfPoint = pointSize / 2; View = dataView = new NControlView { Content = new StackLayout { //BackgroundColor = MainApp.RandomColor(), Orientation = StackOrientation.Horizontal, Children = { (dateLayout = new StackLayout { HorizontalOptions = LayoutOptions.EndAndExpand, //Padding = new Thickness(7, 0), WidthRequest = SpaceUnderGraph, Children = { (dateLabel = new Label { HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.CenterAndExpand, Rotation = -90, Style = StyleKit.AutoDarkLabelStyles.Caption, //FontSize = 12, BindingContext = this }) } }) } }, DrawingFunction = (canvas, rect) => { /* Transforms for natural drawing - as in the end, the whole graph is rotated 90 degrees! */ canvas.Rotate(-90); canvas.Translate(-rect.Height, halfPoint.Height); rect = new NRect(NPoint.Zero, new NSize(rect.Size.Height, rect.Size.Width - dateLayout.Width - pointSize.Height)); //canvas.DrawLine(rect.BottomLeft, rect.BottomRight, Colors.Black, 2); if (Data == null) { return; } points.Clear(); /* Add past points */ var yesterday = Data.Yesterday; if (yesterday?.Events?.Count == 1) { var beforeYesterday = yesterday?.Yesterday; points.AddRange(CalculateEventPoints(beforeYesterday?.Events, rect, -2)); } points.AddRange(CalculateEventPoints(yesterday?.Events, rect, -1)); /* Add today's points */ points.AddRange(CalculateEventPoints(Data.Events, rect)); /* Add future points */ var tomorrow = Data.Tomorrow; points.AddRange(CalculateEventPoints(tomorrow?.Events, rect, 1)); if (tomorrow?.Events?.Count == 1) { var afterTomorrow = tomorrow?.Tomorrow; points.AddRange(CalculateEventPoints(afterTomorrow?.Events, rect, 2)); } if (Data.Events.Count > 0) { var path = new Path(pen: new Pen(Colors.Black, pointSize.Width / 4)); path.MoveTo(points[0]); for (int i = 1; i < points.Count; i++) { path.Operations.Add(SplineTo( from: points[i - 1], to: points[i], beforeFrom: i >= 2 ? points[i - 2] : points[i - 1] - (points[i] - points[i - 1]).WithY(0), afterTo: i <= points.Count - 2 ? points[i + 1] : points[i] + (points[i] - points[i - 1]).WithY(0) )); } path.Draw(canvas); } foreach (var p in points) { if (p.X >= -halfPoint.Width && p.X <= rect.Width + halfPoint.Width) { canvas.FillEllipse(p - halfPoint, pointSize, Colors.Black); canvas.FillEllipse(p - halfPoint * 4 / 5, pointSize * 4 / 5, Colors.White); } } /* canvas.DrawText(Math.Round(data.Value * 5 + 1, 1).ToString("F1"), * rect.Center, new NFont(), Colors.Black); */ } }; View.SizeChanged += (sender, e) => dataView.Invalidate(); dateLabel.SetBinding <GraphCell, DateTime, string>(Label.TextProperty, cell => cell.Data.Day, dt => dt.ToString("ddd\ndd/MM")); dateLabel.SizeChanged += (sender, e) => dataView.Invalidate(); }
void ReadPath(Path p, string pathDescriptor) { var args = pathDescriptor.Split (WSC, StringSplitOptions.RemoveEmptyEntries); var i = 0; var n = args.Length; while (i < n) { var a = args[i]; // // Get the operation // var op = ""; if (a.Length == 1) { op = a; i++; } else { op = a.Substring (0, 1); args [i] = a.Substring (1); } // // Execute // if (op == "M" && i + 1 < n) { p.MoveTo (new Point (ReadNumber (args [i]), ReadNumber (args [i + 1]))); i += 2; } else if (op == "L" && i + 1 < n) { p.LineTo (new Point (ReadNumber (args [i]), ReadNumber (args [i + 1]))); i += 2; } else if (op == "C" && i + 5 < n) { var c1 = new Point (ReadNumber (args [i]), ReadNumber (args [i + 1])); var c2 = new Point (ReadNumber (args [i + 2]), ReadNumber (args [i + 3])); var pt = new Point (ReadNumber (args [i + 4]), ReadNumber (args [i + 5])); p.CurveTo (c1, c2, pt); i += 6; } else if (op == "S" && i + 3 < n) { var c = new Point (ReadNumber (args [i]), ReadNumber (args [i + 1])); var pt = new Point (ReadNumber (args [i + 2]), ReadNumber (args [i + 3])); p.ContinueCurveTo (c, pt); i += 4; } else if (op == "A" && i + 6 < n) { var r = new Size (ReadNumber (args [i]), ReadNumber (args [i + 1])); // var xr = ReadNumber (args [i + 2]); var laf = ReadNumber (args [i + 3]) != 0; var swf = ReadNumber (args [i + 4]) != 0; var pt = new Point (ReadNumber (args [i + 5]), ReadNumber (args [i + 6])); p.ArcTo (r, laf, swf, pt); i += 7; } else if (op == "z" || op == "Z") { p.Close (); } else { throw new NotSupportedException ("Path Operation " + op); } } }
void ReadPath (Path p, string pathDescriptor) { Match m = pathRegex.Match(pathDescriptor); while(m.Success) { var match = m.Value.TrimStart (); var op = match[0]; if (op == 'z' || op == 'Z') { p.Close (); } else { // make sure negative numbers are split properly match = negativeNumberRe.Replace(match.Substring(1), " -"); var args = match.Split(WSC, StringSplitOptions.RemoveEmptyEntries); Point previousPoint = new Point (); int index = 0; while(index < args.Length) { if (p.Operations.Count > 0 && !(p.Operations.Last() is ClosePath)) previousPoint = p.Operations.Last().EndPoint; if ((op == 'M' || op == 'm') && args.Length >= index+2) { var point = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); if (op == 'm') point += previousPoint; p.MoveTo (point); index += 2; } else if ((op == 'L' || op == 'l') && args.Length >= index+2) { var point = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); if (op == 'l') point += previousPoint; p.LineTo (point); index += 2; } else if ((op == 'C' || op == 'c') && args.Length >= index+6) { var c1 = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); var c2 = new Point (ReadNumber (args [index+2]), ReadNumber (args [index+3])); var pt = new Point (ReadNumber (args [index+4]), ReadNumber (args [index+5])); if (op == 'c') { c1 += previousPoint; c2 += previousPoint; pt += previousPoint; } p.CurveTo (c1, c2, pt); index += 6; } else if ((op == 'S' || op == 's') && args.Length >= index+4) { var c = new Point (ReadNumber (args [index]), ReadNumber (args [index+1])); var pt = new Point (ReadNumber (args [index+2]), ReadNumber (args [index+3])); if (op == 's') { c += previousPoint; pt += previousPoint; } p.ContinueCurveTo (c, pt); index += 4; } else if ((op == 'A' || op == 'a') && args.Length >= index+7) { var r = new Size (ReadNumber (args [index]), ReadNumber (args [index+1])); // var xr = ReadNumber (args [i + 2]); var laf = ReadNumber (args [index+3]) != 0; var swf = ReadNumber (args [index+4]) != 0; var pt = new Point (ReadNumber (args [index+5]), ReadNumber (args [index+6])); if (op == 'a') pt += previousPoint; p.ArcTo (r, laf, swf, pt); index += 7; } else if ((op == 'V' || op == 'v') && args.Length >= index+1 && p.Operations.Count > 0) { var previousX = previousPoint.X; var y = ReadNumber(args[index]); if (op == 'v') y += previousPoint.Y; var point = new Point(previousX, y); p.LineTo(point); index += 1; } else if ((op == 'H' || op == 'h') && args.Length >= index+1 && p.Operations.Count > 0) { var previousY = previousPoint.Y; var x = ReadNumber(args[index]); if (op == 'h') x += previousPoint.X; var point = new Point(x, previousY); p.LineTo(point); index += 1; } else { throw new NotSupportedException ("Path Operation " + op); } } } m = m.NextMatch(); } }
void ReadPath(Path p, string pathDescriptor) { Match m = pathRegex.Match(pathDescriptor); while(m.Success) { var match = m.Value.Trim(); var op = match.Substring(0, 1); // make sure negative numbers are split properly match = match.Replace("-", " -"); var args = match.Substring(1).Split(WSC, StringSplitOptions.RemoveEmptyEntries); Point previousPoint = new Point (); if (p.Operations.Count > 0 && !(p.Operations.Last() is ClosePath)) previousPoint = p.Operations.Last().EndPoint; if ((op == "M" || op == "m") && args.Length >= 2) { var point = new Point (ReadNumber (args [0]), ReadNumber (args [1])); if (op == "m") point += previousPoint; p.MoveTo (point); } else if ((op == "L" || op == "l") && args.Length >= 2) { var point = new Point (ReadNumber (args [0]), ReadNumber (args [1])); if (op == "l") point += previousPoint; p.LineTo (point); } else if ((op == "C" || op == "c") && args.Length >= 6) { var c1 = new Point (ReadNumber (args [0]), ReadNumber (args [1])); var c2 = new Point (ReadNumber (args [2]), ReadNumber (args [3])); var pt = new Point (ReadNumber (args [4]), ReadNumber (args [5])); if (op == "c") { c1 += previousPoint; c2 += previousPoint; pt += previousPoint; } p.CurveTo (c1, c2, pt); } else if ((op == "S" || op == "s") && args.Length >= 4) { var c = new Point (ReadNumber (args [0]), ReadNumber (args [1])); var pt = new Point (ReadNumber (args [2]), ReadNumber (args [3])); if (op == "s") { c += previousPoint; pt += previousPoint; } p.ContinueCurveTo (c, pt); } else if ((op == "A" || op == "a") && args.Length >= 7) { var r = new Size (ReadNumber (args [0]), ReadNumber (args [1])); // var xr = ReadNumber (args [i + 2]); var laf = ReadNumber (args [3]) != 0; var swf = ReadNumber (args [4]) != 0; var pt = new Point (ReadNumber (args [5]), ReadNumber (args [6])); if (op == "a") pt += previousPoint; p.ArcTo (r, laf, swf, pt); } else if ((op == "V" || op == "v") && args.Length >= 1 && p.Operations.Count > 0) { var previousX = previousPoint.X; var y = ReadNumber(args[0]); if (op == "v") y += previousPoint.Y; var point = new Point(previousX, y); p.LineTo(point); } else if ((op == "H" || op == "h") && args.Length >= 1 && p.Operations.Count > 0) { var previousY = previousPoint.Y; var x = ReadNumber(args[0]); if (op == "h") x += previousPoint.X; var point = new Point(x, previousY); p.LineTo(point); } else if (op == "z" || op == "Z") { p.Close (); } else { throw new NotSupportedException ("Path Operation " + op); } m = m.NextMatch(); } }
public void ArcTo(Size radius, bool largeArc, bool sweepClockwise, Point point) { Add (new ArcTo (radius, largeArc, sweepClockwise, point)); }
public GraphicCanvas(Size size) { Graphic = new Graphic (size); }
public Ellipse (Point position, Size size, Pen pen = null, Brush brush = null) : this (new Rect (position, size), pen, brush) { }
public static void DrawRectangle(this ICanvas canvas, Point position, Size size, Pen pen = null, Brush brush = null) { canvas.DrawRectangle (new Rect (position, size), pen, brush); }