コード例 #1
0
        protected override void Draw(SKCanvas canvas)
        {
            var transformationMatrix = SKMatrix.CreateTranslation(Position.X - 266.75f, Position.Y - 272.15f);
            var scale = Size.Width / 200.0f;

            transformationMatrix = transformationMatrix.PostConcat(SKMatrix.CreateScale(scale, scale, Position.X, Position.Y));

            var red = SKPath.ParseSvgPathData("M272.1 107.7c38.8-.6 76.3 14 104.4 40.8l77.7-77.7C405 24.6 339.7-.8 272.1 0 169.2 0 75.1 58 28.9 150l90.4 70.1c21.5-64.5 81.8-112.4 152.8-112.4z");

            red.Transform(transformationMatrix);

            var green = SKPath.ParseSvgPathData("M272.1 544.3c73.4 0 135.3-24.1 180.4-65.7l-87.7-68c-24.4 16.6-55.9 26-92.6 26-71 0-131.2-47.9-152.8-112.3H28.9v70.1c46.2 91.9 140.3 149.9 243.2 149.9z");

            green.Transform(transformationMatrix);

            var blue = SKPath.ParseSvgPathData("M533.5 278.4c0-18.5-1.5-37.1-4.7-55.3H272.1v104.8h147c-6.1 33.8-25.7 63.7-54.4 82.7v68h87.7c51.5-47.4 81.1-117.4 81.1-200.2z");

            blue.Transform(transformationMatrix);

            var yellow = SKPath.ParseSvgPathData("M119.3 324.3c-11.4-33.8-11.4-70.4 0-104.2V150H28.9c-38.6 76.9-38.6 167.5 0 244.4l90.4-70.1z");

            yellow.Transform(transformationMatrix);

            canvas.DrawPath(red, _r);
            canvas.DrawPath(green, _g);
            canvas.DrawPath(blue, _b);
            canvas.DrawPath(yellow, _y);
        }
コード例 #2
0
        public void TranslationToMatrixIsCorrect()
        {
            var m   = SKMatrix.CreateTranslation(5, 7);
            var rsm = SKRotationScaleMatrix.CreateTranslation(5, 7).ToMatrix();

            Assert.Equal(m.Values, rsm.Values);
        }
コード例 #3
0
        /// <inheritdoc />
        public override void Render(SKCanvas canvas, SKRect bounds, SKPaint paint)
        {
            _lastBounds = bounds;

            // For brevity's sake
            ColorGradient gradient = Properties.Colors.BaseValue;

            SKMatrix matrix = SKMatrix.Concat(
                SKMatrix.CreateRotationDegrees(Properties.Rotation, bounds.MidX, bounds.MidY),
                SKMatrix.CreateTranslation(_scrollX, _scrollY)
                );

            // LinearGradientRepeatMode.Mirror is currently the only setting that requires a different tile mode
            SKShaderTileMode tileMode = Properties.RepeatMode.CurrentValue == LinearGradientRepeatMode.Mirror
                ? SKShaderTileMode.Mirror
                : SKShaderTileMode.Repeat;

            // Render gradient
            paint.Shader = SKShader.CreateLinearGradient(
                new SKPoint(bounds.Left, bounds.Top),
                new SKPoint(
                    (Properties.Orientation == LinearGradientOrientationMode.Horizontal ? bounds.Right : bounds.Left) * Properties.WaveSize / 100,
                    (Properties.Orientation == LinearGradientOrientationMode.Horizontal ? bounds.Top : bounds.Bottom) * Properties.WaveSize / 100
                    ),
                gradient.GetColorsArray(0, Properties.RepeatMode.CurrentValue == LinearGradientRepeatMode.RepeatSeamless),
                gradient.GetPositionsArray(0, Properties.RepeatMode.CurrentValue == LinearGradientRepeatMode.RepeatSeamless),
                tileMode,
                matrix
                );

            canvas.DrawRect(bounds, paint);
            paint.Shader?.Dispose();
            paint.Shader = null;
        }
コード例 #4
0
        public void MatrixCanInvert()
        {
            var m = SKMatrix.CreateTranslation(10, 20);

            Assert.True(m.TryInvert(out var inverse));
            Assert.Equal(SKMatrix.CreateTranslation(-10, -20).Values, inverse.Values);
        }
コード例 #5
0
        internal override void Render(SKSurface surface)
        {
            foreach (var shape in Shapes)
            {
                surface.Canvas.Save();

                var visualMatrix = surface.Canvas.TotalMatrix;

                visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateTranslation(shape.Offset.X, shape.Offset.Y));

                if (shape.Scale != new Vector2(1, 1))
                {
                    visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateScale(shape.Scale.X, shape.Scale.Y));
                }

                if (shape.RotationAngleInDegrees != 0)
                {
                    visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateRotationDegrees(shape.RotationAngleInDegrees, shape.CenterPoint.X, shape.CenterPoint.Y));
                }

                if (shape.TransformMatrix != Matrix3x2.Identity)
                {
                    visualMatrix = visualMatrix.PreConcat(shape.TransformMatrix.ToSKMatrix44().Matrix);
                }

                surface.Canvas.SetMatrix(visualMatrix);

                shape.Render(surface);

                surface.Canvas.Restore();
            }
        }
コード例 #6
0
        public void MatrixMapsPoint()
        {
            var matrix         = SKMatrix.CreateTranslation(2, 4);
            var expectedResult = matrix.MapPoint(3, 6);

            Assert.Equal(new SKPoint(5, 10), expectedResult);
        }
コード例 #7
0
        public void MatrixMapsPoints()
        {
            var source = new[] {
                new SKPoint(0, 0),
                new SKPoint(-10, -10),
                new SKPoint(-10, 10),
                new SKPoint(10, -10),
                new SKPoint(10, 10),
                new SKPoint(-5, -5),
                new SKPoint(-5, 5),
                new SKPoint(5, -5),
                new SKPoint(5, 5),
            };

            var expectedResult = new[] {
                new SKPoint(10, 10),
                new SKPoint(0, 0),
                new SKPoint(0, 20),
                new SKPoint(20, 0),
                new SKPoint(20, 20),
                new SKPoint(5, 5),
                new SKPoint(5, 15),
                new SKPoint(15, 5),
                new SKPoint(15, 15),
            };

            var matrix = SKMatrix.CreateTranslation(10, 10);

            matrix.MapPoints(source, source);

            Assert.Equal(expectedResult, source);
        }
コード例 #8
0
        /// <summary>
        ///  Centers the viewport around the specified position(x-index and y-value)
        /// in the chart.Centering the viewport outside the bounds of the chart is
        /// not possible. Makes most sense in combination with the
        /// setScaleMinima(...) method.
        /// </summary>
        /// <param name="transformedPts">the position to center view viewport to</param>
        /// <param name="view"></param>
        public void CenterViewPort(SKPoint transformedPts, IChartBase view)
        {
            float x = transformedPts.X - OffsetLeft;
            float y = transformedPts.Y - OffsetTop;

            Refresh(touchMatrix.PostConcat(SKMatrix.CreateTranslation(-x, -y)), view, true);
        }
コード例 #9
0
        protected override void Draw(SKCanvas canvas)
        {
            var transformationMatrix = SKMatrix.CreateTranslation(Position.X - 11.5f, Position.Y - 11.5f);
            var scale = 6.0f / Size.Width;

            transformationMatrix = transformationMatrix.PostConcat(SKMatrix.CreateScale(scale, scale, Position.X, Position.Y));

            var backgroundPath = SKPath.ParseSvgPathData("M0 0h23v23H0z");

            backgroundPath.Transform(transformationMatrix);

            var redSquarePath = SKPath.ParseSvgPathData("M1 1h10v10H1z");

            redSquarePath.Transform(transformationMatrix);

            var greenSquarePath = SKPath.ParseSvgPathData("M12 1h10v10H12z");

            greenSquarePath.Transform(transformationMatrix);

            var blueSquarePath = SKPath.ParseSvgPathData("M1 12h10v10H1z");

            blueSquarePath.Transform(transformationMatrix);

            var yellowSquarePath = SKPath.ParseSvgPathData("M12 12h10v10H12z");

            yellowSquarePath.Transform(transformationMatrix);

            canvas.DrawPath(backgroundPath, _background);
            canvas.DrawPath(redSquarePath, _r);
            canvas.DrawPath(greenSquarePath, _g);
            canvas.DrawPath(blueSquarePath, _b);
            canvas.DrawPath(yellowSquarePath, _y);
        }
コード例 #10
0
        /// <summary>
        /// Configure paint wrapper for using tile brush.
        /// </summary>
        /// <param name="paintWrapper">Paint wrapper.</param>
        /// <param name="targetSize">Target size.</param>
        /// <param name="tileBrush">Tile brush to use.</param>
        /// <param name="tileBrushImage">Tile brush image.</param>
        private void ConfigureTileBrush(ref PaintWrapper paintWrapper, Size targetSize, ITileBrush tileBrush, IDrawableBitmapImpl tileBrushImage)
        {
            var calc         = new TileBrushCalculator(tileBrush, tileBrushImage.PixelSize.ToSizeWithDpi(_dpi), targetSize);
            var intermediate = CreateRenderTarget(calc.IntermediateSize);

            paintWrapper.AddDisposable(intermediate);

            using (var context = intermediate.CreateDrawingContext(null))
            {
                var sourceRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(96));
                var targetRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(_dpi));

                context.Clear(Colors.Transparent);
                context.PushClip(calc.IntermediateClip);
                context.Transform = calc.IntermediateTransform;
                context.DrawBitmap(
                    RefCountable.CreateUnownedNotClonable(tileBrushImage),
                    1,
                    sourceRect,
                    targetRect,
                    tileBrush.BitmapInterpolationMode);
                context.PopClip();
            }

            var tileTransform =
                tileBrush.TileMode != TileMode.None
                    ? SKMatrix.CreateTranslation(-(float)calc.DestinationRect.X, -(float)calc.DestinationRect.Y)
                    : SKMatrix.CreateIdentity();

            SKShaderTileMode tileX =
                tileBrush.TileMode == TileMode.None
                    ? SKShaderTileMode.Clamp
                    : tileBrush.TileMode == TileMode.FlipX || tileBrush.TileMode == TileMode.FlipXY
                        ? SKShaderTileMode.Mirror
                        : SKShaderTileMode.Repeat;

            SKShaderTileMode tileY =
                tileBrush.TileMode == TileMode.None
                    ? SKShaderTileMode.Clamp
                    : tileBrush.TileMode == TileMode.FlipY || tileBrush.TileMode == TileMode.FlipXY
                        ? SKShaderTileMode.Mirror
                        : SKShaderTileMode.Repeat;


            var image = intermediate.SnapshotImage();

            paintWrapper.AddDisposable(image);

            var paintTransform = default(SKMatrix);

            SKMatrix.Concat(
                ref paintTransform,
                tileTransform,
                SKMatrix.CreateScale((float)(96.0 / _dpi.X), (float)(96.0 / _dpi.Y)));

            using (var shader = image.ToShader(tileX, tileY, paintTransform))
            {
                paintWrapper.Paint.Shader = shader;
            }
        }
コード例 #11
0
ファイル: SampleBase.cs プロジェクト: ywscr/SkiaSharp
        public void Pinch(GestureState state, float scale, SKPoint origin)
        {
            switch (state)
            {
            case GestureState.Started:
                startPinchMatrix = Matrix;
                startPinchOrigin = origin;
                totalPinchScale  = 1f;
                break;

            case GestureState.Running:
                totalPinchScale *= scale;
                var pinchTranslation  = origin - startPinchOrigin;
                var canvasTranslation = SKMatrix.CreateTranslation(pinchTranslation.X, pinchTranslation.Y);
                var canvasScaling     = SKMatrix.CreateScale(totalPinchScale, totalPinchScale, origin.X, origin.Y);
                var canvasCombined    = SKMatrix.Identity;
                SKMatrix.Concat(ref canvasCombined, ref canvasScaling, ref canvasTranslation);
                SKMatrix.Concat(ref Matrix, ref canvasCombined, ref startPinchMatrix);
                break;

            default:
                startPinchMatrix = SKMatrix.Identity;
                startPinchOrigin = SKPoint.Empty;
                totalPinchScale  = 1f;
                break;
            }
        }
コード例 #12
0
        private static SKMatrix CreateRotationMatrix(IReadOnlyViewport viewport, MRect rect, SKMatrix priorMatrix)
        {
            // The front-end sets up the canvas with a matrix based on screen scaling (e.g. retina).
            // We need to retain that effect by combining our matrix with the incoming matrix.

            // We'll create four matrices in addition to the incoming matrix. They perform the
            // zoom scale, focal point offset, user rotation and finally, centering in the screen.

            var userRotation     = SKMatrix.CreateRotationDegrees((float)viewport.Rotation);
            var focalPointOffset = SKMatrix.CreateTranslation(
                (float)(rect.Left - viewport.Center.X),
                (float)(viewport.Center.Y - rect.Top));
            var zoomScale      = SKMatrix.CreateScale((float)(1.0 / viewport.Resolution), (float)(1.0 / viewport.Resolution));
            var centerInScreen = SKMatrix.CreateTranslation((float)(viewport.Width / 2.0), (float)(viewport.Height / 2.0));

            // We'll concatenate them like so: incomingMatrix * centerInScreen * userRotation * zoomScale * focalPointOffset

            var matrix = SKMatrix.Concat(zoomScale, focalPointOffset);

            matrix = SKMatrix.Concat(userRotation, matrix);
            matrix = SKMatrix.Concat(centerInScreen, matrix);
            matrix = SKMatrix.Concat(priorMatrix, matrix);

            return(matrix);
        }
コード例 #13
0
        public static void Save(Dictionary <int, ushort> characterToGlyphMap, SKTypeface typeface, float textSize, string fill, string outputDirectory, ZipArchive?zipArchive)
        {
            var skColor = new SKColor(0x00, 0x00, 0x00);

            using var skTextPaint = new SKPaint
                  {
                      IsAntialias   = true,
                      Color         = skColor,
                      Typeface      = typeface,
                      TextEncoding  = SKTextEncoding.Utf32,
                      TextSize      = textSize,
                      TextAlign     = SKTextAlign.Center,
                      LcdRenderText = true,
                      SubpixelText  = true
                  };

            var metrics  = skTextPaint.FontMetrics;
            var mAscent  = metrics.Ascent;
            var mDescent = metrics.Descent;

            foreach (var kvp in characterToGlyphMap)
            {
                var   charCode = kvp.Key;
                var   utf32    = Char.ConvertFromUtf32((int)charCode);
                float x        = 0;
                float y        = (mAscent / 2.0f) - mDescent / 2.0f;

                using var outlinePath = skTextPaint.GetTextPath(utf32, x, y);
                using var fillPath    = skTextPaint.GetFillPath(outlinePath);

                fillPath.Transform(SKMatrix.CreateTranslation(-fillPath.Bounds.Left, -fillPath.Bounds.Top));

                var bounds      = fillPath.Bounds;
                var svgPathData = fillPath.ToSvgPathData();

                var sb = new StringBuilder();

                sb.AppendLine($"<svg viewBox=\"{bounds.Left} {bounds.Top} {bounds.Width} {bounds.Height}\" xmlns=\"http://www.w3.org/2000/svg\">"); // width=\"{bounds.Width}\" height=\"{bounds.Height}\"
                sb.AppendLine($"  <path fill=\"{fill}\" d=\"{svgPathData}\"/>");
                sb.AppendLine($"</svg>");

                var svg = sb.ToString();

                var outputPath = Path.Combine(outputDirectory, $"{charCode.ToString("X2").PadLeft(5, '0')}_{typeface.FamilyName}.svg");

                if (zipArchive != null)
                {
                    var zipArchiveEntry = zipArchive.CreateEntry(outputPath);
                    using var streamWriter = new StreamWriter(zipArchiveEntry.Open());
                    streamWriter.Write(svg);
                }
                else
                {
                    using var streamWriter = File.CreateText(outputPath);
                    streamWriter.Write(svg);
                }
            }
        }
コード例 #14
0
        /// <summary>
        ///     Opens the render context using the dimensions of the provided path
        /// </summary>
        public void Open(SKPath path, Folder?parent)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("Renderer");
            }

            if (IsOpen)
            {
                throw new ArtemisCoreException("Cannot open render context because it is already open");
            }

            if (path.Bounds != _lastBounds || (parent != null && parent.Bounds != _lastParentBounds) || _lastGraphicsContext != Constants.ManagedGraphicsContext?.GraphicsContext)
            {
                Invalidate();
            }

            if (!_valid || Surface == null)
            {
                SKRect pathBounds = path.Bounds;
                int    width      = (int)pathBounds.Width;
                int    height     = (int)pathBounds.Height;

                SKImageInfo imageInfo = new(width, height);
                if (Constants.ManagedGraphicsContext?.GraphicsContext == null)
                {
                    Surface = SKSurface.Create(imageInfo);
                }
                else
                {
                    Surface = SKSurface.Create(Constants.ManagedGraphicsContext.GraphicsContext, true, imageInfo);
                }

                Path = new SKPath(path);
                Path.Transform(SKMatrix.CreateTranslation(pathBounds.Left * -1, pathBounds.Top * -1));

                TargetLocation = new SKPoint(pathBounds.Location.X, pathBounds.Location.Y);
                if (parent != null)
                {
                    TargetLocation -= parent.Bounds.Location;
                }

                Surface.Canvas.ClipPath(Path);

                _lastParentBounds    = parent?.Bounds ?? new SKRect();
                _lastBounds          = path.Bounds;
                _lastGraphicsContext = Constants.ManagedGraphicsContext?.GraphicsContext;
                _valid = true;
            }

            Paint = new SKPaint();

            Surface.Canvas.Clear();
            Surface.Canvas.Save();

            IsOpen = true;
        }
コード例 #15
0
        public void MatrixCanPostConcat()
        {
            var a = SKMatrix.CreateTranslation(10, 20);
            var b = SKMatrix.CreateTranslation(5, 7);

            var c = a.PostConcat(b);

            Assert.Equal(SKMatrix.CreateTranslation(15, 27).Values, c.Values);
        }
コード例 #16
0
        public void MapRectCreatesModifiedRect()
        {
            var rect = SKRect.Create(2, 4, 6, 8);

            var matrix = SKMatrix.CreateTranslation(10, 12);
            var mapped = matrix.MapRect(rect);

            Assert.Equal(SKRect.Create(12, 16, 6, 8), mapped);
        }
コード例 #17
0
        /// <summary>
        /// Updates the particle's position and orientation based on the given time
        /// </summary>
        /// <para>Call this method first and then <see cref="Paint"/></para>
        /// <para>This method doesn't need to be called on the UI/Main thread</para>
        /// <param name="absoluteElapsedMillis"></param>
        public virtual void Update(long absoluteElapsedMillis, SKSize scale)
        {
            // Determine elapsed time since this particles was created
            var elapsedMillis = absoluteElapsedMillis - _absoluteElapsedMillisPrevious;

            if (_absoluteElapsedMillisPrevious == 0)
            {
                _absoluteElapsedMillisPrevious = absoluteElapsedMillis;
                return;
            }

            _internalAbsoluteMillis       += elapsedMillis;
            _absoluteElapsedMillisPrevious = absoluteElapsedMillis;

            // Traversed distance = speed x time
            var dist = TranslationSpeed * _internalAbsoluteMillis * 0.001;

            // New position
            var deg2radFactor = 0.0174533;
            var angle         = Direction * deg2radFactor;

            Position = InitialPosition + new SKPoint
            {
                X = (float)(dist * Math.Cos(angle)),
                Y = (float)(dist * Math.Sin(angle))
            };

            TransformationMatrix = SKMatrix.CreateTranslation(-Position.X, -Position.Y);

            // New Scale
            TransformationMatrix = TransformationMatrix.PostConcat(SKMatrix.CreateScale(scale.Width, scale.Height));

            // New Orientation
            Orientation = InitialOrientation + new SKPoint3
            {
                X = _internalAbsoluteMillis * 0.001f * RotationSpeed.X,
                Y = _internalAbsoluteMillis * 0.001f * RotationSpeed.Y,
                Z = _internalAbsoluteMillis * 0.001f * RotationSpeed.Z
            };

            _totalRotationMatrix.SetIdentity();

            _xAxisRotationMatrix.SetRotationAboutDegrees(1, 0, 0, Orientation.X);
            _totalRotationMatrix.PostConcat(_xAxisRotationMatrix);

            _yAxisRotationMatrix.SetRotationAboutDegrees(0, 1, 0, Orientation.Y);
            _totalRotationMatrix.PostConcat(_yAxisRotationMatrix);

            _zAxisRotationMatrix.SetRotationAboutDegrees(0, 0, 1, Orientation.Z);
            _totalRotationMatrix.PostConcat(_zAxisRotationMatrix);

            TransformationMatrix = TransformationMatrix.PostConcat(_totalRotationMatrix.Matrix);

            // Translate back
            TransformationMatrix = TransformationMatrix.PostConcat(SKMatrix.CreateTranslation(Position.X, Position.Y));
        }
コード例 #18
0
ファイル: DrawHelper.cs プロジェクト: redowl3/BlazorTest
        public static void PerformMirrorOperation(DrawItem tmpItem, float canvasWidth)
        {
            float midPoint      = canvasWidth / 2.0f;
            float drawMidXPoint = tmpItem.Path.Bounds.MidX;
            float x             = (midPoint - drawMidXPoint) * 2;

            SKMatrix translateXaxis = SKMatrix.CreateTranslation(x, 0);

            tmpItem.Path.Transform(translateXaxis);
        }
コード例 #19
0
        private static void RenderVisual(SKSurface surface, SKImageInfo info, Visual visual)
        {
            if (visual.Opacity != 0)
            {
                surface.Canvas.Save();

                var visualMatrix = surface.Canvas.TotalMatrix;

                visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateTranslation(visual.Offset.X, visual.Offset.Y));

                if (visual.RotationAngleInDegrees != 0)
                {
                    visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateRotationDegrees(visual.RotationAngleInDegrees, visual.CenterPoint.X, visual.CenterPoint.Y));
                }

                if (visual.TransformMatrix != Matrix4x4.Identity)
                {
                    visualMatrix = visualMatrix.PreConcat(visual.TransformMatrix.ToSKMatrix44().Matrix);
                }

                surface.Canvas.SetMatrix(visualMatrix);

                if (visual.Clip is InsetClip insetClip)
                {
                    surface.Canvas.ClipRect(new SKRect {
                        Top    = insetClip.TopInset,
                        Bottom = insetClip.BottomInset,
                        Left   = insetClip.LeftInset,
                        Right  = insetClip.RightInset
                    });
                }

                visual.Render(surface, info);

                switch (visual)
                {
                case SpriteVisual spriteVisual:
                    foreach (var inner in spriteVisual.Children)
                    {
                        RenderVisual(surface, info, inner);
                    }
                    break;

                case ContainerVisual containerVisual:
                    foreach (var inner in containerVisual.Children)
                    {
                        RenderVisual(surface, info, inner);
                    }
                    break;
                }

                surface.Canvas.Restore();
            }
        }
コード例 #20
0
        public virtual void Update(SKCanvas canvas, long absoluteElapsedMillis)
        {
            var elapsedMillis = absoluteElapsedMillis - _absoluteElapsedMillisPrevious;

            if (_absoluteElapsedMillisPrevious == 0)
            {
                _absoluteElapsedMillisPrevious = absoluteElapsedMillis;
                return;
            }

            _internalAbsoluteMillis       += elapsedMillis;
            _absoluteElapsedMillisPrevious = absoluteElapsedMillis;

            canvas.Save();

            // Traversed distance = speed x time
            var dist = TranslationSpeed * _internalAbsoluteMillis * 0.001;

            // New position
            var deg2radFactor = 0.0174533;
            var angle         = Direction * deg2radFactor;

            Position = InitialPosition + new SKPoint
            {
                X = (float)(dist * Math.Cos(angle)),
                Y = (float)(dist * Math.Sin(angle))
            };

            var matrix = SKMatrix.CreateTranslation(-Position.X, -Position.Y);

            // New Orientation
            Orientation = InitialOrientation + new SKPoint3
            {
                X = _internalAbsoluteMillis * 0.001f * RotationSpeed.X,
                Y = _internalAbsoluteMillis * 0.001f * RotationSpeed.Y,
                Z = _internalAbsoluteMillis * 0.001f * RotationSpeed.Z
            };

            var matrix44 = SKMatrix44.CreateIdentity();

            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, Orientation.X));
            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, Orientation.Y));
            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, Orientation.Z));

            // Apply transforms
            matrix = matrix.PostConcat(matrix44.Matrix);
            matrix = matrix.PostConcat(SKMatrix.CreateTranslation(Position.X, Position.Y));
            canvas.SetMatrix(matrix);

            Draw(canvas);

            canvas.Restore();
        }
コード例 #21
0
ファイル: ShapeView.cs プロジェクト: bmacombe/Xamarin.Forms
        SKMatrix CreateMatrix()
        {
            SKMatrix matrix = SKMatrix.CreateIdentity();

            SKRect drawableBounds  = _drawableBounds;
            float  halfStrokeWidth = _skPaint.StrokeWidth / 2;

            drawableBounds.Left   += halfStrokeWidth;
            drawableBounds.Top    += halfStrokeWidth;
            drawableBounds.Right  -= halfStrokeWidth;
            drawableBounds.Bottom -= halfStrokeWidth;

            float widthScale  = drawableBounds.Width / _pathFillBounds.Width;
            float heightScale = drawableBounds.Height / _pathFillBounds.Height;

            switch (_stretch)
            {
            case Stretch.None:
                drawableBounds = _drawableBounds;
                float adjustX = Math.Min(0, _pathStrokeBounds.Left);
                float adjustY = Math.Min(0, _pathStrokeBounds.Top);
                if (adjustX < 0 || adjustY < 0)
                {
                    matrix = SKMatrix.CreateTranslation(-adjustX, -adjustY);
                }
                break;

            case Stretch.Fill:
                matrix = SKMatrix.CreateScale(widthScale, heightScale);
                matrix = matrix.PostConcat(
                    SKMatrix.CreateTranslation(drawableBounds.Left - widthScale * _pathFillBounds.Left,
                                               drawableBounds.Top - heightScale * _pathFillBounds.Top));
                break;

            case Stretch.Uniform:
                float minScale = Math.Min(widthScale, heightScale);
                matrix = SKMatrix.CreateScale(minScale, minScale);
                matrix = matrix.PostConcat(
                    SKMatrix.CreateTranslation(drawableBounds.Left - (minScale * _pathFillBounds.Left) + (drawableBounds.Width - (minScale * _pathFillBounds.Width)) / 2,
                                               drawableBounds.Top - (minScale * _pathFillBounds.Top) + (drawableBounds.Height - (minScale * _pathFillBounds.Height)) / 2));
                break;

            case Stretch.UniformToFill:
                float maxScale = Math.Max(widthScale, heightScale);
                matrix = SKMatrix.CreateScale(maxScale, maxScale);
                matrix = matrix.PostConcat(
                    SKMatrix.CreateTranslation(drawableBounds.Left - (maxScale * _pathFillBounds.Left),
                                               drawableBounds.Top - (maxScale * _pathFillBounds.Top)));
                break;
            }

            return(matrix);
        }
コード例 #22
0
        /**
         * <summary>Expands the size of this quad stretching around its center.</summary>
         * <param name="valueX">Expansion's horizontal extent.</param>
         * <param name="valueY">Expansion's vertical extent.</param>
         * <returns>This quad.</returns>
         */
        public Quad Inflate(float valueX, float valueY)
        {
            SKRect oldBounds = GetBounds();
            var    matrix    = SKMatrix.CreateTranslation(oldBounds.MidX, oldBounds.MidY);

            matrix           = matrix.PreConcat(SKMatrix.CreateScale(1 + valueX * 2 / oldBounds.Width, 1 + valueY * 2 / oldBounds.Height));
            matrix           = matrix.PreConcat(SKMatrix.CreateTranslation(-(oldBounds.MidX), -(oldBounds.MidY)));
            pointTopLeft     = matrix.MapPoint(pointTopLeft);
            pointTopRight    = matrix.MapPoint(pointTopRight);
            pointBottomRight = matrix.MapPoint(pointBottomRight);
            pointBottomLeft  = matrix.MapPoint(pointBottomLeft);
            return(this);
        }
コード例 #23
0
        private protected SKMatrix CreateTransformMatrix(SKRect bounds)
        {
            var transform = SKMatrix.Identity;

            // Translate to origin
            if (CenterPoint != Vector2.Zero)
            {
                transform = SKMatrix.CreateTranslation(-CenterPoint.X, -CenterPoint.Y);
            }

            // Scaling
            if (Scale != Vector2.One)
            {
                transform = transform.PostConcat(SKMatrix.CreateScale(Scale.X, Scale.Y));
            }

            // Rotating
            if (RotationAngle != 0)
            {
                transform = transform.PostConcat(SKMatrix.CreateRotation(RotationAngle));
            }

            // Translating
            if (Offset != Vector2.Zero)
            {
                transform = transform.PostConcat(SKMatrix.CreateTranslation(Offset.X, Offset.Y));
            }

            // Translate back
            if (CenterPoint != Vector2.Zero)
            {
                transform = transform.PostConcat(SKMatrix.CreateTranslation(CenterPoint.X, CenterPoint.Y));
            }

            if (!TransformMatrix.IsIdentity)
            {
                transform = transform.PostConcat(TransformMatrix.ToSKMatrix());
            }

            var relativeTransform = RelativeTransformMatrix.IsIdentity ? SKMatrix.Identity : RelativeTransformMatrix.ToSKMatrix();

            if (!relativeTransform.IsIdentity)
            {
                relativeTransform.TransX *= bounds.Width;
                relativeTransform.TransY *= bounds.Height;

                transform = transform.PostConcat(relativeTransform);
            }

            return(transform);
        }
コード例 #24
0
        protected override void Draw(SKCanvas canvas)
        {
            var transformationMatrix = SKMatrix.CreateTranslation(Position.X - 8.0f, Position.Y - 8.0f);
            var scale = 6.0f / Size.Width;

            transformationMatrix = transformationMatrix.PostConcat(SKMatrix.CreateScale(scale, scale, Position.X, Position.Y));

            var backgroundPath = SKPath.ParseSvgPathData(
                "M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z");

            backgroundPath.Transform(transformationMatrix);

            canvas.DrawPath(backgroundPath, _paint);
        }
コード例 #25
0
 public override void PrepareMatrixOffset(bool inverted)
 {
     if (!inverted)
     {
         MatrixOffset = SKMatrix.Identity.PostConcat(SKMatrix.CreateTranslation(ViewPortHandler.OffsetLeft,
                                                                                ViewPortHandler.ChartHeight - ViewPortHandler.OffsetBottom));
     }
     else
     {
         MatrixOffset = SKMatrix
                        .CreateTranslation(ViewPortHandler.OffsetRight - ViewPortHandler.ChartWidth, ViewPortHandler.ChartHeight - ViewPortHandler.OffsetTop)
                        .PostConcat(SKMatrix.CreateScale(-1f, 1f));
     }
 }
コード例 #26
0
        /// <summary>
        /// 单指操纵
        /// </summary>
        /// <param name="prevPoint"></param>
        /// <param name="newPoint"></param>
        /// <param name="pivotPoint"></param>
        /// <returns></returns>
        public SKMatrix OneFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            if (Mode == TouchManipulationMode.None)
            {
                return(SKMatrix.CreateIdentity());
            }

            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  delta       = newPoint - prevPoint;

            if (Mode == TouchManipulationMode.ScaleDualRotate)  // One-finger rotation
            {
                SKPoint oldVector = prevPoint - pivotPoint;
                SKPoint newVector = newPoint - pivotPoint;

                float scale = Magnitude(newVector) / Magnitude(oldVector);


                // Avoid rotation if fingers are too close to center
                if (Magnitude(newVector) > 30 && Magnitude(oldVector) > 30)
                {
                    float prevAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                    float newAngle  = (float)Math.Atan2(newVector.Y, newVector.X);

                    // Calculate rotation matrix
                    float angle = newAngle - prevAngle;
                    touchMatrix = SKMatrix.CreateRotation(angle, pivotPoint.X, pivotPoint.Y);

                    // Effectively rotate the old vector
                    float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                    oldVector.X = magnitudeRatio * newVector.X;
                    oldVector.Y = magnitudeRatio * newVector.Y;

                    // Recalculate delta
                    delta = newVector - oldVector;
                }

                if (!float.IsNaN(scale) && !float.IsInfinity(scale))
                {
                    var tm = SKMatrix.CreateScale(scale, scale, pivotPoint.X, pivotPoint.Y);
                    touchMatrix.PostConcat(tm);
                }
            }

            // Multiply the rotation matrix by a translation matrix
            touchMatrix.PostConcat(SKMatrix.CreateTranslation(delta.X, delta.Y));

            return(touchMatrix);
        }
コード例 #27
0
ファイル: Compositor.Skia.cs プロジェクト: Robert-Louis/Uno
        private void RenderVisual(SKSurface surface, SKImageInfo info, Visual visual)
        {
            if (visual.Opacity != 0 && visual.IsVisible)
            {
                surface.Canvas.Save();

                var visualMatrix = surface.Canvas.TotalMatrix;

                visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateTranslation(visual.Offset.X, visual.Offset.Y));
                visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateTranslation(visual.AnchorPoint.X, visual.AnchorPoint.Y));

                if (visual.RotationAngleInDegrees != 0)
                {
                    visualMatrix = visualMatrix.PreConcat(SKMatrix.CreateRotationDegrees(visual.RotationAngleInDegrees, visual.CenterPoint.X, visual.CenterPoint.Y));
                }

                if (visual.TransformMatrix != Matrix4x4.Identity)
                {
                    visualMatrix = visualMatrix.PreConcat(visual.TransformMatrix.ToSKMatrix44().Matrix);
                }

                surface.Canvas.SetMatrix(visualMatrix);

                ApplyClip(surface, visual);

                using var opacityDisposable = PushOpacity(visual.Opacity);

                visual.Render(surface, info);

                switch (visual)
                {
                case SpriteVisual spriteVisual:
                    foreach (var inner in spriteVisual.Children)
                    {
                        RenderVisual(surface, info, inner);
                    }
                    break;

                case ContainerVisual containerVisual:
                    foreach (var inner in containerVisual.Children)
                    {
                        RenderVisual(surface, info, inner);
                    }
                    break;
                }

                surface.Canvas.Restore();
            }
        }
コード例 #28
0
ファイル: SKRoundRectTest.cs プロジェクト: ywscr/SkiaSharp
        public void CanTransform()
        {
            var radii = new[] { new SKPoint(5, 5), new SKPoint(5, 5), new SKPoint(5, 5), new SKPoint(5, 5) };

            var rect   = SKRect.Create(10, 10, 100, 100);
            var offset = rect;

            offset.Offset(2, 2);

            var rrect       = new SKRoundRect(rect, 5, 5);
            var transformed = rrect.Transform(SKMatrix.CreateTranslation(2, 2));

            Assert.Equal(offset, transformed.Rect);
            Assert.Equal(radii, transformed.Radii);
        }
コード例 #29
0
        public static MaskDrawable Create(SvgMask svgMask, SKRect skViewport, DrawableBase?parent, IAssetLoader assetLoader, HashSet <Uri>?references, DrawAttributes ignoreAttributes = DrawAttributes.None)
        {
            var drawable = new MaskDrawable(assetLoader, references)
            {
                Element          = svgMask,
                Parent           = parent,
                IgnoreAttributes = ignoreAttributes,
                IsDrawable       = true
            };

            if (!drawable.IsDrawable)
            {
                return(drawable);
            }

            var maskUnits        = svgMask.MaskUnits;
            var maskContentUnits = svgMask.MaskContentUnits;
            var xUnit            = svgMask.X;
            var yUnit            = svgMask.Y;
            var widthUnit        = svgMask.Width;
            var heightUnit       = svgMask.Height;

            // TODO: Pass correct skViewport
            var skRectTransformed = SvgExtensions.CalculateRect(xUnit, yUnit, widthUnit, heightUnit, maskUnits, skViewport, skViewport, svgMask);

            if (skRectTransformed is null)
            {
                drawable.IsDrawable = false;
                return(drawable);
            }

            var skMatrix = SKMatrix.CreateIdentity();

            if (maskContentUnits == SvgCoordinateUnits.ObjectBoundingBox)
            {
                var skBoundsTranslateTransform = SKMatrix.CreateTranslation(skViewport.Left, skViewport.Top);
                skMatrix = skMatrix.PreConcat(skBoundsTranslateTransform);

                var skBoundsScaleTransform = SKMatrix.CreateScale(skViewport.Width, skViewport.Height);
                skMatrix = skMatrix.PreConcat(skBoundsScaleTransform);
            }

            drawable.CreateChildren(svgMask, skViewport, drawable, assetLoader, references, ignoreAttributes);

            drawable.Initialize(skRectTransformed.Value, skMatrix);

            return(drawable);
        }
コード例 #30
0
        /// <summary>
        ///     Opens the render context using the dimensions of the provided path
        /// </summary>
        public void Open(SKPath path, Folder?parent)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("Renderer");
            }

            if (IsOpen)
            {
                throw new ArtemisCoreException("Cannot open render context because it is already open");
            }

            if (path.Bounds != _lastBounds || (parent != null && parent.Bounds != _lastParentBounds))
            {
                Invalidate();
            }

            if (!_valid || Canvas == null)
            {
                SKRect pathBounds = path.Bounds;
                int    width      = (int)pathBounds.Width;
                int    height     = (int)pathBounds.Height;

                Bitmap = new SKBitmap(width, height);
                Path   = new SKPath(path);
                Canvas = new SKCanvas(Bitmap);
                Path.Transform(SKMatrix.CreateTranslation(pathBounds.Left * -1, pathBounds.Top * -1));

                TargetLocation = new SKPoint(pathBounds.Location.X, pathBounds.Location.Y);
                if (parent != null)
                {
                    TargetLocation -= parent.Bounds.Location;
                }

                Canvas.ClipPath(Path);

                _lastParentBounds = parent?.Bounds ?? new SKRect();
                _lastBounds       = path.Bounds;
                _valid            = true;
            }

            Paint = new SKPaint();

            Canvas.Clear();
            Canvas.Save();

            IsOpen = true;
        }