public void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IWidget widget, float layerOpacity) { var scaleBar = (ScaleBarWidget)widget; if (!scaleBar.CanTransform()) { return; } // If this is the first time, we call this renderer, ... if (_paintScaleBar == null) { // ... than create the paints _paintScaleBar = CreateScaleBarPaint(SKPaintStyle.Fill); _paintScaleBarStroke = CreateScaleBarPaint(SKPaintStyle.Stroke); _paintScaleText = CreateTextPaint(SKPaintStyle.Fill); _paintScaleTextStroke = CreateTextPaint(SKPaintStyle.Stroke); } // Update paints with new values _paintScaleBar.Color = scaleBar.TextColor.ToSkia(layerOpacity); _paintScaleBar.StrokeWidth = scaleBar.StrokeWidth * scaleBar.Scale; _paintScaleBarStroke.Color = scaleBar.Halo.ToSkia(layerOpacity); _paintScaleBarStroke.StrokeWidth = scaleBar.StrokeWidthHalo * scaleBar.Scale; _paintScaleText.Color = scaleBar.TextColor.ToSkia(layerOpacity); _paintScaleText.StrokeWidth = scaleBar.StrokeWidth * scaleBar.Scale; _paintScaleText.Typeface = SKTypeface.FromFamilyName(scaleBar.Font.FontFamily, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); _paintScaleText.TextSize = (float)scaleBar.Font.Size * scaleBar.Scale; _paintScaleTextStroke.Color = scaleBar.Halo.ToSkia(layerOpacity); _paintScaleTextStroke.StrokeWidth = scaleBar.StrokeWidthHalo / 2 * scaleBar.Scale; _paintScaleTextStroke.Typeface = SKTypeface.FromFamilyName(scaleBar.Font.FontFamily, SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright); _paintScaleTextStroke.TextSize = (float)scaleBar.Font.Size * scaleBar.Scale; float scaleBarLength1; string scaleBarText1; float scaleBarLength2; string scaleBarText2; (scaleBarLength1, scaleBarText1, scaleBarLength2, scaleBarText2) = scaleBar.GetScaleBarLengthAndText(viewport); // Calc height of scale bar SKRect textSize = SKRect.Empty; // Do this, because height of text changes sometimes (e.g. from 2 m to 1 m) _paintScaleTextStroke.MeasureText("9999 m", ref textSize); var scaleBarHeight = textSize.Height + (scaleBar.TickLength + scaleBar.StrokeWidthHalo * 0.5f + scaleBar.TextMargin) * scaleBar.Scale; if (scaleBar.ScaleBarMode == ScaleBarMode.Both && scaleBar.SecondaryUnitConverter != null) { scaleBarHeight *= 2; } else { scaleBarHeight += scaleBar.StrokeWidthHalo * 0.5f * scaleBar.Scale; } scaleBar.Height = scaleBarHeight; // Draw lines // Get lines for scale bar var points = scaleBar.GetScaleBarLinePositions(viewport, scaleBarLength1, scaleBarLength2, scaleBar.StrokeWidthHalo); // BoundingBox for scale bar BoundingBox envelop = new BoundingBox(); if (points != null) { // Draw outline of scale bar for (int i = 0; i < points.Length; i += 2) { canvas.DrawLine((float)points[i].X, (float)points[i].Y, (float)points[i + 1].X, (float)points[i + 1].Y, _paintScaleBarStroke); } // Draw scale bar for (int i = 0; i < points.Length; i += 2) { canvas.DrawLine((float)points[i].X, (float)points[i].Y, (float)points[i + 1].X, (float)points[i + 1].Y, _paintScaleBar); } envelop = points[0].BoundingBox; for (int i = 1; i < points.Length; i++) { envelop = envelop.Join(points[i].BoundingBox); } envelop = envelop.Grow(scaleBar.StrokeWidthHalo * 0.5f * scaleBar.Scale); } // Draw text // Calc text height SKRect textSize1 = SKRect.Empty; SKRect textSize2 = SKRect.Empty; scaleBarText1 = scaleBarText1 ?? string.Empty; _paintScaleTextStroke.MeasureText(scaleBarText1, ref textSize1); var(posX1, posY1, posX2, posY2) = scaleBar.GetScaleBarTextPositions(viewport, textSize.ToMapsui(), textSize1.ToMapsui(), textSize2.ToMapsui(), scaleBar.StrokeWidthHalo); // Now draw text canvas.DrawText(scaleBarText1, posX1, posY1 - textSize1.Top, _paintScaleTextStroke); canvas.DrawText(scaleBarText1, posX1, posY1 - textSize1.Top, _paintScaleText); envelop = envelop.Join(new BoundingBox(posX1, posY1, posX1 + textSize1.Width, posY1 + textSize1.Height)); if (scaleBar.ScaleBarMode == ScaleBarMode.Both && scaleBar.SecondaryUnitConverter != null) { // Now draw second text scaleBarText2 = scaleBarText2 ?? string.Empty; _paintScaleTextStroke.MeasureText(scaleBarText2, ref textSize2); canvas.DrawText(scaleBarText2, posX2, posY2 - textSize2.Top, _paintScaleTextStroke); canvas.DrawText(scaleBarText2, posX2, posY2 - textSize2.Top, _paintScaleText); envelop = envelop.Join(new BoundingBox(posX2, posY2, posX2 + textSize2.Width, posY2 + textSize2.Height)); } scaleBar.Envelope = envelop; if (scaleBar.ShowEnvelop) { // Draw a rect around the scale bar for testing var tempPaint = _paintScaleTextStroke; canvas.DrawRect(new SKRect((float)envelop.MinX, (float)envelop.MinY, (float)envelop.MaxX, (float)envelop.MaxY), tempPaint); } }
private void canvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e) { SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(SKColors.CornflowerBlue); int width = e.Info.Width; int height = e.Info.Height; // Set transforms canvas.Translate(width / 2, height / 2); canvas.Scale(Math.Min(width / 210f, height / 520f)); // Get datetime DateTime dateTime = DateTime.Now; // Head canvas.DrawCircle(0, -160, 75, blackFillPaint); // Draw ears and eyes for (int i = 0; i < 2; i++) { canvas.Save(); canvas.Scale(2 * i - 1, 1); canvas.Save(); canvas.Translate(-65, -266); canvas.DrawPath(catEarPath, blackFillPaint); canvas.Restore(); canvas.Save(); canvas.Translate(10, -170); canvas.DrawPath(catEyePath, yellowFillPaint); canvas.DrawPath(catPupilPath, blackFillPaint); canvas.Restore(); // Draw whiskers canvas.DrawLine(10, -120, 100, -100, whiteStrokePaint); canvas.DrawLine(10, -125, 100, -120, whiteStrokePaint); canvas.DrawLine(10, -130, 100, -140, whiteStrokePaint); canvas.DrawLine(10, -135, 100, -160, whiteStrokePaint); canvas.Restore(); } // Draw tail canvas.DrawPath(catTailPath, blackStrokePaint); // Clock background canvas.DrawCircle(0, 0, 100, blackFillPaint); // Hour and minute marks for (int angle = 0; angle < 360; angle += 6) { canvas.DrawCircle(0, -90, angle % 30 == 0 ? 4 : 2, whiteFillPaint); canvas.RotateDegrees(6); } // Hour hand white canvas.Save(); canvas.RotateDegrees(30 * dateTime.Hour + dateTime.Minute / 2f); whiteStrokePaint.StrokeWidth = 15; canvas.DrawLine(0, 0, 0, -50, whiteStrokePaint); canvas.Restore(); // Hour hand gray canvas.Save(); canvas.RotateDegrees(30 * dateTime.Hour + dateTime.Minute / 2f); grayStrokePaint.StrokeWidth = 10; canvas.DrawLine(0, 0, 0, -50, grayStrokePaint); canvas.Restore(); // Minute hand white canvas.Save(); canvas.RotateDegrees(6 * dateTime.Minute + dateTime.Second / 10f); whiteStrokePaint.StrokeWidth = 10; canvas.DrawLine(0, 0, 0, -70, whiteStrokePaint); canvas.Restore(); // Minute hand gray canvas.Save(); canvas.RotateDegrees(6 * dateTime.Minute + dateTime.Second / 10f); grayStrokePaint.StrokeWidth = 5; canvas.DrawLine(0, 0, 0, -70, grayStrokePaint); canvas.Restore(); // Second hand canvas.Save(); float seconds = dateTime.Second + dateTime.Millisecond / 1000f; canvas.RotateDegrees(6 * seconds); whiteStrokePaint.StrokeWidth = 2; canvas.DrawLine(0, 0, 0, -80, whiteStrokePaint); canvas.Restore(); // Draw middle dot canvas.DrawCircle(0, 0, 3, blackFillPaint); }
public static void Draw(SKCanvas canvas, double screenWidth, double screenHeight, ZoomInOutWidget zoomInOut, float layerOpacity) { // If this widget belongs to no viewport, than stop drawing if (zoomInOut.Map == null) { return; } // If this is the first time, we call this renderer, ... if (paintStroke == null) { // ... than create the paints paintStroke = CreatePaint(zoomInOut.StrokeColor.ToSkia(layerOpacity), stroke, SKPaintStyle.Stroke); paintBackground = CreatePaint(zoomInOut.BackColor.ToSkia(layerOpacity), stroke, SKPaintStyle.Fill); paintText = CreatePaint(zoomInOut.TextColor.ToSkia(layerOpacity), stroke, SKPaintStyle.Fill); } else { // Update paints with new values paintStroke.Color = zoomInOut.StrokeColor.ToSkia(zoomInOut.Opacity); paintBackground.Color = zoomInOut.BackColor.ToSkia(zoomInOut.Opacity); paintText.Color = zoomInOut.TextColor.ToSkia(zoomInOut.Opacity); } var posX = zoomInOut.CalculatePositionX(0, (float)screenWidth, zoomInOut.Orientation == Orientation.Vertical ? zoomInOut.Size : zoomInOut.Size * 2 - stroke); var posY = zoomInOut.CalculatePositionY(0, (float)screenHeight, zoomInOut.Orientation == Orientation.Vertical ? zoomInOut.Size * 2 - stroke : zoomInOut.Size); // Draw a rect for zoom in button SKRect rect; rect = new SKRect(posX, posY, posX + zoomInOut.Size, posY + zoomInOut.Size); canvas.DrawRoundRect(rect, 2, 2, paintBackground); canvas.DrawRoundRect(rect, 2, 2, paintStroke); // Draw rect for zoom out button if (zoomInOut.Orientation == Orientation.Vertical) { rect = new SKRect(posX, posY + zoomInOut.Size, posX + zoomInOut.Size, posY + zoomInOut.Size * 2 - stroke); } else { rect = new SKRect(posX + zoomInOut.Size, posY, posX + zoomInOut.Size * 2 - stroke, posY + zoomInOut.Size); } canvas.DrawRoundRect(rect, 2, 2, paintBackground); canvas.DrawRoundRect(rect, 2, 2, paintStroke); // Draw + canvas.DrawLine(posX + zoomInOut.Size * 0.3f, posY + zoomInOut.Size * 0.5f, posX + zoomInOut.Size * 0.7f, posY + zoomInOut.Size * 0.5f, paintText); canvas.DrawLine(posX + zoomInOut.Size * 0.5f, posY + zoomInOut.Size * 0.3f, posX + zoomInOut.Size * 0.5f, posY + zoomInOut.Size * 0.7f, paintText); // Draw - if (zoomInOut.Orientation == Orientation.Vertical) { canvas.DrawLine(posX + zoomInOut.Size * 0.3f, posY - stroke + zoomInOut.Size * 1.5f, posX + zoomInOut.Size * 0.7f, posY - stroke + zoomInOut.Size * 1.5f, paintText); } else { canvas.DrawLine(posX - stroke + zoomInOut.Size * 1.3f, posY + zoomInOut.Size * 0.5f, posX - stroke + zoomInOut.Size * 1.7f, posY + zoomInOut.Size * 0.5f, paintText); } // Perhaps we should resize the Envelop about half of stroke, because of Skia rendering have of line outside if (zoomInOut.Orientation == Orientation.Vertical) { zoomInOut.Envelope = new BoundingBox(posX, posY, posX + rect.Width, posY + rect.Width * 2 - stroke); } else { zoomInOut.Envelope = new BoundingBox(posX, posY, posX + rect.Width * 2 - stroke, posY + rect.Width); } }
private void canvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e) { SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; canvas.DrawPaint(backgroundFillPaint); int width = e.Info.Width; int height = e.Info.Height; // Set transforms canvas.Translate(width / 2, height / 2); canvas.Scale(Math.Min(width / 210f, height / 520f)); // Get DateTime DateTime dateTime = DateTime.Now; // Head canvas.DrawCircle(0, -160, 75, blackFillPaint); // Draw ears and eyes for (int i = 0; i < 2; i++) { canvas.Save(); canvas.Scale(2 * i - 1, 1); canvas.Save(); canvas.Translate(-65, -255); canvas.DrawPath(catEarPath, blackFillPaint); canvas.Restore(); canvas.Save(); canvas.Translate(10, -170); canvas.DrawPath(catEyePath, greenFillPaint); canvas.DrawPath(catPupilPath, blackFillPaint); canvas.Restore(); // Draw whiskers canvas.DrawLine(10, -120, 100, -100, whiteStrokePaint); canvas.DrawLine(10, -125, 100, -120, whiteStrokePaint); canvas.DrawLine(10, -130, 100, -140, whiteStrokePaint); canvas.DrawLine(10, -135, 100, -160, whiteStrokePaint); canvas.Restore(); } // Move Tail float t = (float)Math.Sin((dateTime.Second % 2 + dateTime.Millisecond / 1000.0) * Math.PI); catTailPath.Reset(); catTailPath.MoveTo(0, 100); SKPoint point1 = new SKPoint(-50 * t, 200); SKPoint point2 = new SKPoint(0, 250 - Math.Abs(50 * t)); SKPoint point3 = new SKPoint(50 * t, 250 - Math.Abs(75 * t)); catTailPath.CubicTo(point1, point2, point3); canvas.DrawPath(catTailPath, blackStrokePaint); // Clock background canvas.DrawCircle(0, 0, 100, blackFillPaint); // Hour and minute marks for (int angle = 0; angle < 360; angle += 6) { canvas.DrawCircle(0, -90, angle % 30 == 0 ? 4 : 2, whiteFillPaint); canvas.RotateDegrees(6); } // Hour hand canvas.Save(); canvas.RotateDegrees(30 * dateTime.Hour + dateTime.Minute / 2f); canvas.DrawPath(hourHandPath, grayFillPaint); canvas.DrawPath(hourHandPath, whiteStrokePaint); canvas.Restore(); // Minute hand canvas.Save(); canvas.RotateDegrees(6 * dateTime.Minute + dateTime.Second / 10f); canvas.DrawPath(minuteHandPath, grayFillPaint); canvas.DrawPath(minuteHandPath, whiteStrokePaint); canvas.Restore(); // Second hand canvas.Save(); float seconds = dateTime.Second + dateTime.Millisecond / 1000f; canvas.RotateDegrees(6 * seconds); whiteStrokePaint.StrokeWidth = 2; canvas.DrawLine(0, 10, 0, -80, whiteStrokePaint); canvas.Restore(); }
public byte[] GetImage(string referenceName, int zoomLevel, int chunk) { var refer = _service._references.First(r => r.Name == referenceName); var height = (_service._histograms[refer.Name].Max() + 1) * 15; using var surface = SKSurface.Create(new SKImageInfo(WIDTH, height)); using SKCanvas canvas = surface.Canvas; canvas.Clear(); using SKPaint paint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Black, StrokeWidth = 1 }; using SKPaint fillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = SKColors.Blue, StrokeWidth = 1 }; using SKPaint reverseFillPaint = new SKPaint { Style = SKPaintStyle.Fill, Color = SKColors.Red, StrokeWidth = 1 }; var startY = 7; var list = new List <long> { 0 }; using var reader = new StreamReader($"{_service._references.IndexOf(refer)}.tmp"); string line; while ((line = reader.ReadLine()) != null) { var splitLine = line.Split('\t'); var read = new SamFile { QueryName = splitLine[0], ReferenceName = splitLine[1], StartingPos = int.Parse(splitLine[2]), DrawExpressions = DataService.GetDrawExpressions(splitLine[3]), Reverse = bool.Parse(splitLine[4]) }; var realStartingX = zoomLevel * read.StartingPos; if (realStartingX >= (chunk + 1) * WIDTH) { break; } var index = list.FindIndex(i => realStartingX > i + 1); var y = startY * (index != -1 ? index : list.Count); var lineLength = read.DrawExpressions.Sum(de => de.Length) * zoomLevel; if (index == -1) { list.Add(realStartingX + lineLength); } else { list[index] = realStartingX + lineLength; } realStartingX -= chunk * WIDTH; if (realStartingX < 0 && realStartingX + lineLength < 0) { continue; } canvas.DrawLine(new SKPoint(realStartingX, y + 3), new SKPoint(realStartingX + lineLength, y + 3), paint); var currentX = realStartingX; foreach (var draw in read.DrawExpressions) { if (draw.Type == DrawType.Rectangle) { canvas.DrawRect(currentX, y, draw.Length * zoomLevel, 5, read.Reverse ? reverseFillPaint : fillPaint); canvas.DrawRect(currentX, y, draw.Length * zoomLevel, 5, paint); } currentX += draw.Length * zoomLevel; } canvas.Flush(); } var width = (chunk + 1) * WIDTH * zoomLevel > refer.Length * zoomLevel ? refer.Length * zoomLevel % WIDTH : WIDTH; var realHeight = 7 * (list.Count + 1); SKPixmap pixmap = surface.Snapshot().Subset(SKRectI.Create(0, 0, width, realHeight)).PeekPixels(); SKData data; if (realHeight > 15000) { data = pixmap.Encode(SKPngEncoderOptions.Default); } else { var options = new SKWebpEncoderOptions(SKWebpEncoderCompression.Lossless, 100); data = pixmap.Encode(options); } return(data.ToArray()); }
private void ReadElement(XElement e, SKCanvas canvas, SKPaint stroke, SKPaint fill) { // transform matrix var transform = ReadTransform(e.Attribute("transform")?.Value ?? string.Empty); canvas.Save(); canvas.Concat(ref transform); // SVG element var elementName = e.Name.LocalName; var isGroup = elementName == "g"; // read style var style = ReadPaints(e, ref stroke, ref fill, isGroup); // parse elements switch (elementName) { case "text": if (stroke != null || fill != null) { ReadText(e, canvas, stroke?.Clone(), fill?.Clone()); } break; case "rect": if (stroke != null || fill != null) { var x = ReadNumber(e.Attribute("x")); var y = ReadNumber(e.Attribute("y")); var width = ReadNumber(e.Attribute("width")); var height = ReadNumber(e.Attribute("height")); var rx = ReadNumber(e.Attribute("rx")); var ry = ReadNumber(e.Attribute("ry")); var rect = SKRect.Create(x, y, width, height); if (rx > 0 || ry > 0) { if (fill != null) { canvas.DrawRoundRect(rect, rx, ry, fill); } if (stroke != null) { canvas.DrawRoundRect(rect, rx, ry, stroke); } } else { if (fill != null) { canvas.DrawRect(rect, fill); } if (stroke != null) { canvas.DrawRect(rect, stroke); } } } break; case "ellipse": if (stroke != null || fill != null) { var cx = ReadNumber(e.Attribute("cx")); var cy = ReadNumber(e.Attribute("cy")); var rx = ReadNumber(e.Attribute("rx")); var ry = ReadNumber(e.Attribute("ry")); if (fill != null) { canvas.DrawOval(cx, cy, rx, ry, fill); } if (stroke != null) { canvas.DrawOval(cx, cy, rx, ry, stroke); } } break; case "circle": if (stroke != null || fill != null) { var cx = ReadNumber(e.Attribute("cx")); var cy = ReadNumber(e.Attribute("cy")); var rr = ReadNumber(e.Attribute("r")); if (fill != null) { canvas.DrawCircle(cx, cy, rr, fill); } if (stroke != null) { canvas.DrawCircle(cx, cy, rr, stroke); } } break; case "path": if (stroke != null || fill != null) { var d = e.Attribute("d")?.Value; if (!string.IsNullOrWhiteSpace(d)) { var path = SKPath.ParseSvgPathData(d); if (fill != null) { canvas.DrawPath(path, fill); } if (stroke != null) { canvas.DrawPath(path, stroke); } } } break; case "polygon": case "polyline": if (stroke != null || fill != null) { var close = elementName == "polygon"; var p = e.Attribute("points")?.Value; if (!string.IsNullOrWhiteSpace(p)) { var path = ReadPolyPath(p, close); if (fill != null) { canvas.DrawPath(path, fill); } if (stroke != null) { canvas.DrawPath(path, stroke); } } } break; case "g": if (e.HasElements) { // get current group opacity float groupOpacity = ReadOpacity(style); if (groupOpacity != 1.0f) { var opacity = (byte)(255 * groupOpacity); var opacityPaint = new SKPaint { Color = SKColors.Black.WithAlpha(opacity) }; // apply the opacity canvas.SaveLayer(opacityPaint); } foreach (var gElement in e.Elements()) { ReadElement(gElement, canvas, stroke?.Clone(), fill?.Clone()); } // restore state if (groupOpacity != 1.0f) { canvas.Restore(); } } break; case "use": if (e.HasAttributes) { var href = ReadHref(e); if (href != null) { // TODO: copy/process other attributes var x = ReadNumber(e.Attribute("x")); var y = ReadNumber(e.Attribute("y")); var useTransform = SKMatrix.MakeTranslation(x, y); canvas.Save(); canvas.Concat(ref useTransform); ReadElement(href, canvas, stroke?.Clone(), fill?.Clone()); canvas.Restore(); } } break; case "line": if (stroke != null) { var x1 = ReadNumber(e.Attribute("x1")); var x2 = ReadNumber(e.Attribute("x2")); var y1 = ReadNumber(e.Attribute("y1")); var y2 = ReadNumber(e.Attribute("y2")); canvas.DrawLine(x1, y1, x2, y2, stroke); } break; case "switch": if (e.HasElements) { foreach (var ee in e.Elements()) { var requiredFeatures = ee.Attribute("requiredFeatures"); var requiredExtensions = ee.Attribute("requiredExtensions"); var systemLanguage = ee.Attribute("systemLanguage"); // TODO: evaluate requiredFeatures, requiredExtensions and systemLanguage var isVisible = requiredFeatures == null && requiredExtensions == null && systemLanguage == null; if (isVisible) { ReadElement(ee, canvas, stroke?.Clone(), fill?.Clone()); } } } break; case "defs": case "title": case "desc": case "description": // already read earlier break; default: LogOrThrow($"SVG element '{elementName}' is not supported"); break; } // restore matrix canvas.Restore(); }
private void canvas_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e) { SKImageInfo info = e.Info; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; SKPaint strokePaint = GetPaintColor(SKPaintStyle.Stroke, null, 10, SKStrokeCap.Square); SKPaint dotPaint = GetPaintColor(SKPaintStyle.Fill, "#DE0469"); SKPaint hrPaint = GetPaintColor(SKPaintStyle.Stroke, "#262626", 4, SKStrokeCap.Square); SKPaint minPaint = GetPaintColor(SKPaintStyle.Stroke, "#DE0469", 2, SKStrokeCap.Square); SKPaint bgPaint = GetPaintColor(SKPaintStyle.Fill, "#FFFFFF"); canvas.Clear(); SKRect arcRect = new SKRect(10, 10, info.Width - 10, info.Height - 10); SKRect bgRect = new SKRect(25, 25, info.Width - 25, info.Height - 25); canvas.DrawOval(bgRect, bgPaint); strokePaint.Shader = SKShader.CreateLinearGradient( new SKPoint(arcRect.Left, arcRect.Top), new SKPoint(arcRect.Right, arcRect.Bottom), new SKColor[] { SKColor.Parse("#DE0469"), SKColors.Transparent }, new float[] { 0, 1 }, SKShaderTileMode.Repeat); path.ArcTo(arcRect, 45, arcLength, true); canvas.DrawPath(path, strokePaint); canvas.Translate(info.Width / 2, info.Height / 2); canvas.Scale(info.Width / 200f); canvas.Save(); canvas.RotateDegrees(240); canvas.DrawCircle(0, -75, 2, dotPaint); canvas.Restore(); DateTime dateTime = DateTime.Now; //Draw hour hand canvas.Save(); canvas.RotateDegrees(30 * dateTime.Hour + dateTime.Minute / 2f); canvas.DrawLine(0, 5, 0, -60, hrPaint); canvas.Restore(); //Draw minute hand canvas.Save(); canvas.RotateDegrees(6 * dateTime.Minute + dateTime.Second / 10f); canvas.DrawLine(0, 10, 0, -90, minPaint); canvas.Restore(); canvas.DrawCircle(0, 0, 5, dotPaint); secondsTxt.Text = dateTime.Second.ToString("00"); timeTxt.Text = dateTime.ToString("hh:mm"); periodTxt.Text = dateTime.Hour >= 12 ? "PM" : "AM"; var alarmDiff = alarmDate - dateTime; alarmTxt.Text = $"{alarmDiff.Hours}h {alarmDiff.Minutes}m until next alarm"; }
public void DrawLine(Vector2 from, Vector2 to) { SetLineStyle(); _skiaCanvas.DrawLine(from.ToSkiaPoint(), to.ToSkiaPoint(), _skiaPaint); }
private void SKCanvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e) { SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(SKColors.Transparent); int width = e.Info.Width; int height = e.Info.Height; double heightAsDp = Height; double widthAsDp = Width; var density = width / widthAsDp; float tickSizeAsPixel = (float)density * TickSize; float currentTickSizeAsPixel = (float)density * CurrentTickSize; float tickWidthAsPixel = (float)density * TickWidth; TickPaint = new SKPaint() { Color = SKColors.Wheat, Style = SKPaintStyle.StrokeAndFill, StrokeWidth = tickWidthAsPixel, IsAntialias = IsAntialias, }; CurrentTickPaint = new SKPaint() { Color = SKColors.MediumVioletRed, Style = SKPaintStyle.StrokeAndFill, StrokeWidth = tickWidthAsPixel * 1.5f, IsAntialias = IsAntialias, }; EllepsedTickPaint = new SKPaint() { Color = SKColors.MidnightBlue, Style = SKPaintStyle.StrokeAndFill, StrokeWidth = tickWidthAsPixel, IsAntialias = IsAntialias, }; int radius = (width <= height ? width : height) / 2; float TickMargin = currentTickSizeAsPixel - tickSizeAsPixel; float degreeStep = (Direction == Direction.Clockwise ? 1 : -1) * (FinishAngleDegree - StartAngleDegree) / TickCount; float currentTickDegree = CurrentTick * (Direction == Direction.Clockwise ? 1 : -1) * (FinishAngleDegree - StartAngleDegree) / TickCount; var tickStartRadius = radius - currentTickSizeAsPixel; var tickEndRadius = radius - TickMargin; canvas.Translate(width / 2, height / 2); canvas.Save(); canvas.RotateDegrees(StartAngleDegree); for (int i = 0; i < TickCount; i++) { if (i < CurrentTick) { canvas.DrawLine(0, tickStartRadius, 0, tickEndRadius, EllepsedTickPaint); } else { canvas.DrawLine(0, tickStartRadius, 0, tickEndRadius, TickPaint); } canvas.RotateDegrees(degreeStep); } canvas.Restore(); canvas.Save(); canvas.RotateDegrees(StartAngleDegree + currentTickDegree); canvas.DrawLine(0, tickStartRadius, 0, radius, CurrentTickPaint); canvas.Restore(); }
public byte[] DrawAreaAtSize(ImageStats stats, List <CompletePaintOp> paintOps) { //This is the new core drawing function. Once the paint operations have been created, I just draw them here. //baseline image data stuff SKBitmap bitmap = new SKBitmap(stats.imageSizeX, stats.imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul); SKCanvas canvas = new SKCanvas(bitmap); canvas.Clear(eraser.Color); canvas.Scale(1, -1, stats.imageSizeX / 2, stats.imageSizeY / 2); SKPaint paint = new SKPaint(); foreach (var w in paintOps.OrderByDescending(p => p.paintOp.LayerId).ThenByDescending(p => p.areaSize)) { paint = cachedPaints[w.paintOp.Id]; //SetPaintForTPP(w.paintOp); // w.paintOp.paint; if (w.paintOp.FromTag) //FromTag is for when you are saving color data directly to each element, instead of tying it to a styleset. { paint.Color = SKColor.Parse(w.tagValue); } if (w.paintOp.Randomize) //To randomize the color on every Draw call. { paint.Color = new SKColor((byte)r.Next(0, 255), (byte)r.Next(0, 255), (byte)r.Next(0, 255), 99); } paint.StrokeWidth = (float)w.lineWidthPixels; var path = new SKPath(); switch (w.elementGeometry.GeometryType) { case "Polygon": var p = w.elementGeometry as Polygon; //if (p.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw //continue; path.AddPoly(PolygonToSKPoints(p.ExteriorRing, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); foreach (var ir in p.Holes) { //if (ir.Envelope.Length < (w.lineWidth * 4)) //This poly's perimeter is less than 2x2 pixels in size. //continue; path.AddPoly(PolygonToSKPoints(ir, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); } canvas.DrawPath(path, paint); break; case "MultiPolygon": foreach (var p2 in ((MultiPolygon)w.elementGeometry).Geometries) { //if (p2.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw //continue; var p2p = p2 as Polygon; path.AddPoly(PolygonToSKPoints(p2p.ExteriorRing, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); foreach (var ir in p2p.Holes) { //if (ir.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw // continue; path.AddPoly(PolygonToSKPoints(ir, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); } canvas.DrawPath(path, paint); } break; case "LineString": var firstPoint = w.elementGeometry.Coordinates.First(); var lastPoint = w.elementGeometry.Coordinates.Last(); var points = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY); if (firstPoint.Equals(lastPoint)) { //This is a closed shape. Check to see if it's supposed to be filled in. if (paint.Style == SKPaintStyle.Fill) { path.AddPoly(points); canvas.DrawPath(path, paint); continue; } } //if (w.lineWidth < 1) //Don't draw lines we can't see. //continue; for (var line = 0; line < points.Length - 1; line++) { canvas.DrawLine(points[line], points[line + 1], paint); } break; case "MultiLineString": //if (w.lineWidth < 1) //Don't draw lines we can't see. //continue; foreach (var p3 in ((MultiLineString)w.elementGeometry).Geometries) { var points2 = PolygonToSKPoints(p3, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY); for (var line = 0; line < points2.Length - 1; line++) { canvas.DrawLine(points2[line], points2[line + 1], paint); } } break; case "Point": var convertedPoint = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY); //If this type has an icon, use it. Otherwise draw a circle in that type's color. if (!string.IsNullOrEmpty(w.paintOp.FileName)) { SKBitmap icon = SKBitmap.Decode(TagParser.cachedBitmaps[w.paintOp.FileName]); //TODO optimize by making icons in Initialize. canvas.DrawBitmap(icon, convertedPoint[0]); } else { var circleRadius = (float)(ConstantValues.resolutionCell10 / stats.degreesPerPixelX / 2); //I want points to be drawn as 1 Cell10 in diameter. canvas.DrawCircle(convertedPoint[0], circleRadius, paint); //TODO re-add outline paint to this DLL not TagParser. //canvas.DrawCircle(convertedPoint[0], circleRadius, TagParser.outlinePaint); } break; default: Log.WriteLog("Unknown geometry type found, not drawn."); break; } } //} var ms = new MemoryStream(); var skms = new SKManagedWStream(ms); bitmap.Encode(skms, SKEncodedImageFormat.Png, 100); var results = ms.ToArray(); skms.Dispose(); ms.Close(); ms.Dispose(); return(results); }
/// <summary> /// Creates an SVG image instead of a PNG file, but otherwise operates the same as DrawAreaAtSize. /// </summary> /// <param name="stats">the image properties to draw</param> /// <param name="drawnItems">the list of elements to draw. Will load from the database if null.</param> /// <param name="styles">a dictionary of TagParserEntries to select to draw</param> /// <param name="filterSmallAreas">if true, skips entries below a certain size when drawing.</param> /// <returns>a string containing the SVG XML</returns> public string DrawAreaAtSizeSVG(ImageStats stats, List <DbTables.Place> drawnItems = null, Dictionary <string, StyleEntry> styles = null, bool filterSmallAreas = true) { //TODO: make this take CompletePaintOps //This is the new core drawing function. Takes in an area, the items to draw, and the size of the image to draw. //The drawn items get their paint pulled from the TagParser's list. If I need multiple match lists, I'll need to make a way //to pick which list of tagparser rules to use. if (styles == null) { styles = TagParser.allStyleGroups.First().Value; } double minimumSize = 0; if (filterSmallAreas) { minimumSize = stats.degreesPerPixelX; //don't draw elements under 1 pixel in size. at slippy zoom 12, this is approx. 1 pixel for a Cell10. } var db = new PraxisContext(); var geo = Converters.GeoAreaToPolygon(stats.area); if (drawnItems == null) { drawnItems = GetPlaces(stats.area, filterSize: minimumSize); } //baseline image data stuff //SKBitmap bitmap = new SKBitmap(stats.imageSizeX, stats.imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul); var bounds = new SKRect(0, 0, stats.imageSizeX, stats.imageSizeY); MemoryStream s = new MemoryStream(); SKCanvas canvas = SKSvgCanvas.Create(bounds, s); //output not guaranteed to be complete until the canvas is deleted?!? //SKCanvas canvas = new SKCanvas(bitmap); var bgColor = SKColor.Parse(styles["background"].PaintOperations.First().HtmlColorCode); //Backgound is a named style, unmatched will be the last entry and transparent. canvas.Clear(bgColor); canvas.Scale(1, -1, stats.imageSizeX / 2, stats.imageSizeY / 2); SKPaint paint = new SKPaint(); //I guess what I want here is a list of an object with an elementGeometry object for the shape, and a paintOp attached to it var pass1 = drawnItems.Select(d => new { d.AreaSize, d.ElementGeometry, paintOp = styles[d.GameElementName].PaintOperations }); var pass2 = new List <CompletePaintOp>(drawnItems.Count() * 2); foreach (var op in pass1) { foreach (var po in op.paintOp) { pass2.Add(new CompletePaintOp(op.ElementGeometry, op.AreaSize, po, "", po.LineWidthDegrees * stats.pixelsPerDegreeX)); } } foreach (var w in pass2.OrderByDescending(p => p.paintOp.LayerId).ThenByDescending(p => p.areaSize)) { paint = cachedPaints[w.paintOp.Id]; if (paint.Color.Alpha == 0) { continue; //This area is transparent, skip drawing it entirely. } if (stats.degreesPerPixelX > w.paintOp.MaxDrawRes || stats.degreesPerPixelX < w.paintOp.MinDrawRes) { continue; //This area isn't drawn at this scale. } var path = new SKPath(); switch (w.elementGeometry.GeometryType) { //Polygons without holes are super easy and fast: draw the path. //Polygons with holes require their own bitmap to be drawn correctly and then overlaid onto the canvas. //I want to use paths to fix things for performance reasons, but I have to use Bitmaps because paths apply their blend mode to //ALL elements already drawn, not just the last one. case "Polygon": var p = w.elementGeometry as Polygon; path.AddPoly(PolygonToSKPoints(p, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); foreach (var hole in p.InteriorRings) { path.AddPoly(PolygonToSKPoints(hole, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); } canvas.DrawPath(path, paint); break; case "MultiPolygon": foreach (var p2 in ((MultiPolygon)w.elementGeometry).Geometries) { var p2p = p2 as Polygon; path.AddPoly(PolygonToSKPoints(p2p, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); foreach (var hole in p2p.InteriorRings) { path.AddPoly(PolygonToSKPoints(hole, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY)); } canvas.DrawPath(path, paint); } break; case "LineString": var firstPoint = w.elementGeometry.Coordinates.First(); var lastPoint = w.elementGeometry.Coordinates.Last(); var points = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY); if (firstPoint.Equals(lastPoint)) { //This is a closed shape. Check to see if it's supposed to be filled in. if (paint.Style == SKPaintStyle.Fill) { path.AddPoly(points); canvas.DrawPath(path, paint); continue; } } for (var line = 0; line < points.Length - 1; line++) { canvas.DrawLine(points[line], points[line + 1], paint); } break; case "MultiLineString": foreach (var p3 in ((MultiLineString)w.elementGeometry).Geometries) { var points2 = PolygonToSKPoints(p3, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY); for (var line = 0; line < points2.Length - 1; line++) { canvas.DrawLine(points2[line], points2[line + 1], paint); } } break; case "Point": var convertedPoint = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY); //If this type has an icon, use it. Otherwise draw a circle in that type's color. if (!string.IsNullOrEmpty(w.paintOp.FileName)) { SKBitmap icon = SKBitmap.Decode(TagParser.cachedBitmaps[w.paintOp.FileName]); //TODO optimize by creating in Initialize canvas.DrawBitmap(icon, convertedPoint[0]); } else { var circleRadius = (float)(ConstantValues.resolutionCell10 / stats.degreesPerPixelX / 2); //I want points to be drawn as 1 Cell10 in diameter. canvas.DrawCircle(convertedPoint[0], circleRadius, paint); } break; default: Log.WriteLog("Unknown geometry type found, not drawn."); break; } } canvas.Flush(); canvas.Dispose(); canvas = null; s.Position = 0; var svgData = new StreamReader(s).ReadToEnd(); return(svgData); }
public override void Draw(SKCanvas canvas, SKPaint paint, int x, int y) { canvas.DrawLine(new SKPoint(x - 100, y), new SKPoint(x + 100, y), paint); }
public void Render(SKCanvas canvas, MapDataContext mapDataContext) { var solarSystemVertexes = new List <SolarSystemVertex>(); foreach (var solarSystem in mapDataContext.SolarSystems) { solarSystemVertexes.Add(new SolarSystemVertex(solarSystem)); } var voronoiMesh = VoronoiMesh.Create <SolarSystemVertex, SolarySystemTriangulationCell>(solarSystemVertexes); var voronoiCells = CreateVoronoiCells(voronoiMesh); using (var paint = new SKPaint()) { paint.Style = SKPaintStyle.Fill; paint.IsAntialias = true; foreach (var cell in voronoiCells) { var solarSystem = cell.SolarSystemVertex.SolarSystem; var cellVertices = cell.SolarSystemVoronoiEdges; var points = SortVertices(cellVertices.SelectMany(x => new List <SKPoint>() { x.PointOne, x.PointTwo }).Distinct().ToList()).ToArray(); if (solarSystem.allianceID != null && solarSystem.allianceID != 0) { var md5 = MD5.Create(); var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(solarSystem.allianceID.ToString())); paint.Color = new SKColor(hash[0], hash[1], hash[2]).WithAlpha(60); var path = new SKPath(); // for (var i = 0; i < cellVertices.Count(); i++) // { // path.MoveTo(cellVertices[i].PointOne); // path.LineTo(cellVertices[i].PointTwo); // } path.MoveTo(points.First()); for (var i = 0; i < points.Count(); i++) { path.LineTo(points[i]); } path.LineTo(points.First()); canvas.DrawPath(path, paint); // canvas.DrawPoints(SKPointMode.Polygon, points, paint); } else { paint.Color = new SKColor(0xB0, 0xB0, 0xFF).WithAlpha(50); var path = new SKPath(); for (var i = 0; i < cellVertices.Count(); i++) { path.MoveTo(cellVertices[i].PointOne); path.LineTo(cellVertices[i].PointTwo); } // canvas.DrawPath(path, paint); } // paint.Color = new SKColor(randomBytes[0], randomBytes[1], randomBytes[2]); } canvas.DrawLine(new SKPoint(0.0f, 0.0f), new SKPoint(100.0f, 100.0f), paint); } }
public static void DrawLine(this SKCanvas canvas, float x1, float y1, float x2, float y2, SKColor color, int thickness = 1) { using var paint = new SKPaint { Color = color, StrokeWidth = thickness }; canvas.DrawLine(x1, y1, x2, y2, paint); }
public override bool Draw(SKCanvas c) { c.DrawLine(Point1.X, Point1.Y, Point2.X, Point2.Y, Paint); return(true); }
private void OnCanvasViewPaintSurfaceAsync(object sender, SKPaintSurfaceEventArgs e) { var ArenaCell = (SKCanvasView)sender; int[] index = new int[2] { int.Parse(ArenaCell.StyleId[0].ToString()), int.Parse(ArenaCell.StyleId[1].ToString()) }; SKImageInfo info = e.Info; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); if (ArenaCell.StyleId == "98") { if (GameViewModel.PlayerSymbol == 'X') { x = info.Width; y = info.Height; canvas.DrawLine(40, 40, x - 40, y - 40, paint); canvas.DrawLine(40, y - 40, x - 40, 40, paint); } else { x = info.Width; canvas.DrawCircle(info.Width / 2, info.Height / 2, (x / 2) - 30, paint); } return; } else if (ArenaCell.StyleId == "99") { if (GameViewModel.OpponentSymbol == 'X') { x = info.Width; y = info.Height; canvas.DrawLine(40, 40, x - 40, y - 40, paint); canvas.DrawLine(40, y - 40, x - 40, 40, paint); } else { x = info.Width; canvas.DrawCircle(info.Width / 2, info.Height / 2, (x / 2) - 30, paint); } return; } else if (GameViewModel.ArenaMatrix[index[0], index[1]] == ' ') { return; } else if (GameViewModel.ArenaMatrix[index[0], index[1]] == 'X') { x = info.Width; y = info.Height; canvas.DrawLine(35, 35, x - 35, y - 35, paint); canvas.DrawLine(35, y - 35, x - 35, 35, paint); } else { x = info.Width; int i = 35; canvas.DrawCircle(info.Width / 2, info.Height / 2, (x / 2) - i, paint); } }
private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; SKCanvasView canvasView = (SKCanvasView)sender; Pattern pattern = (Pattern)canvasView.BindingContext; canvas.Clear(); int diagramsize = pattern.Fretboard.GetLength(1) - pattern.FirstFret + 1; diagramsize = diagramsize > 5 ? diagramsize : 5; int scale = info.Width / diagramsize; int scalecenter = (int)(scale * 0.5f); int neckright = (int)(scale * 3.5f); int radius = (int)(scale * 0.4f); int firstfret = pattern.FirstFret; int numfrets = pattern.Fretboard.GetLength(1); int numstrings = pattern.Fretboard.GetLength(0); const int pad = 15; int i, j; SKPaint notes = new SKPaint { Style = SKPaintStyle.StrokeAndFill, Color = Color.Black.ToSKColor(), StrokeWidth = 1, TextSize = scale }; SKPaint lines = new SKPaint { Style = SKPaintStyle.StrokeAndFill, StrokeWidth = 5, Color = Color.LightGray.ToSKColor() }; // Draw the frets for (j = firstfret; j < numfrets + 1 || j < 4; j++) { int fretheight = (j - pattern.FirstFret + 1) * scale + pad; canvas.DrawLine(scalecenter, fretheight, neckright, fretheight, lines); } // Draw the strings lines.Color = Color.Black.ToSKColor(); for (i = 0; i < numstrings; i++) { int stringpos = (i + 1) * scale - scalecenter; canvas.DrawLine(stringpos, 0, stringpos, info.Height, lines); } // Draw the notes for (i = 0; i < numstrings; i++) { for (j = firstfret; j < numfrets; j++) { if (pattern.Fretboard[i, j] <= 0) { continue; } int x = (i + 1) * scale - scalecenter; int y = (j - pattern.FirstFret + 1) * scale - scalecenter + pad; canvas.DrawCircle(x, y, radius, notes); } } // Draw the nut lines.Color = Color.Black.ToSKColor(); lines.StrokeWidth = pad * 2; canvas.DrawLine(scalecenter, 0, neckright, 0, lines); // Draw the first fret number, if any if (firstfret > 0) { canvas.DrawText($"{firstfret + 1}", 4 * scale, scale - scalecenter + (int)(pad * 1.5f), notes); } }
public void Draw(SKCanvas canvas, IReadOnlyViewport viewport, IWidget widget, float layerOpacity) { canvas.RotateDegrees((float)viewport.Rotation, 0.0f, 0.0f); var TL = viewport.ScreenToWorld(canvas.LocalClipBounds.Left, canvas.LocalClipBounds.Top); var BR = viewport.ScreenToWorld(canvas.LocalClipBounds.Right, canvas.LocalClipBounds.Bottom); var width = viewport.Extent.Width; var height = viewport.Extent.Height; var usedLineOffset = lineOffset; uint usedLineOffsetInt = (uint)usedLineOffset; IEnumerable <SKPaint> usedPaints = paints; if (viewport.Resolution > 0.25) { usedLineOffset *= 10; // hide 10m layer usedLineOffsetInt *= 10; // hide 10m layer usedPaints = paintsL2; } if (viewport.Resolution > 3) { usedLineOffset *= 10; // hide 100m layer usedLineOffsetInt *= 10; // hide 100m layer usedPaints = paintsL3; } int lineCount100M = (int)(100 / usedLineOffset); //How many lines are 1000m int lineCount1000M = (int)(1000 / usedLineOffset); if (lineCount100M == 0) { lineCount100M = 9000; //will never be reached, if we only render 1k's } double screenWidthPerLine = canvas.LocalClipBounds.Width / (width / usedLineOffset); double screenHeightPerLine = canvas.LocalClipBounds.Height / (height / usedLineOffset); //World coordinates of first lineOffset line var first100mW = (TL.X + (usedLineOffset - TL.X % usedLineOffset)); var first100mH = (TL.Y + (usedLineOffset - TL.Y % usedLineOffset)); //Screen offset of first lineOffset line double offsetCW = ((first100mW - TL.X) / usedLineOffset) * screenWidthPerLine; double offsetCH = screenHeightPerLine + ((TL.Y - first100mH) / usedLineOffset) * screenHeightPerLine; //offset of next 1k int KOffsetW = (int)((first100mW % 1000) / usedLineOffset); if (KOffsetW < 0) { KOffsetW = 10 + KOffsetW; } int KOffsetH = (int)((first100mH % 1000) / usedLineOffset) - 1; if (lineCount1000M > 1) { KOffsetH = lineCount1000M - KOffsetH; } for (double curX = offsetCW; curX < canvas.LocalClipBounds.Right; curX += screenWidthPerLine) { var worldPos = viewport.ScreenToWorld(curX, 0).X; var Xgrid10KM = (uint)(worldPos / 10000) % 10; var Xgrid1KM = (uint)(worldPos / 1000) % 10; var Xgrid100m = (uint)(worldPos / 100) % 10; //var Xgrid10m = (uint)(worldPos / 10) % 10; string gridPosString; if (usedLineOffsetInt == 1000) { gridPosString = $"{Xgrid10KM}{Xgrid1KM}"; } else if (usedLineOffsetInt == 100) { gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}"; } else { gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}{(uint)(worldPos / 10) % 10}"; } SKPaint paint; if (KOffsetW >= 1000 && KOffsetW % 1000 == 0) { paint = usedPaints.ElementAt(0); } if (KOffsetW >= 100 && KOffsetW % 100 == 0) { paint = usedPaints.ElementAt(2); } else if (KOffsetW >= 10 && KOffsetW % 10 == 0) { paint = usedPaints.ElementAt(1); } else { paint = usedPaints.ElementAt(0); } if (KOffsetW == lineCount1000M) { KOffsetW = 0; } canvas.DrawLine((float)curX, 0, (float)curX, canvas.LocalClipBounds.Height, paint); using (var gtext = SKTextBlob.Create(gridPosString, markerFont)) canvas.DrawText(gtext, (float)(curX + screenWidthPerLine / 2) - gtext.Bounds.MidX, 20 + gtext.Bounds.MidY, paint100m); KOffsetW++; } for (double curH = offsetCH; curH < canvas.LocalClipBounds.Bottom; curH += screenHeightPerLine) { var worldPos = viewport.ScreenToWorld(0, curH).Y; var Xgrid10KM = (uint)(worldPos / 10000) % 10; var Xgrid1KM = (uint)(worldPos / 1000) % 10; var Xgrid100m = (uint)(worldPos / 100) % 10; //var Xgrid10m = (uint)(worldPos / 10) % 10; string gridPosString; if (usedLineOffsetInt == 1000) { gridPosString = $"{Xgrid10KM}{Xgrid1KM}"; } else if (usedLineOffsetInt == 100) { gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}"; } else { gridPosString = $"{Xgrid10KM}{Xgrid1KM}{Xgrid100m}{(uint)(worldPos / 10) % 10}"; } SKPaint paint; if (KOffsetH >= 100 && KOffsetH % 100 == 0) { paint = usedPaints.ElementAt(2); } else if (KOffsetH >= 10 && KOffsetH % 10 == 0) { paint = usedPaints.ElementAt(1); } else { paint = usedPaints.ElementAt(0); } if (KOffsetH == lineCount1000M) { KOffsetH = 0; } canvas.DrawLine(0, (float)curH, canvas.LocalClipBounds.Width, (float)curH, paint); using (var gtext = SKTextBlob.Create(gridPosString, markerFont)) canvas.DrawText(gtext, 0, (float)(curH + screenWidthPerLine / 2) - gtext.Bounds.MidY, paint100m); KOffsetH++; } }
private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs e) { SKImageInfo info = e.Info; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(SKColors.Silver); canvas.Translate(info.Width / 2, info.Height / 2); SKPaint paint = new SKPaint { IsAntialias = true, Color = SKColors.Black, StrokeWidth = 2 }; canvas.DrawLine(-info.Width / 2, 0, info.Width / 2, 0, paint); canvas.DrawLine(0, -info.Height / 2, 0, info.Height / 2, paint); SKPaint paintA = new SKPaint { IsAntialias = true, Color = SKColors.Red, Style = SKPaintStyle.Fill }; SKPath pathA = new SKPath(); pathA.MoveTo(0, 0); pathA.LineTo(0.1f * info.Width, -0.1f * info.Height); pathA.LineTo(0.3f * info.Width, -0.2f * info.Height); pathA.LineTo(0.5f * info.Width, -0.4f * info.Height); pathA.LineTo(0, -0.5f * info.Height); pathA.LineTo(-0.5f * info.Width, -0.4f * info.Height); pathA.LineTo(-0.3f * info.Width, -0.2f * info.Height); pathA.LineTo(-0.1f * info.Width, -0.1f * info.Height); pathA.Close(); canvas.DrawPath(pathA, paintA); //SKPaint paintB= new SKPaint //{ // IsAntialias = true, // Color = SKColors.Blue, // Style = SKPaintStyle.Fill //}; //SKPath pathB = new SKPath(); //pathB.MoveTo(0, 0); //pathB.LineTo(info.Width / 8, -info.Height / 4); //pathB.LineTo(0, -info.Height / 2); //pathB.LineTo(-info.Width / 8, -info.Height / 4); //pathB.Close(); //canvas.DrawPath(pathB, paintB); }
public override void Line(double x1, double y1, double x2, double y2) { _skCanvas.DrawLine((float)x1, (float)y1, (float)x2, (float)y2, _stroke); }
public override void DrawContent(SKCanvas canvas, int width, int height) { var total = this.Entries.Count(); if (total > 0) { var captionHeight = this.Entries.Max(x => { var result = 0.0f; var hasLabel = !string.IsNullOrEmpty(x.Label); var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel); if (hasLabel || hasValueLabel) { var hasOffset = hasLabel && hasValueLabel; var captionMargin = this.LabelTextSize * 0.60f; var space = hasOffset ? captionMargin : 0; if (hasLabel) { result += this.LabelTextSize; } if (hasValueLabel) { result += this.LabelTextSize; } } return(result); }); var center = new SKPoint(width / 2, height / 2); var radius = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight; var rangeAngle = (float)((Math.PI * 2) / total); var startAngle = (float)Math.PI; var nextEntry = this.Entries.First(); var nextAngle = startAngle; var nextPoint = this.GetPoint(nextEntry.Value, center, nextAngle, radius); this.DrawBorder(canvas, center, radius); for (int i = 0; i < total; i++) { var angle = nextAngle; var entry = nextEntry; var point = nextPoint; var nextIndex = (i + 1) % total; nextAngle = startAngle + (rangeAngle * nextIndex); nextEntry = this.Entries.ElementAt(nextIndex); nextPoint = this.GetPoint(nextEntry.Value, center, nextAngle, radius); // Border center bars using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = this.BorderLineSize, Color = this.BorderLineColor, IsAntialias = true, }) { var borderPoint = this.GetPoint(this.MaxValue, center, angle, radius); canvas.DrawLine(point.X, point.Y, borderPoint.X, borderPoint.Y, paint); } // Values points and lines using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = this.BorderLineSize, Color = entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), PathEffect = SKPathEffect.CreateDash(new[] { this.BorderLineSize, this.BorderLineSize * 2 }, 0), IsAntialias = true, }) { var amount = Math.Abs(entry.Value - this.AbsoluteMinimum) / this.ValueRange; canvas.DrawCircle(center.X, center.Y, radius * amount, paint); } canvas.DrawGradientLine(center, entry.Color.WithAlpha(0), point, entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), this.LineSize); canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, this.LineSize); canvas.DrawPoint(point, entry.Color, this.PointSize, this.PointMode); // Labels var labelPoint = this.GetPoint(this.MaxValue, center, angle, radius + this.LabelTextSize + (this.PointSize / 2)); var alignment = SKTextAlign.Left; if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon)) { alignment = SKTextAlign.Center; } else if (angle > (float)(startAngle + Math.PI)) { alignment = SKTextAlign.Right; } canvas.DrawCaptionLabels(entry.Label, entry.TextColor, entry.ValueLabel, entry.Color, this.LabelTextSize, labelPoint, alignment); } } }
private void OnPaintSample(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e) { surfaceWidth = e.Info.Width; surfaceHeight = e.Info.Height; myCanvas = e.Surface.Canvas; float side = Math.Min(surfaceHeight, surfaceWidth) * 0.5f; switch (_重繪狀態) { case 重繪狀態.第一次初始化: myCanvas.Clear(Color.Gray.ToSKColor()); //paint it black break; case 重繪狀態.清除: myCanvas.Clear(Color.Black.ToSKColor()); //paint it black myCanvas.Clear(Color.Red.ToSKColor()); //paint it black myCanvas.Clear(Color.Blue.ToSKColor()); //paint it black myCanvas.Clear(Color.Gray.ToSKColor()); //paint it black break; case 重繪狀態.繪製點: var foo = 1; using (SKPaint paint = new SKPaint()) { paint.Color = Color.FromHex("00FF00").ToSKColor(); paint.StrokeWidth = 5; Random rm = new Random(); for (int i = 0; i < 3000; i++) { //myCanvas.DrawPoint(rm.Next(300), rm.Next(300), SKColor.Parse("#00eFF00")); myCanvas.DrawPoint(rm.Next(surfaceWidth), rm.Next(surfaceHeight), paint); } } break; case 重繪狀態.收集資料: using (SKPaint paint = new SKPaint()) { paint.Color = Color.FromHex("FF0000").ToSKColor(); paint.StrokeWidth = 3; Random rm = new Random(); for (int i = 0; i < surfaceWidth; i++) { var fooPM = rm.Next(10); if (fooPM >= 5) { fooPM = -1; } else { fooPM = 1; } var fooY = surfaceHeight - (32 + i / 3 + (rm.Next(10) * fooPM)); var fooX = i; myCanvas.DrawPoint(fooX, fooY, paint); } } break; case 重繪狀態.繪製線: using (SKPaint paint = new SKPaint()) { paint.Color = Color.Pink.ToSKColor(); paint.StrokeWidth = 7; Random rm = new Random(); var fooPreX = 0; var fooPreY = surfaceHeight - 100; for (int i = 0; i < surfaceWidth / 10; i++) { var fooPM = rm.Next(13); if (fooPM >= 5) { fooPM = -1; } else { fooPM = 1; } var fooY = surfaceHeight - (100 + i + (rm.Next(50) * fooPM)); var fooX = i * 10; myCanvas.DrawLine(fooPreX, fooPreY, fooX, fooY, paint); fooPreX = fooX; fooPreY = fooY; } } break; default: break; } return; using (SKPaint paint = new SKPaint()) { myCanvas.Clear(Color.Gray.ToSKColor()); //paint it black SKRect r1 = new SKRect(10f, 20f, side, side); paint.Color = Color.Blue.ToSKColor(); myCanvas.DrawRect(r1, paint); paint.Color = Color.Red.ToSKColor(); myCanvas.DrawOval(r1, paint); paint.Color = Color.FromHex("00FF00").ToSKColor(); paint.StrokeWidth = 5; Random rm = new Random(); for (int i = 0; i < 3000; i++) { myCanvas.DrawPoint(rm.Next(300), rm.Next(300), paint); //myCanvas.DrawPoint(rm.Next(300), rm.Next(300), SKColor.Parse("#00FF00")); } paint.Color = Color.Green.ToSKColor(); paint.TextSize = 64.0f; paint.IsAntialias = true; paint.Color = new SKColor(0x9C, 0xAF, 0xB7); paint.IsStroke = true; paint.StrokeWidth = 3; paint.TextAlign = SKTextAlign.Center; myCanvas.DrawText("這是Xamarin.Forms", 200f, 200f, paint); myCanvas.DrawText("這是Xamarin.Forms", surfaceWidth / 2f, surfaceHeight / 2f, paint); } }
public SKData DrawHistogram(string referenceName, int zoom, int chunk) { var refer = _service._references.FirstOrDefault(r => r.Name == referenceName); if (chunk == 0 && zoom == 10) { LoadReference(referenceName); } using var surface = SKSurface.Create(new SKImageInfo(refer.Length * zoom, 220)); using SKCanvas canvas = surface.Canvas; canvas.Clear(); using SKPaint paint = new SKPaint { Style = SKPaintStyle.StrokeAndFill, Color = SKColors.Blue, StrokeWidth = 1 }; using SKPaint linePaint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Black, StrokeWidth = 1 }; using SKPaint dashPaint = new SKPaint { Style = SKPaintStyle.Stroke, Color = SKColors.Black, StrokeWidth = 1, PathEffect = SKPathEffect.CreateDash(new[] { 20f, 5f }, 0) }; var histData = _service._histograms[refer.Name]; var scale = (float)(100 / histData.Average()); for (int i = 0; i < refer.Length; i++) { canvas.DrawRect(i * zoom + 5, 200 - (histData[i] * scale), zoom, histData[i] * scale, paint); } canvas.DrawLine(5, 0, 5, 200, linePaint); canvas.DrawLine(5, 199, refer.Length * zoom, 199, linePaint); var average = (int)(Math.Round(histData.Average())); canvas.DrawLine(5, average * scale, refer.Length * zoom, average * scale, dashPaint); using SKPaint textPaint = new SKPaint { Style = SKPaintStyle.StrokeAndFill, Color = SKColors.Black, StrokeWidth = 1, TextSize = 20, Typeface = SKTypeface.FromFamilyName("Courier New"), SubpixelText = true }; canvas.DrawText(average.ToString(), 6, average * scale - 2, textPaint); var cnt = textPaint.MeasureText("ACGT"); if (zoom == 10) { textPaint.TextSize = textPaint.TextSize * 40 / cnt; var shaper = new SKShaper(SKTypeface.FromFamilyName("Courier New")); canvas.DrawShapedText(shaper, reference, 5, 215, textPaint); } var width = (chunk + 1) * WIDTH * zoom > refer.Length * zoom ? refer.Length * zoom % WIDTH : WIDTH; SKPixmap pixmap = surface.Snapshot().Subset(SKRectI.Create(chunk * WIDTH, 0, width, canvas.DeviceClipBounds.Height)).PeekPixels(); var options = new SKWebpEncoderOptions(SKWebpEncoderCompression.Lossless, 100); return(pixmap.Encode(options)); }
/// <summary> /// Creates a bitmap of the graph. /// </summary> /// <param name="Settings">Graph settings.</param> /// <param name="States">State object(s) that contain graph-specific information about its inner states. /// These can be used in calls back to the graph object to make actions on the generated graph.</param> /// <returns>Bitmap</returns> public override SKImage CreateBitmap(GraphSettings Settings, out object[] States) { using (SKSurface Surface = SKSurface.Create(Settings.Width, Settings.Height, SKImageInfo.PlatformColorType, SKAlphaType.Premul)) { SKCanvas Canvas = Surface.Canvas; States = new object[0]; Canvas.Clear(Settings.BackgroundColor); int x1, y1, x2, y2, x3, y3, w, h; x1 = Settings.MarginLeft; x2 = Settings.Width - Settings.MarginRight; y1 = Settings.MarginTop; y2 = Settings.Height - Settings.MarginBottom; if (!string.IsNullOrEmpty(this.labelY)) { x1 += (int)(Settings.LabelFontSize * 2 + 0.5); } if (!string.IsNullOrEmpty(this.labelX)) { y2 -= (int)(Settings.LabelFontSize * 2 + 0.5); } if (!string.IsNullOrEmpty(this.title)) { y1 += (int)(Settings.LabelFontSize * 2 + 0.5); } IVector YLabels = GetLabels(ref this.minY, ref this.maxY, this.y, Settings.ApproxNrLabelsY, out LabelType YLabelType); SKPaint Font = new SKPaint() { FilterQuality = SKFilterQuality.High, HintingLevel = SKPaintHinting.Full, SubpixelText = true, IsAntialias = true, Style = SKPaintStyle.Fill, Color = Settings.AxisColor, Typeface = SKTypeface.FromFamilyName(Settings.FontName, SKTypefaceStyle.Normal), TextSize = (float)Settings.LabelFontSize }; float Size; double MaxSize = 0; if (this.showYAxis) { foreach (IElement Label in YLabels.ChildElements) { Size = Font.MeasureText(LabelString(Label, YLabelType)); if (Size > MaxSize) { MaxSize = Size; } } } x3 = (int)Math.Ceiling(x1 + MaxSize) + Settings.MarginLabel; IVector XLabels = GetLabels(ref this.minX, ref this.maxX, this.x, Settings.ApproxNrLabelsX, out LabelType XLabelType); MaxSize = 0; if (this.showXAxis) { foreach (IElement Label in XLabels.ChildElements) { Size = Font.MeasureText(LabelString(Label, XLabelType)); if (Size > MaxSize) { MaxSize = Size; } } } y3 = (int)Math.Floor(y2 - MaxSize) - Settings.MarginLabel; w = x2 - x3; h = y3 - y1; SKPaint AxisBrush = new SKPaint() { FilterQuality = SKFilterQuality.High, IsAntialias = true, Style = SKPaintStyle.Fill, Color = Settings.AxisColor }; SKPaint GridBrush = new SKPaint() { FilterQuality = SKFilterQuality.High, IsAntialias = true, Style = SKPaintStyle.Fill, Color = Settings.GridColor }; SKPaint AxisPen = new SKPaint() { FilterQuality = SKFilterQuality.High, IsAntialias = true, Style = SKPaintStyle.Stroke, Color = Settings.AxisColor, StrokeWidth = Settings.AxisWidth }; SKPaint GridPen = new SKPaint() { FilterQuality = SKFilterQuality.High, IsAntialias = true, Style = SKPaintStyle.Stroke, Color = Settings.GridColor, StrokeWidth = Settings.GridWidth }; double OrigoX; double OrigoY; if (this.minX.AssociatedSet is IAbelianGroup AgX) { OrigoX = Scale(new ObjectVector(AgX.AdditiveIdentity), this.minX, this.maxX, x3, w)[0]; } else { OrigoX = 0; } if (this.minY.AssociatedSet is IAbelianGroup AgY) { OrigoY = Scale(new ObjectVector(AgY.AdditiveIdentity), this.minY, this.maxY, y3, -h)[0]; } else { OrigoY = 0; } DrawingArea DrawingArea = new DrawingArea(this.minX, this.maxX, this.minY, this.maxY, x3, y3, w, -h, (float)OrigoX, (float)OrigoY); double[] LabelYY = DrawingArea.ScaleY(YLabels); int i = 0; float f; string s; foreach (IElement Label in YLabels.ChildElements) { Size = Font.MeasureText(s = LabelString(Label, YLabelType)); f = (float)LabelYY[i++]; if (this.showGrid) { if (Label is DoubleNumber && ((DoubleNumber)Label).Value == 0) { Canvas.DrawLine(x3, f, x2, f, AxisPen); } else { Canvas.DrawLine(x3, f, x2, f, GridPen); } } if (this.showYAxis) { f += (float)Settings.LabelFontSize * 0.5f; Canvas.DrawText(s, x3 - Size - Settings.MarginLabel, f, Font); } } double[] LabelXX = DrawingArea.ScaleX(XLabels); i = 0; foreach (IElement Label in XLabels.ChildElements) { Size = Font.MeasureText(s = LabelString(Label, XLabelType)); f = (float)LabelXX[i++]; if (this.showGrid) { if (Label is DoubleNumber && ((DoubleNumber)Label).Value == 0) { Canvas.DrawLine(f, y1, f, y3, AxisPen); } else { Canvas.DrawLine(f, y1, f, y3, GridPen); } } if (this.showXAxis) { f -= Size * 0.5f; if (f < x3) { f = x3; } else if (f + Size > x3 + w) { f = x3 + w - Size; } Canvas.DrawText(s, f, y3 + Settings.MarginLabel + (float)Settings.LabelFontSize, Font); } } Font.Dispose(); Font = null; Font = new SKPaint() { FilterQuality = SKFilterQuality.High, HintingLevel = SKPaintHinting.Full, SubpixelText = true, IsAntialias = true, Style = SKPaintStyle.Fill, Color = Settings.AxisColor, Typeface = SKTypeface.FromFamilyName(Settings.FontName, SKTypefaceStyle.Bold), TextSize = (float)(Settings.LabelFontSize * 1.5) }; if (!string.IsNullOrEmpty(this.title)) { Size = Font.MeasureText(this.title); f = x3 + (x2 - x3 - Size) * 0.5f; if (f < x3) { f = x3; } else if (f + Size > x3 + w) { f = x3 + w - Size; } Canvas.DrawText(this.title, f, (float)(Settings.MarginTop + 1.5 * Settings.LabelFontSize), Font); } if (!string.IsNullOrEmpty(this.labelX)) { Size = Font.MeasureText(this.labelX); f = x3 + (x2 - x3 - Size) * 0.5f; if (f < x3) { f = x3; } else if (f + Size > x3 + w) { f = x3 + w - Size; } Canvas.DrawText(this.labelX, f, (float)(y2 + 0.45 * Settings.LabelFontSize), Font); } if (!string.IsNullOrEmpty(this.labelY)) { Size = Font.MeasureText(this.labelY); f = y3 - (y3 - y1 - Size) * 0.5f; if (f - Size < y1) { f = y1 + Size; } else if (f > y3 + h) { f = y3 + h; } Canvas.Translate((float)(Settings.MarginLeft + 0.05 * Settings.LabelFontSize), f); Canvas.RotateDegrees(-90); Canvas.DrawText(this.labelY, 0, 0, Font); Canvas.ResetMatrix(); } IEnumerator <IVector> ex = this.x.GetEnumerator(); IEnumerator <IVector> ey = this.y.GetEnumerator(); IEnumerator <object[]> eParameters = this.parameters.GetEnumerator(); IEnumerator <DrawCallback> eCallbacks = this.callbacks.GetEnumerator(); SKPoint[] Points; SKPoint[] PrevPoints = null; object[] PrevParameters = null; DrawCallback PrevCallback = null; while (ex.MoveNext() && ey.MoveNext() && eParameters.MoveNext() && eCallbacks.MoveNext()) { Points = DrawingArea.Scale(ex.Current, ey.Current); if (PrevCallback != null && eCallbacks.Current.Target.GetType() == PrevCallback.Target.GetType()) { eCallbacks.Current(Canvas, Points, eParameters.Current, PrevPoints, PrevParameters, DrawingArea); } else { eCallbacks.Current(Canvas, Points, eParameters.Current, null, null, DrawingArea); } PrevPoints = Points; PrevParameters = eParameters.Current; PrevCallback = eCallbacks.Current; } SKImage Result = Surface.Snapshot(); if (Font != null) { Font.Dispose(); } AxisBrush.Dispose(); GridBrush.Dispose(); GridPen.Dispose(); AxisPen.Dispose(); States = new object[] { DrawingArea }; return(Result); } }
//METHODS /********************************************************************** *********************************************************************/ // do the drawing static void PaintSurface(object sender, SKPaintSurfaceEventArgs e) { info = e.Info; var surfaceWidth = info.Width; var surfaceHeight = info.Height; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; if (canvas != null) { canvas.Clear(); //Important! Otherwise the drawing will look messed up in iOS } /*important: the coordinate system starts in the upper left corner*/ float lborder = canvas.LocalClipBounds.Left; float tborder = canvas.LocalClipBounds.Top; float rborder = canvas.LocalClipBounds.Right; float bborder = canvas.LocalClipBounds.Bottom; xe = rborder / 100; //using the variable surfacewidth instead would mess everything up ye = bborder / 100; MakeSKPaint(); //depends on xe and ye and therfore has to be called after they were initialized /*********************HERE GOES THE DRAWING************************/ //draw background for ram and disc: pink and yellow float bgRamY1 = 1 + rowWidth; float bgRamY2 = bgRamY1 + (rowWidth * ramSize); float bgDiscY1 = bgRamY2; float bgDiscY2 = bgDiscY1 + (rowWidth * discSize); SKRect sk_rBackgroundRam = new SKRect(1 * xe, bgRamY1 * ye, 99 * xe, bgRamY2 * ye); //left , top, right, bottom SKRect sk_rBackgroundDisc = new SKRect(1 * xe, bgDiscY1 * ye, 99 * xe, bgDiscY2 * ye); //left , top, right, bottom canvas.DrawRect(sk_rBackgroundRam, sk_PaintYellow); //left, top, right, bottom, color canvas.DrawRect(sk_rBackgroundDisc, sk_PaintPink); //draw the words RAM and DISC float blackTextSize = sk_blackText.TextSize; float posTexty = (0.5f + rowWidth + (rowWidth / 2.0f)) * ye + (blackTextSize / 2.0f); // ye is already calculated in blacktextsize float posTextx = columnCenter * xe + xe; //its already centered when specified in new SKPaint (... for (int i = 0; i < ramSize; i++) { canvas.DrawText("RAM", posTextx, posTexty, sk_blackText); posTexty += rowWidth * ye; } for (int i = 0; i < discSize; i++) { canvas.DrawText(App._disk, posTextx, posTexty, sk_blackText); posTexty += rowWidth * ye; } //draw the page sequence float blackTextNumbersSize = sk_blackTextNumbers.TextSize; float posTexty2 = ((rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f) - 0.4f * ye; float posTextx2 = (1 + columnCenter + columnWidth) * xe; foreach (var p in SequenceList) { canvas.DrawText(p.ToString(), posTextx2, posTexty2, sk_blackTextNumbers); posTextx2 += columnWidth * xe; } //prepare a square float posPFX1 = 1 + columnWidth; // 1 + columnWidth + (columnWidth / 6) * 1; float posPFX2 = posPFX1 + columnWidth; // posPFX1 + (columnWidth / 6) * 4; float posPFY1 = 1 + rowWidth; //1 + rowWidth + (rowWidth / 10) * 1; float posPFY2 = posPFY1 + rowWidth; // posPFY1 + (rowWidth / 10) * 8; //prepare a circle float radius = 0; float cx = 1 + columnWidth + columnCenter; float cy = 1 + rowWidth + rowCenter; //if (rowWidth > columnWidth){ radius = columnWidth / 2.6f * xe;} //else{ radius = rowWidth / 2.2f * ye;} radius = xPercent(0.025f); //draw pagefails for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { if (PageReplacementStrategies.ram[step, 0, 3] == 2) { //with replacement(circle) canvas.DrawCircle(cx * xe, cy * ye, radius, sk_PaintWhite); //center x, center y, radius, paint canvas.DrawCircle(cx * xe, cy * ye, radius, sk_PaintBlue); //center x, center y, radius, } else if (PageReplacementStrategies.ram[step, 0, 3] == 1) { //without replacement (square) //SKRect sk_Pagefail = new SKRect(posPFX1 * xe, posPFY1 * ye, posPFX2 * xe, posPFY2 * ye); //left , top, right, bottom SKRect sk_Pagefail = new SKRect(posPFX1 * xe, posPFY1 * ye, posPFX2 * xe, posPFY2 * ye); //left , top, right, canvas.DrawRect(sk_Pagefail, sk_PaintWhite); //left, top, right, bottom, color canvas.DrawRect(sk_Pagefail, sk_PaintBlue); //left, top, right, bottom, color } posPFX1 += columnWidth; posPFX2 = posPFX1 + columnWidth;// posPFX1 + (columnWidth / 6) * 4; cx += columnWidth; } //draw Ram: for every step thats done yet, look for pages in ram float posXText = (1 + columnCenter + columnWidth) * xe; float posYText = (rowWidth + (rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f); for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { for (int ram = 0; ram <= PageReplacementStrategies.ram.GetUpperBound(1); ram++) { int page = PageReplacementStrategies.ram[step, ram, 0]; if (page != -1) { canvas.DrawText(page.ToString(), posXText, posYText, sk_blackTextNumbers); } posYText += rowWidth * ye; } posYText = (rowWidth + (rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f); posXText += columnWidth * xe; } //draw Disc: for evry step thats done yet, look for pages in disc posXText = (1 + columnCenter + columnWidth) * xe; posYText += rowWidth * ye; for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { for (int disc = 0; disc <= PageReplacementStrategies.disc.GetUpperBound(1); disc++) { int page = PageReplacementStrategies.disc[step, disc]; if (page != -1) { canvas.DrawText(page.ToString(), posXText, posYText, sk_blackTextNumbers); } posYText += rowWidth * ye; } posYText = (rowWidth * (ramSize + 1) + (rowWidth / 2.0f)) * ye + (blackTextNumbersSize / 2.0f); posXText += columnWidth * xe; } //draw M-Bits and R-Bits float posXbit = (1 + columnWidth + columnCenter - columnCenter / 2) * xe; float blackTextSmallSize = sk_blackTextSmall.TextSize; float blankSpace = rowWidth * ye - blackTextSmallSize * 2.000f; if (blankSpace < 0.000f) { blankSpace = 0.000f; } float spaceY = blankSpace / 3.0000f; float posYRbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize; float posYMbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize + spaceY + blackTextSmallSize; if (PageReplacementStrategies.strategy == "RNU FIFO Second Chance" || PageReplacementStrategies.strategy == "RNU FIFO") { for (int step = 0; step <= PageReplacementStrategies.currentStep; step++) { for (int ram = 0; ram <= PageReplacementStrategies.ram.GetUpperBound(1); ram++) { if (PageReplacementStrategies.ram[step, ram, 0] != -1) { String rBitValue = PageReplacementStrategies.ram[step, ram, 1].ToString(); String mBitValue = PageReplacementStrategies.ram[step, ram, 2].ToString(); if (PageReplacementStrategies.ram[step, ram, 4] == 0) { canvas.DrawText(rBitValue, posXbit, posYRbit, sk_blackTextSmall); } else { canvas.DrawText(rBitValue, posXbit, posYRbit, sk_redTextSmall); } if (PageReplacementStrategies.ram[step, ram, 5] == 0) { canvas.DrawText(mBitValue, posXbit, posYMbit, sk_blackTextSmall); } else { canvas.DrawText(mBitValue, posXbit, posYMbit, sk_redTextSmall); } } posYMbit += rowWidth * ye; posYRbit += rowWidth * ye; } posXbit += columnWidth * xe; posYMbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize + spaceY + blackTextSmallSize; posYRbit = 0.4f * ye + rowWidth * ye + spaceY + blackTextSmallSize; } } //Draw rows and colums float posCol = 1; for (int i = 0; i <= colums; i++) { if (i == 0 || i == 1 || i == colums) { //first, second and last line is fat canvas.DrawLine(new SKPoint(posCol * xe, 1 * ye), new SKPoint(posCol * xe, 99 * ye), sk_PaintFat); } else { canvas.DrawLine(new SKPoint(posCol * xe, 1 * ye), new SKPoint(posCol * xe, 99 * ye), sk_PaintThin); } posCol += columnWidth; } float posRow = 1; for (int i = 0; i <= rows; i++) { if (i == 0 || i == 1 || i == rows || i == ramSize + 1) { //first, second and last line is fat, also the seperating line between ram and disc canvas.DrawLine(new SKPoint(1 * xe, posRow * ye), new SKPoint(99 * xe, posRow * ye), sk_PaintFat); } else { canvas.DrawLine(new SKPoint(1 * xe, posRow * ye), new SKPoint(99 * xe, posRow * ye), sk_PaintThin); } posRow += rowWidth; } //execute all drawing actions canvas.Flush(); }
public static (bool newRow, int usedWidth) DrawLine(SKCanvas canvas, SKBitmap bitmap, List <SKPoint> points, SKPaint paint, int size = 6, string text = "", int labelRow = 0, int labelXOffset = 0, bool drawPoint = false, float labelYHeight = -1, SKBitmap bitmapIcon = null) { bool newRow = false; if (paint == null) { paint = new SKPaint() { Color = WhiteColor } } ; // Dont fill the rectangles paint.Style = SKPaintStyle.Stroke; int xOffset = 120; // TODO maybe trough padding float usedLabelWidth = paint.MeasureText(text) + 70 /* buffer */; if (xOffset + labelXOffset + usedLabelWidth > bitmap.Width) { labelRow++; labelXOffset = 0; newRow = true; } if (points.Count == 0) { return(false, -1); } SKPoint prevPoint = points.First(); foreach (var point in points) { if (drawPoint) { canvas.DrawRect(new SKRect(point.X - size / 2, point.Y - size / 2, point.X + size / 2, point.Y + size / 2), paint); } canvas.DrawLine(prevPoint, point, paint); prevPoint = point; } // draw Legend int height = bitmap.Height; int yOffset = 25; // TODO Make padding depending int iconDist = 20; var textPaint = MediumTextPaint; int yBase = height - yOffset - (int)textPaint.TextSize / 2 + labelRow * 20; int xBase = xOffset + labelXOffset; if (drawPoint) { canvas.DrawRect(new SKRect(xBase - size / 2 - iconDist / 2, yBase - size / 2, xBase + size / 2 - iconDist / 2, yBase + size / 2), paint); } canvas.DrawLine(new SKPoint(xBase - iconDist, yBase), new SKPoint(xBase, yBase), paint); canvas.DrawText(text, new SKPoint(xBase + 5, yBase + size), textPaint); // TODO Correct paint? if (labelYHeight > 0) { var specialPaint = textPaint; specialPaint.Color = paint.Color; canvas.DrawText(text, new SKPoint(bitmap.Width - 140 /* TODO dynamic trough padding */, labelYHeight), specialPaint); // TODO Correct paint? if (bitmapIcon != null) { canvas.DrawBitmap(bitmapIcon, new SKPoint(bitmap.Width - 140 /* TODO dynamic trough padding */, labelYHeight)); } } return(newRow, (int)usedLabelWidth); }
private void DrawAxes() { bool VerticalOrientation = this.canvasView.Width < this.canvasView.Height ? true : false; SKCanvas canvas = this.fullPlotSurface.Canvas; SKPaint yAxisUnitPaint = new SKPaint { Color = SKColors.Gray, TextAlign = SKTextAlign.Right, IsAntialias = true, TextSize = 14f }; SKPaint refLinePaint = new SKPaint { Color = SKColors.LightGray, Style = SKPaintStyle.Stroke, StrokeWidth = 1f, PathEffect = SKPathEffect.CreateDash(new float[] { 6f, 3f }, 0), IsAntialias = true }; //draw y axis float gridBottomX = this.gridPosX; float gridBottomY = this.gridHeight; for (float UVNum = minY; UVNum <= maxY; ++UVNum) { float unitsFromGridBottom = UVNum * this.unitsPerUVLevel; float curUVPointX = gridBottomX; float curUVPointY = gridBottomY - unitsFromGridBottom; if (VerticalOrientation) { // draw line canvas.DrawLine(curUVPointX, curUVPointY, (float)this.canvasView.Width, curUVPointY, refLinePaint); } if (UVNum % this.deltaY == 0f || UVNum == 0f) { // write text at each reference point float paddingX = 5f; float paddingY = (yAxisUnitPaint.TextSize * 0.3f); canvas.DrawText(UVNum.ToString(), curUVPointX - paddingX, curUVPointY + paddingY, yAxisUnitPaint); // draw line canvas.DrawLine(curUVPointX, curUVPointY, (float)this.canvasView.Width, curUVPointY, refLinePaint); } } SKPaint axisLabelPaint = new SKPaint { Color = SKColors.Gray, TextAlign = SKTextAlign.Center, IsAntialias = true, TextSize = 18f }; float verAxisPosX = axisLabelPaint.TextSize * 0.8f; float verAxisPosY = gridBottomY / 2f; canvas.Save(); canvas.RotateDegrees(-90, verAxisPosX, verAxisPosY); canvas.DrawText("UV Level", verAxisPosX, verAxisPosY, axisLabelPaint); canvas.Restore(); SKPaint timeAxisMarks = new SKPaint { Color = SKColors.LightGray, Style = SKPaintStyle.Stroke, StrokeWidth = 1f, IsAntialias = true }; SKPaint xAxisUnitPaint = new SKPaint { Color = SKColors.Gray, TextAlign = SKTextAlign.Center, IsAntialias = true, TextSize = 14f }; //for each x mark for (TimeSpan timeValue = minX; timeValue <= maxX; timeValue = timeValue.Add(TimeSpan.FromHours(1.0d))) { int hourValue = timeValue.Hours; int minuteValue = timeValue.Minutes; string timeText = hourValue.ToString() + ":" + minuteValue.ToString("D2"); float displacementFromBottom = (float)(timeValue.TotalMinutes - minX.TotalMinutes) * this.unitsPerMinute; float curTimePointX = gridBottomX + displacementFromBottom; float curTimePointY = gridBottomY; float markLength = 5f; if (timeValue.TotalMinutes % this.deltaX.TotalMinutes == 0) { //major mark markLength = 10f; canvas.DrawText(timeText, curTimePointX, curTimePointY + (paddingHeight), xAxisUnitPaint); } canvas.DrawLine(curTimePointX, curTimePointY, curTimePointX, curTimePointY + markLength, timeAxisMarks); } }
public override void DrawContent(SKCanvas canvas, int width, int height) { var total = Entries?.Count() ?? 0; if (total > 0) { var captionHeight = Entries.Max(x => { var result = 0.0f; var hasLabel = !string.IsNullOrEmpty(x.Label); var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel); if (hasLabel || hasValueLabel) { var hasOffset = hasLabel && hasValueLabel; var captionMargin = LabelTextSize * 0.60f; var space = hasOffset ? captionMargin : 0; if (hasLabel) { result += LabelTextSize; } if (hasValueLabel) { result += LabelTextSize; } } return(result); }); var center = new SKPoint(width / 2, height / 2); var radius = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight; var rangeAngle = (float)((Math.PI * 2) / total); var startAngle = (float)Math.PI; var nextEntry = Entries.First(); var nextAngle = startAngle; var nextPoint = GetPoint(nextEntry.Value * AnimationProgress, center, nextAngle, radius); DrawBorder(canvas, center, radius); using (var clip = new SKPath()) { clip.AddCircle(center.X, center.Y, radius); for (int i = 0; i < total; i++) { var angle = nextAngle; var entry = nextEntry; var point = nextPoint; var nextIndex = (i + 1) % total; nextAngle = startAngle + (rangeAngle * nextIndex); nextEntry = Entries.ElementAt(nextIndex); nextPoint = GetPoint(nextEntry.Value * AnimationProgress, center, nextAngle, radius); canvas.Save(); canvas.ClipPath(clip); // Border center bars using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = BorderLineSize, Color = BorderLineColor, IsAntialias = true, }) { var borderPoint = GetPoint(MaxValue, center, angle, radius); canvas.DrawLine(point.X, point.Y, borderPoint.X, borderPoint.Y, paint); } // Values points and lines using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = BorderLineSize, Color = entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f * AnimationProgress)), PathEffect = SKPathEffect.CreateDash(new[] { BorderLineSize, BorderLineSize * 2 }, 0), IsAntialias = true, }) { var amount = Math.Abs(entry.Value - AbsoluteMinimum) / ValueRange; canvas.DrawCircle(center.X, center.Y, radius * amount, paint); } canvas.DrawGradientLine(center, entry.Color.WithAlpha(0), point, entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), LineSize); canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, LineSize); canvas.DrawPoint(point, entry.Color, PointSize, PointMode); canvas.Restore(); // Labels var labelPoint = new SKPoint(0, radius + LabelTextSize + (PointSize / 2)); var rotation = SKMatrix.CreateRotation(angle); labelPoint = center + rotation.MapPoint(labelPoint); var alignment = SKTextAlign.Left; if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon)) { alignment = SKTextAlign.Center; } else if (angle > (float)(startAngle + Math.PI)) { alignment = SKTextAlign.Right; } canvas.DrawCaptionLabels(entry.Label, entry.TextColor, TextDirection, LabelTextSpacing, entry.ValueLabel, entry.Color.WithAlpha((byte)(255 * AnimationProgress)), LabelTextSize, labelPoint, alignment, base.Typeface, out var _); } } } }
public void DrawLine(IPen pen, CanvasPoint p1, CanvasPoint p2) { _canvas?.DrawLine(p1.ToSKPoint(), p2.ToSKPoint(), GetSKPaint(pen)); }
public void DrawLine(Pen pen, float x1, float y1, float x2, float y2) { _image.DrawLine(x1, y1, x2, y2, pen.SKPaint()); }