private SKPath CalculateArrowPath(double height, double width) { SKPath ArrowPath = new SKPath(); SKPoint[] points = new SKPoint[12]; double radius = Math.Min(height, width) / 2; float centerX = (float)(width / 2); float centerY = (float)(height / 2); // omega 6 to 3 ration from nutrients consumed double ratioO63 = nutConsumed.ElementAt(nutConsumed.Count - 1); double tipX = 0; // calculation for where the tip point of the arrow should be if (ratioO63 >= 20) { tipX = width / 2 - 0.8 * radius; } else { tipX = width / 2 - 0.8 * radius * ratioO63 / 20; } SKPoint tipPoint = new SKPoint((float)tipX, centerY); points[0] = tipPoint; // arrowhead left and right points var headWidth = radius * 0.1; var headHeight = radius * 0.2; SKPoint leftHeadPoint = new SKPoint((float)(tipX - headWidth), (float)(centerY - headHeight)); points[1] = leftHeadPoint; SKPoint rightHeadPoint = new SKPoint((float)(tipX + headWidth), (float)(centerY - headHeight)); points[11] = rightHeadPoint; // Arrow Shaft base points var shaftWidth = radius * 0.04; var shaftBaseHeight = radius * 0.2; SKPoint leftShaftBasePoint = new SKPoint((float)(tipX - shaftWidth), (float)(centerY - shaftBaseHeight)); points[2] = leftShaftBasePoint; SKPoint rightShaftBasePoint = new SKPoint((float)(tipX + shaftWidth), (float)(centerY - shaftBaseHeight)); points[10] = rightShaftBasePoint; // Arrow Shaft back points var shaftBackHeight = radius * 0.6; SKPoint leftShaftBackPoint = new SKPoint((float)(tipX - shaftWidth), (float)(centerY - shaftBackHeight)); points[3] = leftShaftBackPoint; SKPoint rightShaftBackPoint = new SKPoint((float)(tipX + shaftWidth), (float)(centerY - shaftBackHeight)); points[9] = rightShaftBackPoint; // Arrow Feathers bottom points var featherBottomHeight = radius * 0.7; var featherWidth = radius * 0.075; SKPoint leftFeatherBottomPoint = new SKPoint((float)(tipX - featherWidth), (float)(centerY - featherBottomHeight)); points[4] = leftFeatherBottomPoint; SKPoint rightFeatherBottomPoint = new SKPoint((float)(tipX + featherWidth), (float)(centerY - featherBottomHeight)); points[8] = rightFeatherBottomPoint; // Arrow Feathers top point var feathertopHeight = radius * 0.9; SKPoint leftFeatherTopPoint = new SKPoint((float)(tipX - featherWidth), (float)(centerY - feathertopHeight)); points[5] = leftFeatherTopPoint; SKPoint rightFeatherTopPoint = new SKPoint((float)(tipX + featherWidth), (float)(centerY - feathertopHeight)); points[7] = rightFeatherTopPoint; // Central back point SKPoint centralBackPoint = new SKPoint((float)tipX, (float)(centerY - radius * 0.70)); points[6] = centralBackPoint; ArrowPath.AddPoly(points, true); return(ArrowPath); }
internal void DrawMarker(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pRefPoint, SKPoint pMarkerPoint1, SKPoint pMarkerPoint2, SKPoint pMarkerPoint3) { float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; float fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI); xDiff = pMarkerPoint3.X - pMarkerPoint2.X; yDiff = pMarkerPoint3.Y - pMarkerPoint2.Y; float fAngle2 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI); DrawMarker(svgMarker, pOwner, pRefPoint, (fAngle1 + fAngle2) / 2); }
/// <summary> /// Update path /// </summary> private static (SKPath, SKPoint) CreateCalloutPath(CalloutStyle callout, double contentWidth, double contentHeight) { var strokeWidth = callout.StrokeWidth < 1 ? 1 : callout.StrokeWidth; var paddingLeft = callout.Padding.Left < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Left; var paddingTop = callout.Padding.Top < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Top; var paddingRight = callout.Padding.Right < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Right; var paddingBottom = callout.Padding.Bottom < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Bottom; var width = (float)contentWidth + (float)paddingLeft + (float)paddingRight; var height = (float)contentHeight + (float)paddingTop + (float)paddingBottom; var halfWidth = width * callout.ArrowPosition; var halfHeight = height * callout.ArrowPosition; var bottom = height + callout.ShadowWidth + strokeWidth * 2; var left = callout.ShadowWidth + strokeWidth; var top = callout.ShadowWidth + strokeWidth; var right = width + callout.ShadowWidth + strokeWidth * 2; var start = new SKPoint(); var center = new SKPoint(); var end = new SKPoint(); // Check, if we are to near at corners if (halfWidth - callout.ArrowWidth * 0.5f - left < callout.RectRadius) { halfWidth = callout.ArrowWidth * 0.5f + left + callout.RectRadius; } else if (halfWidth + callout.ArrowWidth * 0.5f > width - callout.RectRadius) { halfWidth = width - callout.ArrowWidth * 0.5f - callout.RectRadius; } if (halfHeight - callout.ArrowWidth * 0.5f - top < callout.RectRadius) { halfHeight = callout.ArrowWidth * 0.5f + top + callout.RectRadius; } else if (halfHeight + callout.ArrowWidth * 0.5f > height - callout.RectRadius) { halfHeight = height - callout.ArrowWidth * 0.5f - callout.RectRadius; } switch (callout.ArrowAlignment) { case ArrowAlignment.Bottom: start = new SKPoint(halfWidth + callout.ArrowWidth * 0.5f, bottom); center = new SKPoint(halfWidth, bottom + callout.ArrowHeight); end = new SKPoint(halfWidth - callout.ArrowWidth * 0.5f, bottom); break; case ArrowAlignment.Top: top += callout.ArrowHeight; bottom += callout.ArrowHeight; start = new SKPoint(halfWidth - callout.ArrowWidth * 0.5f, top); center = new SKPoint(halfWidth, top - callout.ArrowHeight); end = new SKPoint(halfWidth + callout.ArrowWidth * 0.5f, top); break; case ArrowAlignment.Left: left += callout.ArrowHeight; right += callout.ArrowHeight; start = new SKPoint(left, halfHeight + callout.ArrowWidth * 0.5f); center = new SKPoint(left - callout.ArrowHeight, halfHeight); end = new SKPoint(left, halfHeight - callout.ArrowWidth * 0.5f); break; case ArrowAlignment.Right: start = new SKPoint(right, halfHeight - callout.ArrowWidth * 0.5f); center = new SKPoint(right + callout.ArrowHeight, halfHeight); end = new SKPoint(right, halfHeight + callout.ArrowWidth * 0.5f); break; } // Create path var path = new SKPath(); // Move to start point at left/top path.MoveTo(left + callout.RectRadius, top); // Top horizontal line if (callout.ArrowAlignment == ArrowAlignment.Top) { DrawArrow(path, start, center, end); } // Top right arc path.ArcTo(new SKRect(right - callout.RectRadius, top, right, top + callout.RectRadius), 270, 90, false); // Right vertical line if (callout.ArrowAlignment == ArrowAlignment.Right) { DrawArrow(path, start, center, end); } // Bottom right arc path.ArcTo(new SKRect(right - callout.RectRadius, bottom - callout.RectRadius, right, bottom), 0, 90, false); // Bottom horizontal line if (callout.ArrowAlignment == ArrowAlignment.Bottom) { DrawArrow(path, start, center, end); } // Bottom left arc path.ArcTo(new SKRect(left, bottom - callout.RectRadius, left + callout.RectRadius, bottom), 90, 90, false); // Left vertical line if (callout.ArrowAlignment == ArrowAlignment.Left) { DrawArrow(path, start, center, end); } // Top left arc path.ArcTo(new SKRect(left, top, left + callout.RectRadius, top + callout.RectRadius), 180, 90, false); path.Close(); return(path, center); }
internal static SKPoint HandleBezier(SKPoint startPoint, SKPoint offsetStartPoint, SKPoint offsetEndPoint, SKPoint endPoint, float t) { var x = Math.Pow(1 - t, 3) * startPoint.X + 3 * Math.Pow(1 - t, 2) * t * offsetStartPoint.X + 3 * (1 - t) * Math.Pow(t, 2) * offsetEndPoint.X + Math.Pow(t, 3) * endPoint.X; var y = Math.Pow(1 - t, 3) * startPoint.Y + 3 * Math.Pow(1 - t, 2) * t * offsetStartPoint.Y + 3 * (1 - t) * Math.Pow(t, 2) * offsetEndPoint.Y + Math.Pow(t, 3) * endPoint.Y; return(new SKPoint((float)x, (float)y)); }
internal void DrawMarker(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pMarkerPoint, float fAngle) { var markerElement = GetMarkerElement(svgMarker); if (markerElement == null) { return; } var skMarkerMatrix = SKMatrix.MakeIdentity(); var skMatrixMarkerPoint = SKMatrix.MakeTranslation(pMarkerPoint.X, pMarkerPoint.Y); SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixMarkerPoint); var skMatrixAngle = SKMatrix.MakeRotationDegrees(svgMarker.Orient.IsAuto ? fAngle : svgMarker.Orient.Angle); SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixAngle); var strokeWidth = pOwner.StrokeWidth.ToDeviceValue(null, UnitRenderingType.Other, svgMarker); var refX = svgMarker.RefX.ToDeviceValue(null, UnitRenderingType.Horizontal, svgMarker); var refY = svgMarker.RefY.ToDeviceValue(null, UnitRenderingType.Horizontal, svgMarker); float markerWidth = svgMarker.MarkerWidth; float markerHeight = svgMarker.MarkerHeight; float viewBoxToMarkerUnitsScaleX = 1f; float viewBoxToMarkerUnitsScaleY = 1f; switch (svgMarker.MarkerUnits) { case SvgMarkerUnits.StrokeWidth: { var skMatrixStrokeWidth = SKMatrix.MakeScale(strokeWidth, strokeWidth); SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixStrokeWidth); var viewBoxWidth = svgMarker.ViewBox.Width; var viewBoxHeight = svgMarker.ViewBox.Height; var scaleFactorWidth = (viewBoxWidth <= 0) ? 1 : (markerWidth / viewBoxWidth); var scaleFactorHeight = (viewBoxHeight <= 0) ? 1 : (markerHeight / viewBoxHeight); viewBoxToMarkerUnitsScaleX = Math.Min(scaleFactorWidth, scaleFactorHeight); viewBoxToMarkerUnitsScaleY = Math.Min(scaleFactorWidth, scaleFactorHeight); var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX * viewBoxToMarkerUnitsScaleX, -refY * viewBoxToMarkerUnitsScaleY); SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixTranslateRefXY); var skMatrixScaleXY = SKMatrix.MakeScale(viewBoxToMarkerUnitsScaleX, viewBoxToMarkerUnitsScaleY); SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixScaleXY); } break; case SvgMarkerUnits.UserSpaceOnUse: { var skMatrixTranslateRefXY = SKMatrix.MakeTranslation(-refX, -refY); SKMatrix.PreConcat(ref skMarkerMatrix, ref skMatrixTranslateRefXY); } break; } _skCanvas.Save(); var skMatrix = SkiaUtil.GetSKMatrix(svgMarker.Transforms); SKMatrix.PreConcat(ref skMatrix, ref skMarkerMatrix); SetTransform(skMatrix); SetClipPath(svgMarker, _disposable); var skPaintOpacity = SetOpacity(svgMarker, _disposable); var skPaintFilter = SetFilter(svgMarker, _disposable); switch (svgMarker.Overflow) { case SvgOverflow.Auto: case SvgOverflow.Visible: case SvgOverflow.Inherit: break; default: var skClipRect = SKRect.Create( svgMarker.ViewBox.MinX, svgMarker.ViewBox.MinY, markerWidth / viewBoxToMarkerUnitsScaleX, markerHeight / viewBoxToMarkerUnitsScaleY); _skCanvas.ClipRect(skClipRect, SKClipOperation.Intersect); break; } Draw(markerElement, true); if (skPaintFilter != null) { _skCanvas.Restore(); } if (skPaintOpacity != null) { _skCanvas.Restore(); } _skCanvas.Restore(); }
public static SKPoint GetPosition(SKPoint center, float dist, float angle) { return(new SKPoint((float)(center.X + dist * Math.Cos(angle * FDegToRad)), (float)(center.Y + dist * Math.Sin(angle * FDegToRad)))); }
public static float Magnitude(this SKPoint self) { return((float)Math.Sqrt(self.X * self.X + self.Y * self.Y)); }
static double Length(SKPoint pt0, SKPoint pt1) { return(Math.Sqrt(Math.Pow(pt1.X - pt0.X, 2) + Math.Pow(pt1.Y - pt0.Y, 2))); }
public static SKPath CloneWithTransform(this SKPath pathIn, Func <SKPoint, SKPoint> transform) { SKPath pathOut = new SKPath(); using (SKPath.RawIterator iterator = pathIn.CreateRawIterator()) { SKPoint[] points = new SKPoint[4]; SKPathVerb pathVerb = SKPathVerb.Move; SKPoint firstPoint = new SKPoint(); SKPoint lastPoint = new SKPoint(); while ((pathVerb = iterator.Next(points)) != SKPathVerb.Done) { switch (pathVerb) { case SKPathVerb.Move: pathOut.MoveTo(transform(points[0])); firstPoint = lastPoint = points[0]; break; case SKPathVerb.Line: SKPoint[] linePoints = Interpolate(points[0], points[1]); foreach (SKPoint pt in linePoints) { pathOut.LineTo(transform(pt)); } lastPoint = points[1]; break; case SKPathVerb.Cubic: SKPoint[] cubicPoints = FlattenCubic(points[0], points[1], points[2], points[3]); foreach (SKPoint pt in cubicPoints) { pathOut.LineTo(transform(pt)); } lastPoint = points[3]; break; case SKPathVerb.Quad: SKPoint[] quadPoints = FlattenQuadratic(points[0], points[1], points[2]); foreach (SKPoint pt in quadPoints) { pathOut.LineTo(transform(pt)); } lastPoint = points[2]; break; case SKPathVerb.Conic: SKPoint[] conicPoints = FlattenConic(points[0], points[1], points[2], iterator.ConicWeight()); foreach (SKPoint pt in conicPoints) { pathOut.LineTo(transform(pt)); } lastPoint = points[2]; break; case SKPathVerb.Close: SKPoint[] closePoints = Interpolate(lastPoint, firstPoint); foreach (SKPoint pt in closePoints) { pathOut.LineTo(transform(pt)); } firstPoint = lastPoint = new SKPoint(0, 0); pathOut.Close(); break; } } } return(pathOut); }
public virtual void OnDraw(SKCanvas canvas, SKPoint pos, IChartBase chart) { }
public static Point ToPoint(this SKPoint point) { return(new Point(point.X, point.Y)); }
public static Metadata GetMetadata(HttpClient client, ILogger log, Uri imageUri, int defaultTileWidth, string requestId) { Ckdu_codestream codestream = new Ckdu_codestream(); try { using (var family_src = new JPEG2000Source(log, requestId)) using (var wrapped_src = new Cjpx_source()) using (var jp2_source = new Cjp2_source()) { family_src.Open(client, imageUri, false); int success = wrapped_src.open(family_src, true); if (success < 1) { family_src.close(); wrapped_src.close(); throw new IOException("could not be read as JPEG2000"); } jp2_source.open(family_src); while (!jp2_source.read_header()) { ; } int ref_component = 0; codestream.create(wrapped_src.access_codestream(ref_component).open_stream()); Ckdu_dims image_dims = new Ckdu_dims(); codestream.get_dims(ref_component, image_dims); Ckdu_coords image_size = image_dims.access_size(); int levels = codestream.get_min_dwt_levels(); var imageSize = new SKPoint(image_size.x, image_size.y); Ckdu_dims tile_dims = new Ckdu_dims(); codestream.get_tile_dims(new Ckdu_coords(0, 0), ref_component, tile_dims); var tileSize = new SKPoint(tile_dims.access_size().x, tile_dims.access_size().y); int[] precincts = new int[levels]; // get precinct info using (var param = codestream.access_siz().access_cluster("COD")) { bool usePrecincts = false; param.get("Cuse_precincts", 0, 0, ref usePrecincts); if (usePrecincts) { for (int i = 0; i < levels; i++) { param.get("Cprecincts", i, 0, ref precincts[i]); } tileSize = new SKPoint(precincts[0], precincts[0]); } // if no precincts defined, we should fall back on default size if it reports // tile size as being image size else if (tileSize == imageSize) { tileSize = new SKPoint(defaultTileWidth, defaultTileWidth); } } tile_dims.Dispose(); image_size.Dispose(); image_dims.Dispose(); if (codestream.exists()) { codestream.destroy(); } family_src.close(); return(new Metadata { Width = Convert.ToInt32(imageSize.X), Height = Convert.ToInt32(imageSize.Y), ScalingLevels = levels, TileWidth = Convert.ToInt32(tileSize.X), TileHeight = Convert.ToInt32(tileSize.Y) }); } } finally { if (codestream.exists()) { codestream.destroy(); } } }
public SKTapDetectedEventArgs(SKPoint location) : this(location, 1) { }
public SKTapDetectedEventArgs(SKPoint location, int tapCount) { Location = location; TapCount = tapCount; }
internal void Draw(DrawingContextImpl context, SKCanvas canvas, SKPoint origin, DrawingContextImpl.PaintWrapper foreground, bool canUseLcdRendering) { /* TODO: This originated from Native code, it might be useful for debugging character positions as * we improve the FormattedText support. Will need to port this to C# obviously. Rmove when * not needed anymore. * * SkPaint dpaint; * ctx->Canvas->save(); * ctx->Canvas->translate(origin.fX, origin.fY); * for (int c = 0; c < Lines.size(); c++) * { * dpaint.setARGB(255, 0, 0, 0); * SkRect rc; * rc.fLeft = 0; * rc.fTop = Lines[c].Top; * rc.fRight = Lines[c].Width; * rc.fBottom = rc.fTop + LineOffset; * ctx->Canvas->drawRect(rc, dpaint); * } * for (int c = 0; c < Length; c++) * { * dpaint.setARGB(255, c % 10 * 125 / 10 + 125, (c * 7) % 10 * 250 / 10, (c * 13) % 10 * 250 / 10); * dpaint.setStyle(SkPaint::kFill_Style); * ctx->Canvas->drawRect(Rects[c], dpaint); * } * ctx->Canvas->restore(); */ using (var paint = _paint.Clone()) { IDisposable currd = null; var currentWrapper = foreground; SKPaint currentPaint = null; try { ApplyWrapperTo(ref currentPaint, foreground, ref currd, paint, canUseLcdRendering); bool hasCusomFGBrushes = _foregroundBrushes.Any(); for (int c = 0; c < _skiaLines.Count; c++) { AvaloniaFormattedTextLine line = _skiaLines[c]; float x = TransformX(origin.X, 0, paint.TextAlign); if (!hasCusomFGBrushes) { var subString = Text.Substring(line.Start, line.Length); canvas.DrawText(subString, x, origin.Y + line.Top + _lineOffset, paint); } else { float currX = x; string subStr; int len; for (int i = line.Start; i < line.Start + line.Length;) { var fb = GetNextForegroundBrush(ref line, i, out len); if (fb != null) { //TODO: figure out how to get the brush size currentWrapper = context.CreatePaint(fb, new Size()); } else { if (!currentWrapper.Equals(foreground)) { currentWrapper.Dispose(); } currentWrapper = foreground; } subStr = Text.Substring(i, len); ApplyWrapperTo(ref currentPaint, currentWrapper, ref currd, paint, canUseLcdRendering); canvas.DrawText(subStr, currX, origin.Y + line.Top + _lineOffset, paint); i += len; currX += paint.MeasureText(subStr); } } } } finally { if (!currentWrapper.Equals(foreground)) { currentWrapper.Dispose(); } currd?.Dispose(); } } }
private Geometries.Point GetScreenPosition(SKPoint point) { return(new Geometries.Point(point.X / _skiaScale, point.Y / _skiaScale)); }
public ImageDrawable(SvgImage svgImage, SKRect skOwnerBounds, Drawable?root, Drawable?parent, Attributes ignoreAttributes = Attributes.None) : base(svgImage, root, parent) { IgnoreAttributes = ignoreAttributes; IsDrawable = CanDraw(svgImage, IgnoreAttributes) && HasFeatures(svgImage, IgnoreAttributes); if (!IsDrawable) { return; } float width = svgImage.Width.ToDeviceValue(UnitRenderingType.Horizontal, svgImage, skOwnerBounds); float height = svgImage.Height.ToDeviceValue(UnitRenderingType.Vertical, svgImage, skOwnerBounds); float x = svgImage.Location.X.ToDeviceValue(UnitRenderingType.Horizontal, svgImage, skOwnerBounds); float y = svgImage.Location.Y.ToDeviceValue(UnitRenderingType.Vertical, svgImage, skOwnerBounds); var location = new SKPoint(x, y); if (width <= 0f || height <= 0f || svgImage.Href == null) { IsDrawable = false; return; } // TODO: Check for image recursive references. //if (SkiaUtil.HasRecursiveReference(svgImage, (e) => e.Href)) //{ // _canDraw = false; // return; //} var image = SvgImageExtensions.GetImage(svgImage.Href, svgImage.OwnerDocument); var skImage = image as SKImage; var svgFragment = image as SvgFragment; if (skImage == null && svgFragment == null) { IsDrawable = false; return; } if (skImage != null) { _disposable.Add(skImage); } SrcRect = default; if (skImage != null) { SrcRect = SKRect.Create(0f, 0f, skImage.Width, skImage.Height); } if (svgFragment != null) { var skSize = SvgExtensions.GetDimensions(svgFragment); SrcRect = SKRect.Create(0f, 0f, skSize.Width, skSize.Height); } var destClip = SKRect.Create(location.X, location.Y, width, height); var aspectRatio = svgImage.AspectRatio; if (aspectRatio.Align != SvgPreserveAspectRatio.none) { var fScaleX = destClip.Width / SrcRect.Width; var fScaleY = destClip.Height / SrcRect.Height; var xOffset = 0f; var yOffset = 0f; if (aspectRatio.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } switch (aspectRatio.Align) { case SvgPreserveAspectRatio.xMinYMin: break; case SvgPreserveAspectRatio.xMidYMin: xOffset = (destClip.Width - SrcRect.Width * fScaleX) / 2; break; case SvgPreserveAspectRatio.xMaxYMin: xOffset = (destClip.Width - SrcRect.Width * fScaleX); break; case SvgPreserveAspectRatio.xMinYMid: yOffset = (destClip.Height - SrcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMidYMid: xOffset = (destClip.Width - SrcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - SrcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMaxYMid: xOffset = (destClip.Width - SrcRect.Width * fScaleX); yOffset = (destClip.Height - SrcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatio.xMinYMax: yOffset = (destClip.Height - SrcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMidYMax: xOffset = (destClip.Width - SrcRect.Width * fScaleX) / 2; yOffset = (destClip.Height - SrcRect.Height * fScaleY); break; case SvgPreserveAspectRatio.xMaxYMax: xOffset = (destClip.Width - SrcRect.Width * fScaleX); yOffset = (destClip.Height - SrcRect.Height * fScaleY); break; } DestRect = SKRect.Create( destClip.Left + xOffset, destClip.Top + yOffset, SrcRect.Width * fScaleX, SrcRect.Height * fScaleY); } else { DestRect = destClip; } Clip = destClip; var skClipRect = SvgClippingExtensions.GetClipRect(svgImage, destClip); if (skClipRect != null) { Clip = skClipRect; } if (skImage != null) { Image = skImage; } if (svgFragment != null) { FragmentDrawable = new FragmentDrawable(svgFragment, skOwnerBounds, root, this, ignoreAttributes); _disposable.Add(FragmentDrawable); } IsAntialias = SvgPaintingExtensions.IsAntialias(svgImage); if (Image != null) { TransformedBounds = DestRect; } if (FragmentDrawable != null) { //_skBounds = _fragmentDrawable._skBounds; TransformedBounds = DestRect; } Transform = SvgTransformsExtensions.ToSKMatrix(svgImage.Transforms); FragmentTransform = SKMatrix.MakeIdentity(); if (FragmentDrawable != null) { float dx = DestRect.Left; float dy = DestRect.Top; float sx = DestRect.Width / SrcRect.Width; float sy = DestRect.Height / SrcRect.Height; var skTranslationMatrix = SKMatrix.MakeTranslation(dx, dy); var skScaleMatrix = SKMatrix.MakeScale(sx, sy); SKMatrix.PreConcat(ref FragmentTransform, ref skTranslationMatrix); SKMatrix.PreConcat(ref FragmentTransform, ref skScaleMatrix); } Fill = null; Stroke = null; // TODO: Transform _skBounds using _skMatrix. SKMatrix.MapRect(ref Transform, out TransformedBounds, ref TransformedBounds); }
private static SKPoint InterpolatePoint(SKPoint a, SKPoint b, float t) { return(new SKPoint( a.X + t * (b.X - a.X), a.Y + t * (b.Y - a.Y))); }
public static SKPoint DpToPixel(this SKPoint self) { self.X *= density; self.Y *= density; return(self); }
protected virtual void TouchGestureRecognizerOnPan(object sender, PanEventArgs args) { SKPoint resultVector = args.NewPoint - args.PreviousPoint; _skScene.MoveByVector(resultVector); }
public static Vector2 ToVector2(this SKPoint self) { return(new Vector2(self.X, self.Y)); }
protected virtual void TouchGestureRecognizerOnDoubleTap(object sender, TapEventArgs args) { SKPoint scenePoint = _skScene.GetCanvasPointFromViewPoint(args.ViewPoint); _skScene.ZoomByScaleFactor(scenePoint, DoubleTapScaleFactor); }
internal static Tuple <double, double> GetYValues(SKPoint StartPoint, SKPoint ControlPoint, SKPoint EndPoint, float X) { var Ax = StartPoint.X; var Bx = ControlPoint.X; var Cx = EndPoint.X; var q1 = 2 * Ax - 2 * Bx; var q2 = Math.Sqrt(5 * Ax * Ax - 10 * Ax * Bx + Ax * Cx - Ax * X + 2 * Bx * X + 4 * Bx * Bx); var q3 = 2 * Ax - 4 * Bx + 2 * Cx; var t1 = (q1 + q2) / q3; var t2 = (q1 - q2) / q3; var Ay = StartPoint.Y; var By = ControlPoint.Y; var Cy = EndPoint.Y; var Y1 = Ay * (1 - t1) * (1 - t1) + By * 2 * (1 - t1) * t1 + Cy * t1; var Y2 = Ay * (1 - t2) * (1 - t2) + By * 2 * (1 - t2) * t2 + Cy * t2; return(new Tuple <double, double>(Y1, Y2)); }
/// <summary> /// Paint FastPoint Chart. /// </summary> /// <param name="graph">The Chart Graphics object.</param> /// <param name="common">The Common elements object.</param> /// <param name="area">Chart area for this chart.</param> /// <param name="seriesToDraw">Chart series to draw.</param> virtual public void Paint( ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw) { Common = common; Graph = graph; if (area.Area3DStyle.Enable3D) { // Initialize variables chartArea3DEnabled = true; matrix3D = area.matrix3D; } else { chartArea3DEnabled = false; } //************************************************************ //** Loop through all series //************************************************************ foreach (Series series in common.DataManager.Series) { // Process non empty series of the area with FastPoint chart type if (String.Compare(series.ChartTypeName, Name, true, System.Globalization.CultureInfo.CurrentCulture) != 0 || series.ChartArea != area.Name || !series.IsVisible()) { continue; } // Get 3D series depth and Z position if (chartArea3DEnabled) { area.GetSeriesZPositionAndDepth(series, out float seriesDepth, out seriesZCoordinate); seriesZCoordinate += seriesDepth / 2.0f; } // Set active horizontal/vertical axis Axis hAxis = area.GetAxis(AxisName.X, series.XAxisType, (area.Area3DStyle.Enable3D) ? string.Empty : Series.XSubAxisName); Axis vAxis = area.GetAxis(AxisName.Y, series.YAxisType, (area.Area3DStyle.Enable3D) ? string.Empty : Series.YSubAxisName); double hAxisMin = hAxis.ViewMinimum; double hAxisMax = hAxis.ViewMaximum; double vAxisMin = vAxis.ViewMinimum; double vAxisMax = vAxis.ViewMaximum; // Get "PermittedPixelError" attribute. // By default use 1/3 of the marker size. float permittedPixelError = series.MarkerSize / 3f; if (series.IsCustomPropertySet(CustomPropertyName.PermittedPixelError)) { string attrValue = series[CustomPropertyName.PermittedPixelError]; bool parseSucceed = float.TryParse(attrValue, NumberStyles.Any, CultureInfo.CurrentCulture, out float pixelError); if (parseSucceed) { permittedPixelError = pixelError; } else { throw (new InvalidOperationException(SR.ExceptionCustomAttributeValueInvalid2("PermittedPixelError"))); } // "PermittedPixelError" attribute value should be in range from zero to 1 if (permittedPixelError < 0f || permittedPixelError > 1f) { throw (new InvalidOperationException(SR.ExceptionCustomAttributeIsNotInRange0to1("PermittedPixelError"))); } } // Get pixel size in axes coordinates SKSize pixelSize = graph.GetRelativeSize(new SKSize(permittedPixelError, permittedPixelError)); SKSize axesMin = graph.GetRelativeSize(new SKSize((float)hAxisMin, (float)vAxisMin)); double axesValuesPixelSizeX = Math.Abs(hAxis.PositionToValue(axesMin.Width + pixelSize.Width, false) - hAxis.PositionToValue(axesMin.Width, false)); double axesValuesPixelSizeY = Math.Abs(vAxis.PositionToValue(axesMin.Height + pixelSize.Height, false) - vAxis.PositionToValue(axesMin.Height, false)); // Create point marker brush SKPaint markerBrush = new() { Color = (series.MarkerColor == SKColor.Empty) ? series.Color : series.MarkerColor, Style = SKPaintStyle.Fill }; SKPaint emptyMarkerBrush = new() { Color = (series.EmptyPointStyle.MarkerColor == SKColor.Empty) ? series.EmptyPointStyle.Color : series.EmptyPointStyle.MarkerColor, Style = SKPaintStyle.Fill }; // Create point marker border pen SKPaint borderPen = null; SKPaint emptyBorderPen = null; if (series.MarkerBorderColor != SKColor.Empty && series.MarkerBorderWidth > 0) { borderPen = new SKPaint() { Style = SKPaintStyle.Stroke, Color = series.MarkerBorderColor, StrokeWidth = series.MarkerBorderWidth }; } if (series.EmptyPointStyle.MarkerBorderColor != SKColor.Empty && series.EmptyPointStyle.MarkerBorderWidth > 0) { emptyBorderPen = new SKPaint() { Style = SKPaintStyle.Stroke, Color = series.EmptyPointStyle.MarkerBorderColor, StrokeWidth = series.EmptyPointStyle.MarkerBorderWidth }; } // Check if series is indexed bool indexedSeries = ChartHelper.IndexedSeries(Common, series.Name); // Get marker size taking in consideration current DPIs int markerSize = series.MarkerSize; if (graph != null && graph.Graphics != null) { // Marker size is in pixels and we do the mapping for higher DPIs markerSize = Math.Max(markerSize, markerSize); } // Loop through all ponts in the series int index = 0; double xValuePrev = 0.0; double yValuePrev = 0.0; SKPoint currentPoint = SKPoint.Empty; double xPixelConverter = (graph.Common.ChartPicture.Width - 1.0) / 100.0; double yPixelConverter = (graph.Common.ChartPicture.Height - 1.0) / 100.0; MarkerStyle markerStyle = series.MarkerStyle; MarkerStyle emptyMarkerStyle = series.EmptyPointStyle.MarkerStyle; foreach (DataPoint point in series.Points) { // Get point X and Y values double xValue = (indexedSeries) ? index + 1 : point.XValue; xValue = hAxis.GetLogValue(xValue); double yValue = vAxis.GetLogValue(point.YValues[0]); bool currentPointIsEmpty = point.IsEmpty; // Check if point is completly out of the data scaleView if (xValue < hAxisMin || xValue > hAxisMax || yValue < vAxisMin || yValue > vAxisMax) { xValuePrev = xValue; yValuePrev = yValue; ++index; continue; } // Check if point may be skipped if (index > 0 && Math.Abs(xValue - xValuePrev) < axesValuesPixelSizeX && Math.Abs(yValue - yValuePrev) < axesValuesPixelSizeY) { // Increase counter and proceed to the next data point ++index; continue; } // Get point pixel position currentPoint.X = (float) (hAxis.GetLinearPosition(xValue) * xPixelConverter); currentPoint.Y = (float) (vAxis.GetLinearPosition(yValue) * yPixelConverter); // Draw point marker MarkerStyle currentMarkerStyle = (currentPointIsEmpty) ? emptyMarkerStyle : markerStyle; if (currentMarkerStyle != MarkerStyle.None) { this.DrawMarker( graph, point, index, currentPoint, currentMarkerStyle, markerSize, (currentPointIsEmpty) ? emptyMarkerBrush : markerBrush, (currentPointIsEmpty) ? emptyBorderPen : borderPen); } // Remember last point coordinates xValuePrev = xValue; yValuePrev = yValue; ++index; } // Dispose used brushes and pens markerBrush.Dispose(); emptyMarkerBrush.Dispose(); if (borderPen != null) { borderPen.Dispose(); } if (emptyBorderPen != null) { emptyBorderPen.Dispose(); } } }
internal void DrawMarker(SvgMarker svgMarker, SvgVisualElement pOwner, SKPoint pRefPoint, SKPoint pMarkerPoint1, SKPoint pMarkerPoint2, bool isStartMarker) { float fAngle1 = 0f; if (svgMarker.Orient.IsAuto) { float xDiff = pMarkerPoint2.X - pMarkerPoint1.X; float yDiff = pMarkerPoint2.Y - pMarkerPoint1.Y; fAngle1 = (float)(Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI); if (isStartMarker && svgMarker.Orient.IsAutoStartReverse) { fAngle1 += 180; } } DrawMarker(svgMarker, pOwner, pRefPoint, fAngle1); }
/// <summary> /// Draws a marker that represents a data point in FastPoint series. /// </summary> /// <param name="graph">Chart graphics used to draw the marker.</param> /// <param name="point">Series data point drawn.</param> /// <param name="pointIndex">Data point index in the series.</param> /// <param name="location">Marker location in pixels.</param> /// <param name="markerStyle">Marker style.</param> /// <param name="markerSize">Marker size in pixels.</param> /// <param name="brush">Brush used to fill marker shape.</param> /// <param name="borderPen">Marker border pen.</param> virtual protected void DrawMarker( ChartGraphics graph, DataPoint point, int pointIndex, SKPoint location, MarkerStyle markerStyle, int markerSize, SKPaint brush, SKPaint borderPen) { // Transform 3D coordinates if (chartArea3DEnabled) { Point3D[] points = new Point3D[1]; location = graph.GetRelativePoint(location); points[0] = new Point3D(location.X, location.Y, seriesZCoordinate); matrix3D.TransformPoints(points); location.X = points[0].X; location.Y = points[0].Y; location = graph.GetAbsolutePoint(location); } // Create marker bounding rectangle in pixels SKRect markerBounds = new( location.X - markerSize / 2f, location.Y - markerSize / 2f, markerSize, markerSize); // Draw Marker switch (markerStyle) { case (MarkerStyle.Star4): case (MarkerStyle.Star5): case (MarkerStyle.Star6): case (MarkerStyle.Star10): { // Set number of corners int cornerNumber = 4; if (markerStyle == MarkerStyle.Star5) { cornerNumber = 5; } else if (markerStyle == MarkerStyle.Star6) { cornerNumber = 6; } else if (markerStyle == MarkerStyle.Star10) { cornerNumber = 10; } // Get star polygon SKPoint[] points = ChartGraphics.CreateStarPolygon(markerBounds, cornerNumber); // Fill shape graph.FillPolygon(brush, points); // Draw border if (borderPen != null) { graph.DrawPolygon(borderPen, points); } break; } case (MarkerStyle.Circle): { graph.FillEllipse(brush, markerBounds); // Draw border if (borderPen != null) { graph.DrawEllipse(borderPen, markerBounds); } break; } case (MarkerStyle.Square): { graph.FillRectangle(brush, markerBounds); // Draw border if (borderPen != null) { graph.DrawRectangle( borderPen, (int)Math.Round(markerBounds.Left, 0), (int)Math.Round(markerBounds.Top, 0), (int)Math.Round(markerBounds.Width, 0), (int)Math.Round(markerBounds.Height, 0)); } break; } case (MarkerStyle.Cross): { // Calculate cross line width and size float crossLineWidth = (float)Math.Ceiling(markerSize / 4F); float crossSize = markerSize; // * (float)Math.Sin(45f/180f*Math.PI) // Calculate cross coordinates SKPoint[] points = new SKPoint[12]; points[0].X = location.X - crossSize / 2F; points[0].Y = location.Y + crossLineWidth / 2F; points[1].X = location.X - crossSize / 2F; points[1].Y = location.Y - crossLineWidth / 2F; points[2].X = location.X - crossLineWidth / 2F; points[2].Y = location.Y - crossLineWidth / 2F; points[3].X = location.X - crossLineWidth / 2F; points[3].Y = location.Y - crossSize / 2F; points[4].X = location.X + crossLineWidth / 2F; points[4].Y = location.Y - crossSize / 2F; points[5].X = location.X + crossLineWidth / 2F; points[5].Y = location.Y - crossLineWidth / 2F; points[6].X = location.X + crossSize / 2F; points[6].Y = location.Y - crossLineWidth / 2F; points[7].X = location.X + crossSize / 2F; points[7].Y = location.Y + crossLineWidth / 2F; points[8].X = location.X + crossLineWidth / 2F; points[8].Y = location.Y + crossLineWidth / 2F; points[9].X = location.X + crossLineWidth / 2F; points[9].Y = location.Y + crossSize / 2F; points[10].X = location.X - crossLineWidth / 2F; points[10].Y = location.Y + crossSize / 2F; points[11].X = location.X - crossLineWidth / 2F; points[11].Y = location.Y + crossLineWidth / 2F; // Rotate cross coordinates 45 degrees SKMatrix rotationMatrix = SKMatrix.CreateRotationDegrees(45, location.X, location.Y); rotationMatrix.TransformPoints(points); // Fill shape graph.FillPolygon(brush, points); // Draw border if (borderPen != null) { graph.DrawPolygon(borderPen, points); } break; } case (MarkerStyle.Diamond): { SKPoint[] points = new SKPoint[4]; points[0].X = markerBounds.Left; points[0].Y = markerBounds.Top + markerBounds.Height / 2F; points[1].X = markerBounds.Left + markerBounds.Width / 2F; points[1].Y = markerBounds.Top; points[2].X = markerBounds.Right; points[2].Y = markerBounds.Top + markerBounds.Height / 2F; points[3].X = markerBounds.Left + markerBounds.Width / 2F; points[3].Y = markerBounds.Bottom; graph.FillPolygon(brush, points); // Draw border if (borderPen != null) { graph.DrawPolygon(borderPen, points); } break; } case (MarkerStyle.Triangle): { SKPoint[] points = new SKPoint[3]; points[0].X = markerBounds.Left; points[0].Y = markerBounds.Bottom; points[1].X = markerBounds.Top + markerBounds.Width / 2F; points[1].Y = markerBounds.Top; points[2].X = markerBounds.Right; points[2].Y = markerBounds.Bottom; graph.FillPolygon(brush, points); // Draw border if (borderPen != null) { graph.DrawPolygon(borderPen, points); } break; } default: { throw (new InvalidOperationException(SR.ExceptionFastPointMarkerStyleUnknown)); } } // Process selection regions if (Common.ProcessModeRegions) { Common.HotRegionsList.AddHotRegion( graph.GetRelativeRectangle(markerBounds), point, point.series.Name, pointIndex); } }
internal void OnTouchEffectTouchAction(TouchActionEventArgs args) { SKPoint pixelLocation = new SKPoint((float)(CanvasSize.Width * args.Location.X / Width), (float)(CanvasSize.Height * args.Location.Y / Height));; SKPoint bitmapLocation = inverseBitmapMatrix.MapPoint(pixelLocation); switch (args.Type) { case TouchActionType.Pressed: // Convert radius to bitmap/cropping scale float radius = inverseBitmapMatrix.ScaleX * 50; // Find corner that the finger is touching int cornerIndex = croppingRect.HitTest(bitmapLocation, radius); if (cornerIndex != -1 && !touchPoints.ContainsKey(args.Id)) { TouchPoint touchPoint = new TouchPoint { CornerIndex = cornerIndex, Offset = bitmapLocation - croppingRect.Corners[cornerIndex] }; touchPoints.Add(args.Id, touchPoint); } else { //При получении нажатия в словарь пишем его ID и в переменную записываем коардинаты первой точки if (croppingRect.TestPointInsideSquare(bitmapLocation) && !touchPointsInside.ContainsKey(args.Id)) { touchPointsInside.Add(args.Id, bitmapLocation); bitmapLocationfirst = bitmapLocation; } } break; case TouchActionType.Moved: if (touchPoints.ContainsKey(args.Id)) { TouchPoint touchPoint = touchPoints[args.Id]; croppingRect.MoveCorner(touchPoint.CornerIndex, bitmapLocation - touchPoint.Offset); InvalidateSurface(); } if (touchPointsInside.ContainsKey(args.Id)) { //Если перемещение соответсвует айдишнику от его кардинат вычитаем корадинаты начальной точки и передаем в метод перемещения bitmapLocationlast = bitmapLocation; SKPoint point = new SKPoint(bitmapLocationlast.X - bitmapLocationfirst.X, bitmapLocationlast.Y - bitmapLocationfirst.Y); croppingRect.MoveAllCorner(point); bitmapLocationfirst = bitmapLocationlast; InvalidateSurface(); } break; case TouchActionType.Released: case TouchActionType.Cancelled: if (touchPoints.ContainsKey(args.Id)) { touchPoints.Remove(args.Id); } else if (touchPointsInside.ContainsKey(args.Id)) { touchPointsInside.Remove(args.Id); } break; } }
//gets the correct point to draw. Either a point updated this frame, or the original point in InternalPoints private void GetCorrectPoint(Tuple <Vertex, Vertex>[] updatedPoints, int[] updatedIndices, int internalPointIndex, ref SKPoint p) { if (updatedIndices.Contains(internalPointIndex)) { p.X = updatedPoints[internalPointIndex].Item1.x; p.Y = updatedPoints[internalPointIndex].Item1.y; } else { p.X = InternalPoints[internalPointIndex].x; p.Y = InternalPoints[internalPointIndex].y; } }
/// <summary> /// Draw arrow to path /// </summary> /// <param name="start">Start of arrow at bubble</param> /// <param name="center">Center of arrow</param> /// <param name="end">End of arrow at bubble</param> private static void DrawArrow(SKPath path, SKPoint start, SKPoint center, SKPoint end) { path.LineTo(start); path.LineTo(center); path.LineTo(end); }
private void DrawAxes(SKSize size, SKCanvas canvas, SKPoint pointZero, SKPoint pointMinXMaxY, SKPoint pointMaxXMinY) { //draw coordinate axes canvas.DrawLine(pointZero, pointMinXMaxY, _blackPaint); canvas.DrawLine(pointZero, pointMaxXMinY, _blackPaint); //draw coordinate arcs //MaxY canvas.DrawLine(pointMinXMaxY, new SKPoint(25, 75), _blackPaint); canvas.DrawLine(pointMinXMaxY, new SKPoint(75, 75), _blackPaint); //MaxX canvas.DrawLine(pointMaxXMinY, new SKPoint(size.Width - 75, size.Height - 75), _blackPaint); canvas.DrawLine(pointMaxXMinY, new SKPoint(size.Width - 75, size.Height - 25), _blackPaint); }